LoginSignup
2
2

More than 5 years have passed since last update.

UVセンサーSi1132をArduinoから制御する(I2C)

Last updated at Posted at 2016-01-23

Si1132

Si1132.jpeg

Datasheet

Si1134で取得できる値

UV indexとambient lightが計測可能。

si1134-input.png

項目名 値の意味
ALS_VIS_DATA Visibility
ALS_IR_DATA Infrared Light
AUX_DATA UVインデックスの値

Slave Address

Slave address 0x60

Who_am_i

PART_ID 0x00

Si1132の場合、0x32が返ってくる。

arduino
#define SI1132_PART_ID 0x00
#define SI1132_DEVICE 0x32

bool SearchDevice()
{
  byte device = 0x00;
  readI2c(SI1132_PART_ID, 1, &device);

  if(device == SI1132_DEVICE){
      return true;
  } else{
      return false;
  }
}

Configuration

UCOEF

UVindex測定係数を設定する。

項目 アドレス
UCOEF0 0x13 0x7B
UCOEF1 0x14 0x6B
UCOEF2 0x15 0x01
UCOEF3 0x16 0x00

CHLIST

UV, IR, Visible lightを有効にする。

項目 アドレス Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
CHILIST 0x01 EN_UV EN_AUX EN_ALS_IR EN_ALS_VIS

ここまでのコード

arduino
#define SI1132_UCOEF0 0x13
#define SI1132_UCOEF1 0x14
#define SI1132_UCOEF2 0x15
#define SI1132_UCOEF3 0x16

#define SI1132_CHIPLIST 0x01
#define Si1132_MEASRATE0 0x08

#define SI1132_EN_UV 0b10000000
#define SI1132_EN_AUX 0b01000000
#define SI1132_EN_ALS_IR 0b00100000
#define SI1132_EN_ALS_VIS 0b00010000

void Configuration()
{
  writeI2c(SI1132_UCOEF0, 0x7B);
  writeI2c(SI1132_UCOEF1, 0x6B);
  writeI2c(SI1132_UCOEF2, 0x01);
  writeI2c(SI1132_UCOEF3, 0x00);

  int enable_sensor = SI1132_EN_UV|SI1132_EN_AUX|SI1132_EN_ALS_IR|SI1132_EN_ALS_VIS;
  writeI2c(SI1132_CHIPLIST, enable_sensor);

  // Rateの設定
  writeI2c(SI1132_CHIPLIST, 0xff);  
}

Visible関連

VisibleのConfiguration。Visibilityでは、取得したVisibleと、ALS_VIS_ALIGN, ALS_RATE, ALS_VIS_ADC_REC, ALS_VIS_ADC_GAIN, VIS_RANGEの設定から、ALS_VIS_DATAを生成する。

config_vis.png

設定する値 設定する場所
ALS_VIS_ALIGN ALS_ENCODING(0x06)の4bit目で設定
ALS_RATE MEAS_RATE0(0x08), MEAS_RATE1(0x09)で設定
ALS_VIS_ADC_REC ALS_VIS_ADC_COUNTER(0x10)の4〜6bit目で設定
ALS_VIS_ADC_GAIN ALS_VIS_ADC_GAIN(0x11) の0〜2bit目で設定
VIS_RANGE ALS_VIS_ADC_MISC(0x12)の5bit目で設定

ALS_VIS_ALIGN

Bitをたてると17bit ADCの16bitを取ってくる。

項目 アドレス
ALS_ENCODING 0x06
項目 アドレス Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
ALS_ENCODING 0x06 ALS_IR_ALIGN ALS_VIS_ALIGN

ALS_VIS_ADC_REC

ALS-VIS測定を行う前に必要とするADCの回復周期を設定する。

項目 アドレス
ALS_VIS_ADC_COUNTER 0x10
値(bit) 周期
000 1 ADC Clock (50 ns times 2ALS_VIS_ADC_GAIN)
001 7 ADC Clock (350 ns times 2ALS_VIS_ADC_GAIN)
010 15 ADC Clock (750 ns times 2ALS_VIS_ADC_GAIN)
011 31 ADC Clock (1.55 µs times 2ALS_VIS_ADC_GAIN)
100 63 ADC Clock (3.15 µs times 2ALS_VIS_ADC_GAIN)
101 127 ADC Clock (6.35 µs times 2ALS_VIS_ADC_GAIN)
110 255 ADC Clock (12.75 µs times 2ALS_VIS_ADC_GAIN)
111 511 ADC Clock (25.55 µs times 2ALS_VIS_ADC_GAIN)

