5ドル!ラズパイ・ゼロ(Raspberry pi Zero)でIoT (28) ディジタル光センサ2 I2C S11059-02DT

RGBデータを個別に取り込める

 S11059-02DTは浜松ホトニクスの製品で、フォト・ダイオードの前に色フィルタを置き、RGBそれぞれの光強度を取得できるセンサです。このRGBカラー・センサを使うと、ホワイト・バランスを取りたいとき、色識別や色の管理に使えると、参考文献に書かれています。データシートには、ポータブル機器のバックライト調光、大型テレビの省エネセンサなどが用途として書かれています。

 Lowゲイン・モードでは、赤外、RGBそれぞれ1素子で測定します。Highゲイン・モードでは、それぞれ10素子で測定します。同社にはより受光感度の高い製品にS9706があります。

S11059-02DTのスペック

  • Red、Green、Blue、赤外の連続測光
  • 感度切り替え 1:10
  • 積分時間による感度調節 1~65535倍
  • 動作電圧 2.5または3.3V
  • 動作電流 75uA
  • ダイナミック・レンジ 1~10000lx
  • インターフェース I2C(最大400kHz)

S11059-02DTモジュール

 デバイスは10ピンの小型パッケージに入っています。2.53mmの4ピンに変換するプリント基板に実装したモジュールを入手しました。電源間に0.1uFのコンデンサが実装されています。10ピンのデバイスにある信号は4種類だけなので、省略された機能はありません。

 I2Cのスレーブ・アドレスは0x2A(7ビット)固定です。

データ読み出し手順

 マニュアル設定モードと固定時間モードの二つがあります。どちらも、LowゲインとHighゲインのどちらかに切り替えて測れます。

マニュアル設定モード

 電源が入った後スリープしているので、リセット・コードとスリープ解除コードを送り起こします。リセットを解除します。

 積分時間より長く待ち、データを読み出します。R,G,B,赤外の順です。データは一度送られてくるだけです。

固定時間モード

 電源が入った後スリープしているので、リセット・コードとスリープ解除コードを送って起こします。リセットを解除します。

 積分時間より長く待ち、データを読み出します。R,G,B,赤外の順です。データは常時更新されます。

 固定時間モードの積分時間は短めが多く、最大179.2msです。積分時間が長いほど、カウントできるので、低い照度に対応ができます。マニュアル設定では、最大65.2時間に設定できます。積分時間の4倍が測定時間です。

レジスタ

 機能を設定するコントロール・レジスタです。b1、b0は固定時間モードの積分時間を設定する値で、マニュアル設定では倍の値になります。

アドレス 機能 b7 b6 b5 b4 b3 b2 b1 b0
00 コントロール  1:ADCリセット
0:動作開始
 1:待機モード
0:動作モード

 スリープ機能モニタ

 -  1:Highゲイン
0:Lowゲイン
  1:マニュアル・モード
0:固定時間モード
00:87.5us
01:1.4ms
10:22.4ms
11:179.2ms  

 マニュアル・モードのとき、積分時間の倍数を設定するレジスタです。

アドレス 機能 b7 b6 b5 b4 b3 b2 b1 b0
01 マニュアル・タイミング・レジスタ         積分時間上位バイト
02         積分時間下位バイト

 読み出したR、G、B、赤外のデータ・レジスタです。

アドレス 機能 b7 b6 b5 b4 b3 b2 b1 b0
03 Red出力データ     上位バイト    
04     下位バイト    
05 Green出力データ      上位バイト 
06      下位バイト   
07 Blue出力データ      上位バイト   
08      下位バイト   
09 赤外出力データ       上位バイト  
0a       下位バイト  

接続

S11059-02DT ラズパイ
SCL 5番ピン
GND 9番ピン
SDA 3番ピン
V+ 1番ピン 3.3V

 S11059-02DTとラズパイのI2Cを接続して電源を入れ、ターミナルからi2cdetect -y 1で確認します。2aにいました。

テスト・プログラム

 固定時間モードで、設定できる8種類のパラメータparam(High/Lowゲイン、積分時間4通り)を変えながら、Redのデータを記録しました。

#!/usr/bin/env python
import smbus
import time
bus = smbus.SMBus(1)
addr = 0x2a
param=[0x0b,0x0a,0x09,0x08,0x03,0x02,0x01,0x00]
 
bus.write_byte_data(addr , 0x00, 0x80)
bus.write_byte_data(addr , 0x00, param[0] )
time.sleep(1)
data = bus.read_i2c_block_data(addr , 0x03, 8)
R = data[0] *256 + data[1]
print (R)
param値 Redデータ 値の順番
0 3
1 51
2 833
3 6676
8 49
9 441
a 7154
b 57284

 読み出すデータの最大値は65535です。上記の表の感度の低い順番からスタートし、順番に感度(積分時間)を上げながら、Blueが飽和する一つ手前のparamを求めます。その感度設定で、R,G、B、赤外のデータを読み取るプログラムを作りました。固定時間モードは、新規データの更新は常時行われるので、読み出すだけで、新しいデータが得られます。

