概要
赤外線センサを利用して、NECフォーマットの赤外線リモコンのコードを表示するプログラムを作成します。
PARA LIGHT ELECTRONICS社のPL-IRM2161-C438という赤外線センサを使います。
この実験ではArduino Unoを利用しています。ESP-WROOM-32での実験はこちら。
ハードウェア
以下のものを利用しました。
- Arduino Uno
- 赤外線センサ(PARA LIGHT ELECTRONICS社のPL-IRM2161-C438)
- (PC)
- (USBケーブル)
- (ブレッドボード)
- (ジャンプワイヤ)
データフォーマット
赤外線リモコンでよく使われるデータフォーマットには、以下の3つがあるようです。
- NECフォーマット
- 家電協フォーマット
- SONYフォーマット
私の家にあるDVDレコーダはは東芝製で、このレコーダは、NECフォーマットを採用しているようです。ここでは、NECフォーマットのリモコンコードを読み取っていきます。
概要
NECフォーマットの概要は以下の通りです。詳細は、 FAQ 1007798 : 赤外線リモコンの信号はどうなっているのですか? を参照してください。
リーダコード
リーダコードは、9msのon、その後、4.5msのoffです。
カスタムコード・データコード
カスタムコードとデータコードは、1と0との組み合わせです。
1は、0.56ミリ秒のonの後、1.69ミリ秒のoff(全体では、2.25ミリ秒)、0は、0.56ミリ秒のonの後、0.565ミリ秒のoff)全体では1.125ミリ秒)であらわされます。また、カスタムコードは、16ビット、データコードは8ビットです。それぞれのバイトを、下位ビットから(第0ビットから=LSBファーストで)送信していきます。
データコード(反転)は、データコードのONとOFFを反転させたデータです。これにより、エラーチェックが行えるようになっています。
ストップビット
ストップビットについては、参照したページには明確な定義は見つけられませんでしたが、0.56ミリ秒のonの後、offになるのではと思います。
リピートコード
リピートコードは、リモコンのキーを押し続けた時に出るコードで、リピートコードの後に、すぐに、ストップビットが来ます。
リピートコードは、9msのon、その後、2.25msのoffです。
余談ですが、テレビのリモコンボタンを一度だけ押したところ、そのボタンが押し続けられるような現象が発生しました。音量を一段階上げたつもりがどんどん上がり続け、チャンネルを一つ上げるとどんどんチャンネルが上がり続ける…リモコンが壊れたのかと思い、リモコンの電池を抜いても事態は変わらず、部屋を見渡してみると、別のリモコンの上に本が乗っていました。こちらのリモコンがリピートコードを出し続けて、別のリモコンで出したコードを繰り返し実行していたようです(リピートコードにはカスタムコードがありません)。
まとめ
今までのことをまとめると、上記の数値と少し異なりますが、9/16ミリ秒(=0.5625ミリ秒)を1単位とすると、おおよそ以下のように表せます。
- リーダコード
- 16単位のon、8単位のoff
- データの1
- 1単位のon、3単位のoff
- データの0
- 1単位のon、1単位のoff
1回のリモコンデータの送信では、リーダコード1回、データ32ビット、ストップビット1回が送信されるので、onが34回、offが34回となります。
デバイスの接続
Arduinoと赤外線センサは以下のように接続しました。
赤外線センサのピン | Arduinoのピン番号 |
---|---|
VCC | 5V |
GND | GND |
Vout | 2 |
プログラム
赤外線センサでリモコンコードを読み取る
データフォーマットで示した情報を、赤外線センサ(PL-IRM2161-C438)を利用して、Arduinoで読み取ります。
このセンサは、38kHzのキャリア周波数で変調された赤外線信号を受信します。データがONのときにLOW、OFFのときにHIGHを出力します。
今回は、リーダコードから始まる68個のパルスの開始時刻(ONからOFF、OFFからONに切り替わる時刻)を配列に記録し、配列の情報を基に、コードを解析する方式をとりました。
具体的には、以下のような情報を記録します。
配列 | 説明 | 備考 |
---|---|---|
time[0] | リーダーコードの開始時刻 | |
time[1] | ON→OFFになった時刻 | time[2]-time[1]が4.5msだったらリーダーコード、2.25msだったらリピートコード |
time[2] | カスタムコード(1バイト目)の開始時刻 | 0ビット目on開始時刻 |
time[3] | 0ビット目off開始時刻 | |
time[4] | 1ビット目on開始時刻 → time[4]-time[3] or time[4]-time[2]が、0ビット目が0か1かを決める。 | |
… | ||
time[18] | カスタムコード(2バイト目)の開始時刻 | |
… | ||
time[34] | データコードの開始時刻 | 0ビット目on開始時刻 |
time[35] | 0ビット目off開始時刻 | |
time[36] | 1ビット目on開始時刻 → time[36]-time[35] or [36]-time[34]が、0ビット目が0か1かを決める。 | |
… | ||
time[50] | データコード(反転)の開始時刻 | 0ビット目on開始時刻 |
time[51] | 0ビット目off開始時刻 | |
time[52] | 1ビット目on開始時刻 → time[52]-time[51] or time[52]-time[50]が、0ビット目が0か1かを決める。 | |
… | ||
time[66] | ストップビットの開始時刻 | |
time[67] | ストップビットの終了時刻 | onがoffになった時刻。 |
上記のデータを取得するため、ビジーループを用いました。通常はあまり良い方法ではありませんが、他の処理もないので今回は良しとしました。
- 赤外線センサの出力がLOW(=ON)になるまで待つ(=HIGHの間は待つ)。
- 以降は、赤外線センサの出力がonになった時とoffになった時の時刻を、配列(timeという名前にしました)に記録していく。
- 通常は全部で68回読み取りを繰り返す。ただし、カスタムコードを読み取った後(4回目の記録を行ったとき)に、リーダーコードのoffの時間を調べて、3000ミリ秒以下だったら、読み取りは終了する。
フローにすると以下の通りです。微妙に上記説明とは異なりますが…
受信したデータを出力する
読み取ったコードを人間が読める形に変換して出力します。
- リーダーコードは、onになっていた時間と、offになっていた時間をそれぞれ、ミリ秒単位で表示します。
- カスタムコードは2バイトを1バイトずつにわけて表示、データコードとデータコード(反転)は、それぞれ1バイトを表示します。
- 1バイトを表示する際は、ビット列と16進表記の2種類を表示します。ビット列については受信した順序で表示し、16進表記は、データの値として表示します。
スケッチ
スケッチは以下の通りです。マジックナンバーが多いです。
|
|
動作している様子
以下に動作している様子を示します。リモコンの1、2を順に押した時の様子です。
カスタムコードが、45 bc、データコードがそれぞれ、01、02であることがわかります。また、データコードのビットを反転したものがデータコード(反転)に入っている様子もわかります。
カスタムコードとデータの2進数の0と1は、受信順に表示しているので、LSBから表示していることに注意してください。
2の後には、リピートコードが入っています。どうも、手元のリモコンはリピートコードが送信されるまでの時間が短いようです。
その他
赤外線リモコンを操作する実験のページはこちらを参照してください。
バージョン
Hardware: | Arduino UNO R3 |
Software: | Arduino 1.8.19 |
最終更新日
January 2, 2022