ALS_VIS_ADC_GAIN

ALS可視測定のための、ADCの積分時間を設定。

項目 アドレス
ALS_VIS_ADC_GAIN 0x11
値(bit) 周期
000 1分割したADC Clock
100 16分割したADC Clock
110 64分割したADC Clock

VIS_RANGE

項目 アドレス
ALS_VIS_ADC_MISC 0x12
値(bit) 意味
0 Normal Signal Range
1 High Signal Range

Visibleを追加したソースコード

arduino
#define SI1132_UCOEF0 0x13
#define SI1132_UCOEF1 0x14
#define SI1132_UCOEF2 0x15
#define SI1132_UCOEF3 0x16
#define SI1132_CHIPLIST 0x01
#define Si1132_MEASRATE0 0x08
#define SI1132_ALS_ENCODING 0x06
#define SI1132_ALS_VIS_ADC_COUNTER 0x10
#define SI1132_ALS_VIS_ADC_GAIN 0x11
#define SI1132_ALS_VIS_ADC_MISC 0x12

#define SI1132_EN_UV 0b10000000
#define SI1132_EN_AUX 0b01000000
#define SI1132_EN_ALS_IR 0b00100000
#define SI1132_EN_ALS_VIS 0b00010000

#define SI1132_ALS_VIS_ALIGN 0b00010000

#define SI1132_1_ADC_CLOCK 0b00000000
#define SI1132_7_ADC_CLOCK 0b00010000
#define SI1132_15_ADC_CLOCK 0b00100000
#define SI1132_31_ADC_CLOCK 0b00110000
#define SI1132_63_ADC_CLOCK 0b01000000
#define SI1132_127_ADC_CLOCK 0b10100000
#define SI1132_255_ADC_CLOCK 0b01100000
#define SI1132_511_ADC_CLOCK 0b01110000

#define SI1132_1_DIVIDED_ADC_CLOCK 0b0000000
#define SI1132_16_DEVIDED_ADC_CLOCK 0b0000100
#define SI1132_64_DEVIDED_ADC_CLOCK 0b0000110

#define SI1132_NORMAL_SIGNAL_RANGE 0b00000000
#define SI1132_HIGH_SIGNAL_RANGE 0b00100000

void Configuration()
{
  writeI2c(SI1132_UCOEF0, 0x7B);
  writeI2c(SI1132_UCOEF1, 0x6B);
  writeI2c(SI1132_UCOEF2, 0x01);
  writeI2c(SI1132_UCOEF3, 0x00);

  int enable_sensor = SI1132_EN_UV|SI1132_EN_AUX|SI1132_EN_ALS_IR|SI1132_EN_ALS_VIS;
  writeI2c(SI1132_CHIPLIST, enable_sensor);

  // Rateの設定
  writeI2c(SI1132_CHIPLIST, 0xff);

  int flag_als_encoding = SI1132_ALS_VIS_ALIGN;
  writeI2c(SI1132_ALS_ENCODING, flag_als_encoding);

  // Visible
  writeI2c(SI1132_ALS_VIS_ADC_COUNTER, SI1132_511_ADC_CLOCK);

  writeI2c(SI1132_ALS_VIS_ADC_GAIN, SI1132_1_DIVIDED_ADC_CLOCK);

  writeI2c(SI1132_ALS_VIS_ADC_MISC, SI1132_HIGH_SIGNAL_RANGE);
}

Infrared Light関連

Config-ir.png

Infrared Light(IR)のConfiguration。Infrared Light(IR)では、取得したInfrared Light(IR)と、ALS_IR_ADCMUXのInputと、ALS_IR_ALIGN, IR_RATE, ALS_IR_ADC_REC, ALS_IR_ADC_GAIN, IR_RANGEの設定から、ALS_IR_DATAを生成する。

設定する値 設定する場所
ALS_IR_ALIGN ALS_ENCODING(0x06)の4bit目で設定
ALS_RATE MEAS_RATE0(0x08), MEAS_RATE1(0x09)で設定
ALS_IR_ADC_REC ALS_IR_ADC_COUNTER(0x1D)の4〜6bit目で設定
ALS_IR_ADC_GAIN ALS_IR_ADC_GAIN(0x1E) の0〜2bit目で設定
IR_RANGE ALS_VIS_ADC_MISC(0x1F)の5bit目で設定
ALS_IR_ADCMUX ALS_IR_ADCMUX(0x0E)で設定