#!/usr/bin/env python
import smbus
import time
bus = smbus.SMBus(1)
addr = 0x2a
param=[0x00,0x08,0x091,0x09,0x02,0x03,0x0a,0x0b]

i=0
print (hex(param[i]),param[i])
while i<8:
bus.write_byte_data(addr , 0x00, 0x80)
bus.write_byte_data(addr , 0x00, param[i] )
time.sleep(0.8)
data = bus.read_i2c_block_data(addr , 0x03, 8)
R = data[0] *256 + data[1]
G = data[2] *256 + data[3]
B = data[4] *256 + data[5]
Ir = data[6] *256 + data[7]
max = i
print (R," ",G," ",B," ",Ir)
if B<65535 :
i=i+1
else:
max = i-1
break
print (hex(param[max]),"---")
bus.write_byte_data(addr , 0x00, 0x80)
bus.write_byte_data(addr , 0x00, param[max] )

while 1:
time.sleep(0.6)
data = bus.read_i2c_block_data(addr , 0x03, 8)
R = data[0] *256 + data[1]
G = data[2] *256 + data[3]
B = data[4] *256 + data[5]
Ir = data[6] *256 + data[7]
print (R," ",G," ",B," ",Ir)

 測定中に照度がとても高くなると飽和してしまいます。このプログラムでは、各色のデータがダイナミック・レンジを大きく取れるので、色の判別などに役立つと思います。

 実行例です。データシートにあるように、R、G、B、赤外はそれぞれの感度特性は異なります。

感度を上げられるマニュアル設定モード

 マニュアル設定モードを実行します。感度と積分時間を決めます。

  • 感度;HighとLowゲインがあり、10倍異なる
  • 積分時間;175us(00)、2.8ms(01)、44.8ms(10)、358.4ms(11)の四つのパラメータがあり、長いほど感度が上がる。倍率を設定できる。Tint="00"=175us、倍率=3120(0xc30)だと546msになる。

条件;Lowゲイン、積分時間Tint=175us、倍率3120 結果546ms

(※日本語のコメントはコピー後削除してください)

#!/usr/bin/env python
import smbus
import time
bus = smbus.SMBus(1)
addr = 0x2a

bus.write_byte_data(addr , 0x0, 0xe4) #リセット
bus.write_byte_data(addr , 0x1, 0x0c) #倍率
bus.write_byte_data(addr , 0x2, 0x30) #倍率
bus.write_byte_data(addr , 0x0, 0x84) #リセット、wakeup
bus.write_byte_data(addr , 0x0, 0x04) #リセット解除
time.sleep(3)
data = bus.read_i2c_block_data(addr , 0x03, 8) #8バイトの読み出し

R = data[0] *256 + data[1]
G = data[2] *256 + data[3]
B = data[4] *256 + data[5]
Ir = data[6] *256 + data[7]

print R," ",G," ",B," ",Ir

 読み出した16ビットのデータが、何であるかがデータシートに書かれていません。単位も不明です。受光デバイスなので、それぞれの波長の強度に比例した数値が得られていると推定できます。データシートの最後に「カウント値-照度」グラフがあります。読み出したデータがカウント値と思われます。

 LowとHighゲインの感度設定は10倍異なると書かれていますが、積分時間と感度の相関は書かれていません。

 倍率を×1(0x01)、×10(0x0a)、×100(0x64)、×1000(0x3e8)と変えて、暗めの机の上を測りました(Highゲイン)。設定時間は最長の358.4msです。測定時間に合わせて、sleep時間を延ばしました。×1000はすべての値が飽和しました。

  Red Green Blue 赤外
1倍 358.4ms 1317 1400 912 392
10倍 3584ms 13408 14013 9075 3924
100倍 35840ms 65535 65535 65535 47069

 100倍の約35秒でRGBは飽和しました。

 実用的な範囲の値が得られる10倍に設定したとき、暗記用下敷きをセンサの上に置きました。

  Red Green Blue 赤外
フィルタなし 14888 18960 11799 4948
赤色 14657 14076 9270 5040
緑色 10357 4736 3665 3853

 飽和しない限界ぐらいに積分時間を長くして感度を上げると、色の識別がしやすくなります。

※参考文献;伊藤 勉、鈴木 弘一、RGBカラー・センサの基礎と応用、トランジスタ技術、2003年12月号、p.181