背景
12/15にSpheroV2でIR通信を使うことができなさそうだということが分かりました。
せめて赤外光の送信内容だけでも調べて、ESP32からメッセージを送れないかと目論見ました。
波形測定
メイン基板の赤外光LEDの端子にオシロスコープのプローブを当て、メッセージの内容に対する赤外光LEDの両端電圧の波形を調べてみました。
パルスの塊の短い場合がゼロ、長い場合が1を表していると考え、メッセージの番号との対応を次のように想像しました。
メッセージの番号 | パルスの塊 |
---|---|
0 | 0000 0000 |
1 | 1110 0001 |
2 | 1101 0010 |
3 | 0011 0011 |
4 | 1011 0100 |
5 | 0101 0101 |
6 | 0110 0110 |
7 | 1000 0111 |
一方でSpheroEDUの通信にあるブロードキャストなどのメッセージの組み合わせを見ると、0と1、2と3のように隣り合った番号だったので、混信防止のために対にしている番号の片方は上位1バイトは反転して判別しやすくしているのかもしれません。
次に、パルスの塊の部分を拡大しました。
すみませんが、プローブのキャリブレーションし忘れていました。
この図からゼロを表すと思われる短いパルスの塊は0.024ms x 13、1を表すと思われる長いパルスの塊は0.024 x 25の波形に見えました。
この波形で赤外光をSphero Boltに見せればメッセージを受け取ったとだませるかもしれません。
なお、通信の距離の数字を変えた場合は、次のようにデューティが変化するようでした。
上から距離を64, 48, 32, 16にした場合です。
ESP32で赤外光を送信する実験
最初はledcを使おうとしたのですが、version3以上で設定分が変わっており、何度か試したのですがうまくいきませんでした。
ダメもとでBLINKサンプルにdelayMicrosecondをいれて赤外光のLEDを接続したポートをオンオフしたところ、Sphero boltが認識してくれました。
なお、赤外光のLEDは昔捨てたテレビのリモコンから部品取りしました。
#define GPIO_PIN 18
#define PCOUNT0 13
#define PCOUNT1 8
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(GPIO_PIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
while(1) {
for (int j = 0; j < PCOUNT1; j++) {
// 11 + 1 usでon / offするパルスを13個送る。1msまって8つパルスの塊を送る。
for (int i = 0; i < PCOUNT0; i++) {
digitalWrite(GPIO_PIN, HIGH);
delayMicroseconds(11);
// wait for a second
digitalWrite(GPIO_PIN, LOW);
// turn the LED off by making the voltage LOW
delayMicroseconds(11);
// wait for a second
}
delay(1);
}
delay(200);
}
}
まとめ
赤外光通信の内容を調べESP32でメッセージの送信を模擬しました。
強めに発光させる送信源を場に複数置いたり、応用して楽しめそうです。