ALS_IR_ALIGN

Bitをたてると17bit ADCの16bitを取ってくる。

項目 アドレス
ALS_ENCODING 0x06
項目 アドレス Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
ALS_ENCODING 0x06 ALS_IR_ALIGN ALS_VIS_ALIGN

ALS_IR_ADC_REC

項目 アドレス
ALS_IR_ADC_COUNTER 0x1D

ALS-IR測定を行う前に必要とするADCの回復周期。

値(bit) 周期
000 1 ADC Clock (50 ns times 2ALS_IR_ADC_GAIN)
001 7 ADC Clock (350 ns times 2ALS_IR_ADC_GAIN)
010 15 ADC Clock (750 ns times 2ALS_IR_ADC_GAIN)
011 31 ADC Clock (1.55 µs times 2ALS_IR_ADC_GAIN)
100 63 ADC Clock (3.15 µs times 2ALS_IR_ADC_GAIN)
101 127 ADC Clock (6.35 µs times 2ALS_IR_ADC_GAIN)
110 255 ADC Clock (12.75 µs times 2ALS_IR_ADC_GAIN)
111 511 ADC Clock (25.55 µs times 2ALS_IR_ADC_GAIN)

ALS_IR_ADC_GAIN

ALS可視測定のための、ADCの積分時間を設定。

項目 アドレス
ALS_IR_ADC_GAIN 0x1E
値(bit) 周期
000 1分割したADC Clock
100 16分割したADC Clock
110 64分割したADC Clock

ALS_IR_ADC_MISC

項目 アドレス
ALS_IR_ADC_MISC 0x1F
値(bit) 意味
0 Normal Signal Range
1 High Signal Range

ALS_IR_ADCMUX

Selects ADC Input for ALS_IR Measurement.

項目 アドレス
AUX_ADCMUX 0x0E
値(bit) 周期
0x00 Small IR photodiode

IRを追加したソースコード

arduino
#define SI1132_UCOEF0 0x13
#define SI1132_UCOEF1 0x14
#define SI1132_UCOEF2 0x15
#define SI1132_UCOEF3 0x16
#define SI1132_CHIPLIST 0x01
#define Si1132_MEASRATE0 0x08
#define SI1132_ALS_ENCODING 0x06
#define SI1132_ALS_VIS_ADC_COUNTER 0x10
#define SI1132_ALS_VIS_ADC_GAIN 0x11
#define SI1132_ALS_VIS_ADC_MISC 0x12
#define SI1132_ALS_IR_ADC_COUNTER 0x1D
#define SI1132_ALS_IR_ADC_GAIN 0x1E
#define SI1132_ALS_IR_ADC_MISC 0x1F
#define SI1132_ALS_IR_ADCMUX 0x0E

#define SI1132_EN_UV 0b10000000
#define SI1132_EN_AUX 0b01000000
#define SI1132_EN_ALS_IR 0b00100000
#define SI1132_EN_ALS_VIS 0b00010000

#define SI1132_ALS_VIS_ALIGN 0b00010000
#define SI1132_ALS_VIS_ALIGN 0b00100000

#define SI1132_1_ADC_CLOCK 0b00000000
#define SI1132_7_ADC_CLOCK 0b00010000
#define SI1132_15_ADC_CLOCK 0b00100000
#define SI1132_31_ADC_CLOCK 0b00110000
#define SI1132_63_ADC_CLOCK 0b01000000
#define SI1132_127_ADC_CLOCK 0b10100000
#define SI1132_255_ADC_CLOCK 0b01100000
#define SI1132_511_ADC_CLOCK 0b01110000

#define SI1132_1_DIVIDED_ADC_CLOCK 0b0000000
#define SI1132_16_DEVIDED_ADC_CLOCK 0b0000100
#define SI1132_64_DEVIDED_ADC_CLOCK 0b0000110

#define SI1132_NORMAL_SIGNAL_RANGE 0b00000000
#define SI1132_HIGH_SIGNAL_RANGE 0b00100000

#define SI1132_ALS_IR_ADCMUX_SMALLIR 0x00

