室内照明の自動化システムを製作しましたので、紹介します。
照明自動化システムの概要
室内照明自動化の考え方は、人感センサー、照度センサーからの情報を基に、マイコンが条件を判断して照明器具をON/OFFするもので、ON/OFF指令にはインフラレッドLED(赤外線LED)を使用します。
したがって、照明器具は赤外線リモコンで操作できるタイプか、新たに照明器具用の赤外リモコン受信器具を取り付ける必要があります。
また、使用したマイコンにはWiFi機能があり、自宅内LAN経由で、あるいは外出先からアクセスすることで、照明スイッチの操作が可能となります。
赤外線リモコンの送信コードを調べる
赤外線リモコンの送信コードの意味合い
赤外線リモコンは、照明器具やエアコンなどの家電製品を遠隔でコントロールするため、指令コードを赤外線のパルスにて送信しています。指令コードは0/1の信号として下図のように送られています。
図では、0.56ms間ONとした後、1.69ms間OFFとすることでデータの1を表わしています。
一方、0.56ms間ONとした後、0.56ms間OFFとすることでデータの0を表わします。
このような方法で指令コードは1/0信号に置き換えられ、器具に送られます。
ただし、指令コードそのものは、メーカーによって決められるので、実際のリモコンを操作して各指令に対するコードを調べて行く必要があります。
赤外線リモコン送信コード解析ツールの製作
そこで、指令コードを調べるためのツールの製作しましたので、紹介します。
赤外線リモコンの送信コードを解析するためのセンサーとして、下記の赤外線受信モジュールを使用します。
使用した赤外線受信モジュール 外観図を示します。
製品名:赤外線リモコン受信モジュール、OSRB38C9AA(OptoSupply社製)
秋月電子で2個100円でした。
このモジュールは、赤外線リモコンから送出される約38kHzの赤外線パルスを受信して、図のような電圧パルスを出力します。(出力は反転パルスとなる)
解析ツールでは、このパルスの時間幅を計測することで、コードを解釈します。
解析ツールの回路図
解析ツールで使用したマイコンは手持ちのESP-Wroom-02で電圧が3.3Vですが、赤外線リモコン受信モジュールは2.7-5.5Vに対応しているので他のマイコンでも動作します。
回路はブレッドボード上に製作しました。
実際に赤外線リモコンで操作した時の指令コードをオシロスコープに表示しています。
解析ツールのプログラム
赤外線リモコンから送出される信号フォーマットは、最初にリーダーコードが送られ、その後指令コードが、そして最後にエンドコードで構成されています。
それぞれのコードは約38kHzの赤外線パルスでの送信であるが、赤外線リモコン受信モジュールで電圧パルスに変換されるので、マイコン側では、そのパルスのON、OFF時間を計測することでそれぞれのコード内容を解析します。
コード解析の判断条件を下記に示します。なお各条件はプログラムの中で、#define文にて定義しており、必要により変更することが出来ます。
データ部分はON状態が400~600μs続いた後、OFF状態の長さによりデータの1と0を判断する。
リーダーコード部分は、ON状態がデータ部分より長いので、ON時間の長さにより判断する。
エンドコードは、ON状態が400~600μs続いた後、OFF時間がデータの1より長く続くので、OFFの時間の長さにより判断する。
プログラムリストを下記に示します。
<pre class="c++">/*
赤外線リモコン 送信コード解析
*/
include
include
define LED_BLINK 13
define InteruptInputPin 4
define Brand Pana
define COUNT_NUM 1024
define LeaderCodeDuration_ON 1000
define EndCodeDuration_OFF 3000
Ticker ticker1;
int count_sec = 20; // counter
int pos_i = 0;
unsigned long msred_time[COUNT_NUM];
void count_down() { // 100ミリ秒ごとの処理
count_sec--;
}
void measure_time(){
msred_time[pos_i++] = micros();
}
void setup() {
Serial.begin(115200);
delay(10);
pinMode(LED_BLINK, OUTPUT);
pinMode(InteruptInputPin, INPUT);
attachInterrupt(digitalPinToInterrupt(InteruptInputPin), measure_time, CHANGE); // 割り込みを設定する
ticker1.attach_ms(100, count_down);
Serial.println("");
}
void analyze(){
unsigned int code[256];
int i = 0;
int j = 0;
int k = 0;
char str[1000];
int state = 0;
Serial.print("No of Pulse:");
Serial.println(pos_i/2);
while( i < pos_i){ int duration_ON = msred_time[i+1] - msred_time[i]; i++; if( i+1 < pos_i ){ int duration_OFF = msred_time[i+1] - msred_time[i]; int duration = duration_ON + duration_OFF; if (duration_ON > LeaderCodeDuration_ON) { // パルスONが一定の長さ以上の場合、データ送信の始まり(Leader Code)を示す
sprintf(&str[0], "%d: Leader Code: %dus = (%d + %d) … START\r",i/2, duration, duration_ON, duration_OFF);
Serial.println(str);
j=0;
for (k=0; k<256; k++){ code[k]=0; } }else if(duration_OFF > EndCodeDuration_OFF){ // パルスONの後、一定の長さ以上のOFF時間の場合、データ送信完了(END Code)を示す
sprintf(&str[0], "%d: End Code: %dus = (%d + %d) … END\r",i/2, duration, duration_ON, duration_OFF);
Serial.println(str);
for(int k=0; k= 2 ){ // パルスOFF時間がデータの1と0を示す。(OFFがONの2倍以上を1と判断する)
code[k] |= 1 << (j%8); state = 1; }else{ state = 0; } if(j%8==7){ sprintf(&str[0], "%d: bit%d, %dus (%d + %d) … %d (0x%02x)\r", i/2, j, duration, duration_ON, duration_OFF, state, code[k]); }else{ sprintf(&str[0], "%d: bit%d, %dus (%d + %d) … %d\r", i/2, j, duration, duration_ON, duration_OFF, state); } j++; Serial.println(str); } }else{ // 最後のパルス(OFF時間が続く場合)は送信完了(END Code)を示す sprintf(&str[0], "%d: End Code: %dus … END\r",i/2, duration_ON); Serial.println(str); for(int k=0; k2) && (i%2 == 0) && ((micros() - msred_time[ i-1]) > 500000) && (i == (pos_i)) ){ // 条件:一つ以上のパルス&信号OFF状態&0.5 sec以上のOFF時間&pos_iが不変
analyze();
pos_i = 0;
}
if(count_sec <= 0){
digitalWrite(LED_BLINK, !digitalRead(LED_BLINK));
count_sec = 5;
}
}
</pre>
ツールによる赤外線リモコンコード解析結果
このツールを使って、実際にパナソニックの照明器具やオーム電機のリモコンスイッチなどを解析してみました。もちろんエアコン、テレビなどの家電も同じように解析出来ます。
メーカーによりリーダーコード部やデータ部のON/OFF時間は異なったり、またデータフォーマットも違うので、解析結果を見て最終判断することが必要になります。
パナソニックの例:
No of Pulse:84 0: Leader Code: 5221us = (3525 + 1696) ... START 1: bit0, 875us (478 + 397) ... 0 2: bit1, 867us (420 + 447) ... 0 3: bit2, 1740us (477 + 1263) ... 1 4: bit3, 1740us (480 + 1260) ... 1 5: bit4, 874us (474 + 400) ... 0 6: bit5, 1741us (476 + 1265) ... 1 7: bit6, 899us (451 + 448) ... 0 8: bit7, 845us (393 + 452) ... 0 (0x2c) 9: bit8, 867us (465 + 402) ... 0 10: bit9, 1740us (470 + 1270) ... 1 11: bit10, 873us (479 + 394) ... 0 12: bit11, 871us (477 + 394) ... 0 13: bit12, 1739us (476 + 1263) ... 1 14: bit13, 875us (479 + 396) ... 0 15: bit14, 1736us (469 + 1267) ... 1 16: bit15, 879us (477 + 402) ... 0 (0x52) 17: bit16, 1731us (471 + 1260) ... 1 18: bit17, 873us (474 + 399) ... 0 19: bit18, 872us (477 + 395) ... 0 20: bit19, 1739us (477 + 1262) ... 1 21: bit20, 877us (475 + 402) ... 0 22: bit21, 865us (466 + 399) ... 0 23: bit22, 871us (472 + 399) ... 0 24: bit23, 872us (477 + 395) ... 0 (0x09) 25: bit24, 873us (477 + 396) ... 0 26: bit25, 874us (474 + 400) ... 0 27: bit26, 892us (470 + 422) ... 0 28: bit27, 871us (449 + 422) ... 0 29: bit28, 1710us (393 + 1317) ... 1 30: bit29, 1742us (471 + 1271) ... 1 31: bit30, 877us (480 + 397) ... 0 32: bit31, 872us (473 + 399) ... 0 (0x30) 33: bit32, 1732us (463 + 1269) ... 1 34: bit33, 878us (480 + 398) ... 0 35: bit34, 895us (472 + 423) ... 0 36: bit35, 1709us (421 + 1288) ... 1 37: bit36, 1741us (471 + 1270) ... 1 38: bit37, 1743us (480 + 1263) ... 1 39: bit38, 878us (480 + 398) ... 0 40: bit39, 893us (469 + 424) ... 0 (0x39) 41: End Code: 75253us = (445 + 74808) ... END 2c 52 09 30 39 42: Leader Code: 5222us = (3526 + 1696) ... START 43: bit0, 902us (481 + 421) ... 0 44: bit1, 871us (448 + 423) ... 0 45: bit2, 1709us (393 + 1316) ... 1 46: bit3, 1742us (471 + 1271) ... 1 47: bit4, 873us (480 + 393) ... 0 48: bit5, 1739us (477 + 1262) ... 1 49: bit6, 873us (474 + 399) ... 0 50: bit7, 871us (472 + 399) ... 0 (0x2c) 51: bit8, 877us (476 + 401) ... 0 52: bit9, 1731us (471 + 1260) ... 1 53: bit10, 872us (470 + 402) ... 0 54: bit11, 872us (471 + 401) ... 0 55: bit12, 1740us (477 + 1263) ... 1 56: bit13, 876us (479 + 397) ... 0 57: bit14, 1735us (474 + 1261) ... 1 58: bit15, 873us (475 + 398) ... 0 (0x52) 59: bit16, 1738us (468 + 1270) ... 1 60: bit17, 874us (475 + 399) ... 0 61: bit18, 873us (477 + 396) ... 0 62: bit19, 1735us (474 + 1261) ... 1 63: bit20, 872us (469 + 403) ... 0 64: bit21, 872us (478 + 394) ... 0 65: bit22, 876us (477 + 399) ... 0 66: bit23, 894us (472 + 422) ... 0 (0x09) 67: bit24, 842us (444 + 398) ... 0 68: bit25, 870us (469 + 401) ... 0 69: bit26, 872us (477 + 395) ... 0 70: bit27, 872us (476 + 396) ... 0 71: bit28, 1739us (476 + 1263) ... 1 72: bit29, 1738us (422 + 1316) ... 1 73: bit30, 872us (468 + 404) ... 0 74: bit31, 871us (423 + 448) ... 0 (0x30) 75: bit32, 1740us (477 + 1263) ... 1 76: bit33, 875us (479 + 396) ... 0 77: bit34, 897us (475 + 422) ... 0 78: bit35, 1710us (448 + 1262) ... 1 79: bit36, 1744us (480 + 1264) ... 1 80: bit37, 1737us (450 + 1287) ... 1 81: bit38, 874us (470 + 404) ... 0 82: bit39, 870us (477 + 393) ... 0 (0x39) 83: End Code: 479us ... END 2c 52 09 30 39
パナソニックの例では、送出コードがリーダーコード、データコード、エンドコードのセットで2回送られているのが分かります。
リーダーコード部の判断基準はON時間>1,000usであり、判別結果ではリーダーコード部の抽出に成功しています。
データコード部の判断基準は、OFF/ON各時間の比率で表し、2以上でデータ1と判断しています。判別結果は、ON時間が約400us、OFF時間はデータ1の時、約1,300us(OFF/ON比:3.25)、データ0の時、約400us(OFF/ON比:1)でデータ判別に成功しています。
そして、エンドコードの判断基準は、ON時間の後のOFF時間>2,000usであり、判別結果はONが約450sの後、74,800usのOFF時間となり、判別に成功しています。ただし、2回目のエンドコードには最後のパルスとして処理し、OFF時間の計測はしません。
パナソニックの赤外線リモコンの解析の結果、指令コードは、 2c 52 09 30 39(16進)であることが分りました。
次回では、このコードを使って実際に赤外線LEDより送出し、照明器具をON/OFFして見ます。