秋月で販売している浜松フォトニクスのカラーセンサ S11059-02DTを試してみた。
・RGBに加えIRが計測できて、解像度が16bit/chになった。
・I2Cバス接続が可能。
・ダイナミックレンジが向上し、明るい太陽光下でも値が飽和しにくくなったので使いやすい。
・ダイナミックレンジが向上し、明るい太陽光下でも値が飽和しにくくなったので使いやすい。
接続のポイント
・3.3V系なので、5V系ボードではレベル変換が必要
・数kΩでプルアップ (3kΩ程度かな)
実物は米粒くらいの大きさ |
ユニバーサル基板にハンダ付けするときは、四隅の足だけ残して、真ん中寄りの足をピンセットなどで上に折り曲げてから、4本の足をパッドにハンダ付けすると簡単にできる。
手前がカラーセンサ。奥はTMP006(非接触IR温度センサ) |
1画素ドットカメラの時みたいに、またレンズでも付けてみようかと思っている。
得られた数値で、照度の換算なども出来そう。
動作確認用スケッチ
最初はEnergia IDE(MSP430)で作っていたけど、Arduinoでも動く。Wireの仕様の関係で、1.0以降のAPIに対応したバージョンなら大丈夫だと思う。
MSP430 LaunchPadの場合、デフォルトのボードはI2CのSCLにLED2が接続されているため、通信ができない。 あらかじめLED2の黒いジャンパを外しておくこと。
MSP430 LaunchPadの場合、デフォルトのボードはI2CのSCLにLED2が接続されているため、通信ができない。 あらかじめLED2の黒いジャンパを外しておくこと。
スケッチでは固定露出モード動作となる。 マニュアル露出についてはまだテストしていないけど、任意の露出時間を選べそう。
/********************************************************************************
* S11059_02dt I2C color sensor test sketch v20151220 by KentN
*
*
* tested boards
* MSP430 LaunchPad(G2553) (Energia IDE 0101E016)
* Arduino 1.0 or later (3.3V board or I2C level converter)
*
* MSP430LaunchPad (Energia)
* before enabling I2C bus, remove led2 JUMPER PIN
********************************************************************************/
#include "Wire.h"
#define led 13 // Arduino LED PIN
//#define led RED_LED //(MSP430 LaunchPad)
#define device_address 0x2A
#define control_reg 0x00
#define timing_reg_H 0x01
#define timing_reg_L 0x02
uint16_t red = 0;
uint16_t green = 0;
uint16_t blue = 0;
uint16_t IR = 0;
void getRGB();
void setup()
{
Wire.begin();
Serial.begin(9600);
pinMode(led,OUTPUT);
digitalWrite(led,LOW);
led_blink();
}
void loop()
{
getRGB();
Serial.print(red);
Serial.print(", ");
Serial.print(green);
Serial.print(", ");
Serial.print(blue);
Serial.print(", ");
Serial.println(IR);
delay(500);
}
void getRGB()
{
uint16_t colordata= 0;
/* //manual exposure mode
setManualtGain(100);
Wire.beginTransmission(device_address);
Wire.write(control_reg);
Wire.write(0x84); // ADC reset LowGain wakeup
Wire.endTransmission();
Wire.beginTransmission(device_address);
Wire.write(control_reg);
Wire.write(0x04); //start
Wire.endTransmission();
*/
//Fixsed exposure mode settings
// LowGain mode
// 0x00 = 87.5us
// 0x01 = 1.4ms
// 0x02 = 22.4ms
// 0x03 = 179.2ms
// HighGain Mode
// 0x08 = 87.5us
// 0x09 = 1.4ms
// 0x0a = 22.4ms
// 0x0b = 179.2ms
Wire.beginTransmission(device_address);
Wire.write(control_reg);
Wire.write(0x83); // ADC reset wakeup
Wire.endTransmission(false);
Wire.beginTransmission(device_address);
Wire.write(control_reg);
Wire.write(0x03); // set gain & exposure time
Wire.endTransmission();
delay(180*4); //wait exposure time x4ch
led_blink();
Wire.beginTransmission(device_address);
Wire.write(0x03);
Wire.endTransmission(false);
Wire.requestFrom(device_address,8);
//read data
if (Wire.available() > 0){
colordata = Wire.read();
colordata <<= 8;
colordata |= Wire.read();
red = colordata;
colordata =0;
colordata = Wire.read();
colordata <<= 8;
colordata |= Wire.read();
green = colordata;
colordata =0;
colordata = Wire.read();
colordata <<= 8;
colordata |= Wire.read();
blue = colordata;
colordata =0;
colordata = Wire.read();
colordata <<= 8;
colordata |= Wire.read();
IR = colordata;
} return;
}
void setManualtGain(uint16_t ex_time){
uint8_t reg =0;
Wire.beginTransmission(device_address);
reg =(ex_time >>= 8);
Wire.write(reg);
Wire.endTransmission();
Wire.beginTransmission(device_address);
reg |= ex_time;
Wire.write(reg);
Wire.endTransmission();
}
void led_blink()
{
digitalWrite(led,HIGH);
delay(10);
digitalWrite(led,LOW);
}