赤外線で家電をハックする(簡易版)
導入編
はじめに
ところが
自分で信号を解析するのは正直つらい。
メーカーによっては有志の強者によって解析されているものも多々ある
メーカーによってフォーマット全然違ったりする
そもそも自分の家のがそのリストにあるとも限らない
いや別に全部の信号使えなくても特定の信号だけ送れればいいんだよ!と思う人も少なくないはず
そこで
1. 必要な信号だけをリモコンからコピー
2. マイコンとかに記憶させる
3. 必要に応じて赤外線LEDで送る
をこのページでは目指す
基礎知識
リモコンの赤外線信号は細い間隔でのon/offの繰り返しでできている https://image.itmedia.co.jp/ait/articles/1408/27/arduino4_03.jpg
信号の種類によってこのon/offの間隔が違う
大抵この信号には全ての情報が乗っている
例えば、現在25度冷房で1度上げるボタンを押したとしても「このままの設定で温度だけ一度上げる」という信号が出ているわけではなく、いちいち「冷房で、風速がこれで、スウィングはこうで、温度は26度」というように情報を全て送っている
リモコンの側と受信側で今まで何を押したかとかを同期仕切れないから
なのでたとえ暖房になってようが、25度冷房の時の信号を送れば25度の冷房になる
基礎知識を踏まえて
つまり欲しい特定信号のon/offの間隔を記録すれば良い!
そしてそれ通りに赤外線LEDで送れれば良い!
実践編
赤外線の信号をコピーする
必要なもの
赤外線受信器
https://gyazo.com/bcdceaa102ca25d0d6b3f88a2f798f4c
繋ぎ方
赤外線受信器のGNDピンをarduinoのGNDに 赤外線受信器のVCCピンをarduinoの5Vに(大抵5v) 赤外線受信器のVoutピンをarduinoの11番ピンに
これは別に読めるピンなら何番でも今回は11番に
コード
code:getIR.ino
void setup(){
Serial.begin(57600);
pinMode(READ_PIN,INPUT);
Serial.println("Ready to receive");
}
void waitLow() {
while (digitalRead(READ_PIN)==LOW) {
;
}
}
int waitHigh() {
unsigned long start = micros();
while (digitalRead(READ_PIN)==HIGH) {
if (micros() - start > 5000000) {
return 1;
}
}
return 0;
}
unsigned long now = micros();
unsigned long lastStateChangedMicros = micros();
int state = HIGH_STATE;
void loop() {
if (state == LOW_STATE) {
waitLow();
} else {
int ret = waitHigh();
if (ret == 1) {
Serial.print("\n");
return;
}
}
now = micros();
Serial.print((now - lastStateChangedMicros) / 10, DEC);
Serial.print(",");
lastStateChangedMicros = now;
if (state == HIGH_STATE) {
state = LOW_STATE;
} else {
state = HIGH_STATE;
}
}
これによって大抵
[3450, 1750, 550, 350, 500, 350, 500, 1200, 550, 1200, 550, 300, 500, 1200, 600, 300, 500, 350, 500, 400, 400, 1300, 500, 350, 450, 400, 500, 1250, 550, 300, 450, 1250, 450, 400, 450, 1300, 550, 350, 500, 300, 450, 1350, 400, 450, 500, 350, 500, 350, 500, 350, 500, 350, 450, 400, 450, 1300, 500, 1250, 400, 400, 450, 1350, 500, 300, 450, 450, 400, 1300, 450, 400, 450, 1300, 450, 400, 400, 450, 450, 1300, 450, 400, 400, 500, 400]
みたいな値がシリアルモニタに流れてくる
これはon/offの感覚を10microsec単位で記録したもの
上のコードで/10してるから
めちゃくちゃでかい値(何万とか何十万)より先〜次のめちゃでかい値より前までの配列が信号です
めちゃでかい値=受診する前のずっとoffの状態or受信後のずっとoffの状態
確認のため同じ信号を3、4回記録しておくと良い
赤外線信号を送る
必要なもの
arduinoだとメモリが少なすぎて上でgetした信号が記憶できない....orz
多分工夫して圧縮すればいけるけど
raspiも多分できます、がsaji.iconはやったことがない
抵抗
200Ωとかでいい....多分.....
本当はLEDの電気特性とかから計算しないといけない.... そこら辺はググってください
上で記憶した配列(3つ4つ同じのとって平均取るといいかも)
配線
LEDの+(アノード)をespの3.3Vに
LEDの-(カソード)のさきに抵抗を
抵抗の先をESPのGNDに
→Lチカと同じです
コード例(ESPでの)
code:sendIR.ino
extern "C" {
}
// 記憶した配列を入れる(↓は多分前の家の照明のon/off信号 エアコンはもっと長いです)
short on[] = {3450, 1750, 550, 350, 500, 350, 500, 1200, 550, 1200, 550, 300, 500, 1200, 600, 300, 500, 350, 500, 400, 400, 1300, 500, 350, 450, 400, 500, 1250, 550, 300, 450, 1250, 450, 400, 450, 1300, 550, 350, 500, 300, 450, 1350, 400, 450, 500, 350, 500, 350, 500, 350, 500, 350, 450, 400, 450, 1300, 500, 1250, 400, 400, 450, 1350, 500, 300, 450, 450, 400, 1300, 450, 400, 450, 1300, 450, 400, 400, 450, 450, 1300, 450, 400, 400, 500, 400};
short off[] = {3450, 1750, 450, 450, 400, 450, 400, 1300, 450, 1300, 450, 400, 400, 1350, 450, 400, 400, 500, 350, 450, 450, 1300, 450, 450, 350, 500, 400, 1300, 450, 400, 400, 1350, 450, 400, 400, 1350, 400, 450, 400, 450, 400, 1300, 450, 450, 400, 450, 450, 400, 400, 500, 400, 1300, 450, 1250, 450, 1350, 400, 1300, 450, 400, 400, 1350, 450, 400, 400, 450, 400, 500, 350, 1350, 450, 1250, 450, 400, 450, 450, 400, 1300, 450, 450, 400, 450, 400};
//出力pin
int ir_out_pin = 13;
void setup() {
Serial.begin(115200);
pinMode(ir_out_pin, OUTPUT);
}
void emitIRSignal(short data[]) {
int duration;
unsigned long started_at;
int signalLength = sizeof(data) / sizeof(data0); for (int i = 0; i < signalLength; i++) {
started_at = micros();
while (micros() - started_at < duration) {
// i is even: HIGH. i is odd: LOW
// keep 1/3 duty, 8 usec.
digitalWrite(ir_out_pin, 1 - (i % 2));
delayMicroseconds(8);
// off remaining 2/3, 16 usec.
digitalWrite(ir_out_pin, 0);
delayMicroseconds(16);
}
}
}
void loop() {
emitIRSignal(on);
Serial.print("send on");
delay(3000);
emitIRSignal(off);
Serial.print("send off");
delay(3000);
}
うまく信号を送れていると上のコードなら3秒おきにon/offする
注意点
この配線&普通の赤外線LEDだと光が弱いことが多い
うまく送れてなさそうなら受光部分に近づけてみよう
TIPS
赤外線はデジカメ通すと見れるので信号が出てるかの確認に使える
スマホだと観れなかったりする
iphone6はよく見れなかった
赤外線が弱い時
そもそもESPの電源は大して電流量がない
トランジスタとか使って別の5or3.3V電源からとったので増幅するといいのかも
自己責任でお願いしますsaji.iconも素人なのでテキトーなこと言ってる可能性非常に大です
高電流を流すと平気でLED焼き切れたりします
やけどします(経験者saji.icon)
LEDのデータシートとやてスタートちゃんとにらめっこしてね
最後に
Saji.iconでの例なので全て間に受けず他にも調べたりたりしてやりましょう
赤外線信号は解析している人・解析コード等が沢山出回ってます。このページでやっていることができたら、解析してみるのもいいかもしれません
To詳しい方へ.... 愛のあるマサカリ待ってますsaji.icon