void Configuration()
{
  writeI2c(SI1132_UCOEF0, 0x7B);
  writeI2c(SI1132_UCOEF1, 0x6B);
  writeI2c(SI1132_UCOEF2, 0x01);
  writeI2c(SI1132_UCOEF3, 0x00);

  int enable_sensor = SI1132_EN_UV|SI1132_EN_AUX|SI1132_EN_ALS_IR|SI1132_EN_ALS_VIS;
  writeI2c(SI1132_CHIPLIST, enable_sensor);

  // Rateの設定
  writeI2c(SI1132_CHIPLIST, 0xff);

  int flag_als_encoding = SI1132_ALS_VIS_ALIGN | SI1132_ALS_IR_ALIGN;
  writeI2c(SI1132_ALS_ENCODING, flag_als_encoding);

  // Visible
  writeI2c(SI1132_ALS_VIS_ADC_COUNTER, SI1132_511_ADC_CLOCK);

  writeI2c(SI1132_ALS_VIS_ADC_GAIN, SI1132_1_DIVIDED_ADC_CLOCK);

  writeI2c(SI1132_ALS_VIS_ADC_MISC, SI1132_HIGH_SIGNAL_RANGE);

  // IR
  writeI2c(SI1132_ALS_IR_ADC_COUNTER, SI1132_511_ADC_CLOCK);

  writeI2c(SI1132_ALS_IR_ADC_GAIN, SI1132_1_DIVIDED_ADC_CLOCK);

  writeI2c(SI1132_ALS_IR_ADC_MISC, SI1132_HIGH_SIGNAL_RANGE);

  writeI2c(SI1132_ALS_IR_ADCMUX, SI1132_ALS_IR_ADCMUX_SMALLIR);
}

AUX

config-aux.png

AUX_ADCMUXの設定からTemperatureもしくはVDDを選択し、AUX_DATAを生成する。

AUX_ADCMUX

AUX MeasurementのInputを設定。

項目 アドレス
AUX_ADCMUX 0x0F
値(bit) 周期
0x65 Temperature
0x75 VDD

IRを追加したソースコード

arduino
#define SI1132_UCOEF0 0x13
#define SI1132_UCOEF1 0x14
#define SI1132_UCOEF2 0x15
#define SI1132_UCOEF3 0x16
#define SI1132_CHIPLIST 0x01
#define Si1132_MEASRATE0 0x08
#define SI1132_ALS_ENCODING 0x06
#define SI1132_ALS_VIS_ADC_COUNTER 0x10
#define SI1132_ALS_VIS_ADC_GAIN 0x11
#define SI1132_ALS_VIS_ADC_MISC 0x12
#define SI1132_ALS_IR_ADC_COUNTER 0x1D
#define SI1132_ALS_IR_ADC_GAIN 0x1E
#define SI1132_ALS_IR_ADC_MISC 0x1F
#define SI1132_ALS_IR_ADCMUX 0x0E
#define SI1132_AUX_ADCMUX 0x0F

#define SI1132_EN_UV 0b10000000
#define SI1132_EN_AUX 0b01000000
#define SI1132_EN_ALS_IR 0b00100000
#define SI1132_EN_ALS_VIS 0b00010000

#define SI1132_ALS_VIS_ALIGN 0b00010000
#define SI1132_ALS_VIS_ALIGN 0b00100000

#define SI1132_1_ADC_CLOCK 0b00000000
#define SI1132_7_ADC_CLOCK 0b00010000
#define SI1132_15_ADC_CLOCK 0b00100000
#define SI1132_31_ADC_CLOCK 0b00110000
#define SI1132_63_ADC_CLOCK 0b01000000
#define SI1132_127_ADC_CLOCK 0b10100000
#define SI1132_255_ADC_CLOCK 0b01100000
#define SI1132_511_ADC_CLOCK 0b01110000

#define SI1132_1_DIVIDED_ADC_CLOCK 0b0000000
#define SI1132_16_DEVIDED_ADC_CLOCK 0b0000100
#define SI1132_64_DEVIDED_ADC_CLOCK 0b0000110

#define SI1132_NORMAL_SIGNAL_RANGE 0b00000000
#define SI1132_HIGH_SIGNAL_RANGE 0b00100000

#define SI1132_ALS_IR_ADCMUX_SMALLIR 0x00

#define SI1132_AUX_ADCMUX_TEMPERATURE 0x65
#define SI1132_AUX_ADCMUX_VDD 0x75

