🌚
カラーセンサで赤外線を読み取る
右側で明滅する赤外線をセンサーが読み取って左側に反映している
カラーセンサは赤外線にも対応
前回の記事の、
では色の読み取りを試した。その際に Infrared という見慣れない英単語がでてきて無視していたのだけどこれは赤外線のことだった。
コード
#include <Wire.h>
#define S11059_ADDR 0x2A
void setup() {
Serial.begin(9600);
pinMode(3, OUTPUT);
pinMode(9, OUTPUT);
Wire.begin();
Wire.beginTransmission(S11059_ADDR);
Wire.write(0x00);
Wire.write(B10001011);
Wire.endTransmission();
Wire.beginTransmission(S11059_ADDR);
Wire.write(0x00);
Wire.write(B00001011);
Wire.endTransmission();
}
uint16_t count = 0;
void loop() {
digitalWrite(3, (count / 60) & 1);
if (true) {
Wire.beginTransmission(S11059_ADDR);
Wire.write(0x03);
Wire.endTransmission();
Wire.requestFrom(S11059_ADDR, 8); // 8バイト要求する
if (Wire.available()) {
// R, G, B を読み捨てる
raw_value_read();
raw_value_read();
raw_value_read();
int infrared1 = raw_value_read();
int infrared2 = constrain(map(infrared1, 500, 3900, 0, 255), 0, 255);
if (true) {
char str[128];
sprintf(str, "%u -> %u", infrared1, infrared2);
Serial.println(str);
}
digitalWrite(9, infrared2 >= 128);
}
Wire.endTransmission();
}
delay(1000 / 60);
count++;
}
uint16_t raw_value_read() {
uint8_t h = Wire.read();
uint8_t l = Wire.read();
return h << 8 | l;
}
値の読み取り
- センサからは RGB に続いて赤外線の値が来る
- 最初の3つは不要なので今回は読み飛ばしている
- 赤外線は RGB と比べると感度の幅が小さい
- 測定すると 65536 段階で来てくれていいのに 500..3900 程度の幅しかなかった
- その上、反映間隔が
179.2 ms
なのでスムーズには読み取れない - したがって強弱を計るのにはあまり向いていない
- だったら反映間隔を短かくすれば?
- 試しに積分時間設定を
00
の87.5 μs
に変更してみたらそもそも動かなくなった
- 試しに積分時間設定を
256段階にマッピングするなら次のようになる。
int infrared2 = constrain(map(infrared1, 500, 3900, 0, 255), 0, 255);
LEDへの反映
256段階にしたものの精度がいまいちなので2段階にして digitalWrite で反映した。
赤外線LEDが動いているのか調べる方法
最初に赤外線LEDをブレッドボードに刺してからコードを書いたのは失敗だった。発光が人間に見えないので正常に動いているのかどうかわからなかった。
したがって段階的に最初は発色LEDを使い、最後に赤外線LEDに差し替えるのがよさそう。赤外線LEDと内部LEDを連動させるのもいい。
赤外線受信専用モジュールがある
赤外線の感知だけであればカラーセンサよりも専用モジュールを使った方が便利かもしれない。
Discussion