つまりなにしたの?
I2Cで遊ぼうと思って、ESP-WROOM-32に昔買った明るさセンサを繋いでみた。
TSL2561とは
レンジの広い明るさセンサ。二種類の帯域向けの明るさセンサを併せて使ってるみたい。
スイッチサイエンスさんで買って積んであったよ
https://www.switch-science.com/catalog/1801/
ライブラリつかわないの?
Arduino+TSL2561はうまく動いたけど、ESP-WROOM-32だとうまく動かなかったから
こちらのブログを参考に実装してみた。
okiraku-camera.tokyo
配線
ESP-WROOM-32のブレイクアウトボードが前提でこんな感じ。
Wireだけつかったコードの例
これをArduinoIDEで書き込む。
#include "Wire.h" byte i2c_address = 0x39; byte i2c_status = 0; double lux_value; uint16_t data_ch0 = 0; uint16_t data_ch1 = 0; enum { reg_control = 0, reg_timing = 1, reg_thr_L = 2, reg_thr_H = 4, reg_int = 6, reg_id = 0x0a, reg_data0 = 0x0c, reg_data1 = 0x0e }; byte i2c_write_reg(byte reg, byte data){ Wire.beginTransmission(i2c_address); Wire.write(reg); Wire.write(data); i2c_status = Wire.endTransmission(); return i2c_status; } byte i2c_read16_swab(byte pointer){ Wire.beginTransmission(i2c_address); Wire.write(pointer); i2c_status = Wire.endTransmission(); Wire.requestFrom(i2c_address, (byte)2); uint16_t lsb = (uint16_t)Wire.read(); uint16_t msb = (uint16_t)(Wire.read() << 8); return msb | lsb; } void start() { Serial.println("Start"); Wire.begin(); i2c_write_reg(reg_timing | 0x80, 0x2); //Log gain 402ms i2c_write_reg(reg_int | 0x80, 0x0); i2c_write_reg(reg_control | 0x80, 3); lux_value = 0; } void stop(){ i2c_write_reg(reg_control | 0x80, 0); } double get_data(){ data_ch0 = i2c_read16_swab(reg_data0 | 0x80); data_ch1 = i2c_read16_swab(reg_data1 | 0x80); Serial.print("data_ch0:"); Serial.println(data_ch0); Serial.print("data_ch1:"); Serial.println(data_ch1); if(!data_ch0 || !data_ch1){ lux_value = 0.0; } double ch0 = (double)data_ch0; double ch1 = (double)data_ch1; double ratio = ch1 /ch0; //FN packageなので if (ratio > 0 && ratio <= 0.5) lux_value = 0.0304 * ch0 - 0.062*ch0 * pow(ratio, 1.4); else if(ratio > 0.5 && ratio <= 0.61) lux_value = 0.0224 * ch0 - 0.031 * ch1; else if(ratio > 0.61 && ratio <= 0.80) lux_value = 0x0128 * ch0 - 0.0153 * ch1; else if(ratio > 0.80 && ratio <= 1.30) lux_value = 0.00146 * ch0 - 0.00112 * ch1; else if(ratio > 1.30) lux_value = 0; lux_value *= ch0; return lux_value; } void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("Hello TSL2561"); start(); } void loop() { // put your main code here, to run repeatedly: double current_lx = get_data(); int v = current_lx*10.0; Serial.print("current_lx: "); Serial.println(v); delay(1000); }
概ね1秒おきに各チャンネルのセンサ生値とLux換算した値を吐き出すはず。
換算は参考にしたブログだと想像してた値と違うのが出てきたので、
https://cdn-shop.adafruit.com/datasheets/TSL2561.pdf
の23ページT, FN, and CL Packageを使った。
多分自分が読み間違えたか写経しそこねたんだろうけど…
割り込みなどは使っていないのでたまに変な値が入ることがある。