#define SI1132_COMMAND 0x18
#define SI1132_COMMAND_ALS_AUTO 0x0E

void Configuration()
{
  writeI2c(SI1132_UCOEF0, 0x7B);
  writeI2c(SI1132_UCOEF1, 0x6B);
  writeI2c(SI1132_UCOEF2, 0x01);
  writeI2c(SI1132_UCOEF3, 0x00);

  int enable_sensor = SI1132_EN_UV|SI1132_EN_AUX|SI1132_EN_ALS_IR|SI1132_EN_ALS_VIS;
  writeI2c(SI1132_CHIPLIST, enable_sensor);

  int flag_als_encoding = SI1132_ALS_VIS_ALIGN | SI1132_ALS_IR_ALIGN;
  writeI2c(SI1132_ALS_ENCODING, flag_als_encoding);

  // Visible
  writeI2c(SI1132_ALS_VIS_ADC_COUNTER, SI1132_511_ADC_CLOCK);

  writeI2c(SI1132_ALS_VIS_ADC_GAIN, SI1132_1_DIVIDED_ADC_CLOCK);

  writeI2c(SI1132_ALS_VIS_ADC_MISC, SI1132_HIGH_SIGNAL_RANGE);

  // IR
  writeI2c(SI1132_ALS_IR_ADC_COUNTER, SI1132_511_ADC_CLOCK);

  writeI2c(SI1132_ALS_IR_ADC_GAIN, SI1132_1_DIVIDED_ADC_CLOCK);

  writeI2c(SI1132_ALS_IR_ADC_MISC, SI1132_HIGH_SIGNAL_RANGE);

  writeI2c(SI1132_ALS_IR_ADCMUX, SI1132_ALS_IR_ADCMUX_SMALLIR);

  // AUX
  writeI2c(SI1132_ALS_IR_ADC_GAIN, SI1132_AUX_ADCMUX_TEMPERATURE);

  // COMMAND
  writeI2c(SI1132_COMMAND, SI1132_COMMAND_ALS_AUTO);
}

RESET

項目 アドレス
COMMAND 0x18
コマンド 値(Bit)
RESET 00000001
arduino
#define SI1132_COMMAND_RESET 0b00000001
#define SI1132_COMMAND 0x18

void Reset()
{
  writeI2c(SI1132_COMMAND, SI1132_COMMAND_RESET);
}

UV Indexの読み取り

arduino
#define SI1132_AUX_DATA 0x2C

void ReadUV()
{
  uint16_t uv_index;
  uint8_t buffer[2];

  readI2c(SI1132_AUX_DATA, 2, buffer);
  uv_index = (((uint16_t)buffer[1])<<8) | (uint16_t)buffer[0];

  return uv_index;
}

IRの読み取り

arduino
#define SI1132_IR_DATA 0x24

void ReadIR()
{
  uint16_t ir;
  uint8_t buffer[2];

  readI2c(SI1132_IR_DATA, 2, buffer);
  ir = (((uint16_t)buffer[1])<<8) | (uint16_t)buffer[0];

  return ir;
}

Visibleの読み取り

arduino
#define SI1132_IR_DATA 0x22

void ReadIR()
{
  uint16_t visible;
  uint8_t buffer[2];

  readI2c(SI1132_AUX_DATA, 2, buffer);
  visible = (((uint16_t)buffer[1])<<8) | (uint16_t)buffer[0];

  return visible;
}

I2Cのアクセス用コード

Arduino
#define HTS221_SLAVE_ADDRESS 0x5F

// I2Cへの書き込み
void writeI2c(byte register_addr, byte value) {
  Wire.beginTransmission(HTS221_SLAVE_ADDRESS);  
  Wire.write(register_addr);         
  Wire.write(value);                 
  Wire.endTransmission();        
}

// I2Cへの読み込み
void readI2c(byte register_addr, int num, byte *buf) {
  Wire.beginTransmission(HTS221_SLAVE_ADDRESS); 
  Wire.write(register_addr);           
  Wire.endTransmission(false);         

  //Wire.beginTransmission(DEVICE_ADDR); 
  Wire.requestFrom(HTS221_SLAVE_ADDRESS, num);  

  int i = 0;
  while (Wire.available())
  {
    buf[i] = Wire.read(); 
    i++;   
  }
  //Wire.endTransmission();         
}
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2