Arduino
RaspberryPi
LIRC
赤外線

LIRC の赤外線データについて拙くまとめる

About

Raspberry Pi3 で赤外線LED をつかってリモコンを制御する記事は調べると色々あります。

Amazon Echo や Google Home などと連携しているものもあるが、
その根本の赤外線LED → 受光器の仕組みは変わりません。

その赤外線についてしらべたのでメモ的にまとめます。

※ネットで調べただけのシロウトなので間違いなど指摘頂けると助かります。

回路については赤外線LED へ流す電流が弱いと光が弱くなり、
受光器側との距離が短くなったり届かなかったりする。
そのため、どうやって電流を多く流すのか、
(電源を別にするとかラズパイ 5V から可能な範囲で電流をひっぱるかとか)
fritzing で回路設計しては試行錯誤してみたが、
だいたい先人の示した道のとおりでした。

Detail

LIRC のデータ

ラズパイ、赤外線LED で検索するとたいてい LIRC がでてくる。
インストールや使い方は多く紹介されているのだけれども、
そのなかででてくる送信データがなんなのかがよくわからない。
irrecordmode2 で学習、表示されるデータですね。

こういうやつ↓
(SHARP AQUOS 2013年くらい?の電源ONOFFボタン、以下は正規化したデータです)

3200 1600 400 400 400 1200 400 400
400 1200 400 400 400 1200 400 400
400 1200 400 400 400 1200 400 400
400 1200 400 1200 400 400 400 1200
400 400 400 1200 400 1200 400 1200
400 1200 400 400 400 400 400 400
400 1200 400 400 400 1200 400 400
400 400 400 1200 400 400 400 400
400 400 400 400 400 1200 400 1200
400 400 400 1200 400 400 400 400
400 400 400 1200 400 400 400 400
400 400 400 1200 400 400 400 1200
400 1200 400 9000

これがどういうデータでなんでテレビがついたり消えたりするのだろうと疑問でした。

データがなにか?

まず上記データがなにかでいうと、
PPM の pulse、space の対で、それぞれのマイクロ(μ)秒単位での時間。

3200 1600 400 400 とあるが、
これは 3200 μ秒のパルス1600 μ秒のスペース400 μ秒のパルス400 μ秒のスペース となる。

LIRC は奇数個にしないとエラーになるが、上記データでの 9000gap で定義することになり、
最後のパルスのあとに gap の値分のスペースが送信される(送信というか LOW)。

PPM とは?

PPMとはパルス位相変調信号です。なんか難しいことばですが、要は赤外線の点灯時間と消灯時間の長さの組み合わせによってビット値を表現すると言う物です。

この PPM の点灯と消灯をマイコン(ラズパイ)では、 PWM で変調し赤外線LED の電力を制御して受光器側で PPM として受け取ることができるようようです。
パルス幅とパルス位置。

PWM とは?

PWM(Pulse Width Modulation)とは、半導体を使った電力を制御する方式の1つです。オンとオフの繰り返しスイッチングを行い、出力される電力を制御します。

一定電圧の入力から、パルス列のオンとオフの一定周期を作り、オンの時間幅を変化させる電力制御方式を PWM と呼びます。早い周期でスイッチングを行うことで、オンのパルス幅に比例した任意の電圧が得られます。これは、半導体がオンとオフ状態が最も損失が少ない(中間状態は損失多い)ことを利用した電力制御方式です。

パルスは HIGH の時間、スペースは LOW の時間です。
なのでまずここでのざっくりとした理解として、
3200 1600 400 400 は、
3200 μ秒の HIGH1600 μ秒の LOW400 μ秒の HIGH400 μ秒の LOW となります。

※実際にはキャリア周波数にのせるのでこのとおりではないのですがそれについては後述します。ここでの理解は上記で大丈夫です。

テレビリモコン(家電協)の赤外線フォーマット

テレビリモコンの赤外線フォーマットは公開されているわけではなさそうです。
先人が解析してくれた結果を使う、自分で解析するなどが必要です。
わたしは解析することまではできないので、秋月電子さんの これ を参考にして、
解析結果ありきで AQUOS の電源ONOFF についてみていきます。

SHARP AQUOS は家電協フォーマットであり、
電源 ONOFF は 0x55,0x5A,0xF1,0x48,0x68,0x8B と表記してくれています。

さらに ここ より、
家電協フォーマットは、 リーダー部 + データ部 + トレーラー部 となります。

リーダー部

T = 0.4ms とすると、リーダー部は次から HIGH 3.2 ms、LOW 1.6ms となります。

ON(8T)→OFF(4T)、Tは0.35〜0.5msと規定されている。典型的には中央値0.425msを使用する。

秋月電子さんのこれでは、家電協フォーマットは HIGH 3.2ms、LOW 1.6ms となっています。
引用では T=0.425ms として、ON(3.4ms)→OFF(1.7ms) としています。
このへんの T の値からくる差はありますが、どちらであっても ON(8T)→OFF(4T) となっており、T が範囲内であればよいみたいです。(アバウトですね。。。)
計算が楽でわかりやすいので T=0.4ms にあわせます。

データ部

3バイト以上・任意バイト数の送信データ。各バイトはLSB first。
データ「0」は ON(1T)→OFF(1T)
データ「1」は ON(1T)→OFF(3T)
なお、データの内容は

1〜2バイト目がカスタムコード (ベンダー/機器の識別)
3バイト目以降がデータコード (コマンド等)

データ「0」0.4ms HIGH → 0.4ms LOW
データ「1」0.4ms HIGH → 1.2ms LOW
となります。

LSB first とありますが、元の仕様として決められているコードがイマイチわからず、
秋月電子さんのものは LSB first にしてくれた状態?でしょうか…。
0x55,0x5A,0xF1,0x48,0x68,0x8B を2進数にすると

(LSB?)0101 0101 0101 1010 1111 0001 0100 1000 0110 1000 1000 1011(MSB?)

となります。
上記のデータにあてはめて考えていくと、

「0」 0.4ms HIGH → 0.4ms LOW
「1」 0.4ms HIGH → 1.2ms LOW
「0」 0.4ms HIGH → 0.4ms LOW
「1」 0.4ms HIGH → 1.2ms LOW

「0」 0.4ms HIGH → 0.4ms LOW
「1」 0.4ms HIGH → 1.2ms LOW
「0」 0.4ms HIGH → 0.4ms LOW
「1」 0.4ms HIGH → 1.2ms LOW

「0」 0.4ms HIGH → 0.4ms LOW
「1」 0.4ms HIGH → 1.2ms LOW
「0」 0.4ms HIGH → 0.4ms LOW
「1」 0.4ms HIGH → 1.2ms LOW

「1」 0.4ms HIGH → 1.2ms LOW
「0」 0.4ms HIGH → 0.4ms LOW
「1」 0.4ms HIGH → 1.2ms LOW
「0」 0.4ms HIGH → 0.4ms LOW
・
・
・

となります。
ms を μs にすると・・・

「0」 400μs HIGH →  400μs LOW
「1」 400μs HIGH → 1200μs LOW
「0」 400μs HIGH →  400μs LOW
「1」 400μs HIGH → 1200μs LOW

これを pulse,space で書き出すと

400 400 400 1200 400 400 400 1200

なんかみたことある値になってきました。
これが LIRC のデータとして扱っているものになります。

トレーラー部

ON(1T)→OFF(nn)
nnは8ms以上と規定されている。Panasonic製デジタルチューナー付属のリモコンの場合は約75ms。

とあるので、いったんかりで次のようにしておきます。

400 1200 400 9000

まとめると

まずリーダー部の 3200 1600 があり、
次にデータ部が 400 400... からはじまり、
トレーラー部の 400 1200 400 9000 でおわります。

3200 1600 400 400 400 1200 400 400
400 1200 400 400 400 1200 400 400
400 1200 400 400 400 1200 400 400
400 1200 400 1200 400 400 400 1200
400 400 400 1200 400 1200 400 1200
400 1200 400 400 400 400 400 400
400 1200 400 400 400 1200 400 400
400 400 400 1200 400 400 400 400
400 400 400 400 400 1200 400 1200
400 400 400 1200 400 400 400 400
400 400 400 1200 400 400 400 400
400 400 400 1200 400 400 400 1200
400 1200 400 9000

このようなデータとなりました。
実際に irrecord で学習したデータとつきあわせてみると、
実際のデータは 3425 1583 412 408... のように少しずつ違いはありますがおおよそ同じ値となりました。

LIRC を使うのであればここでおわりです。

PWM とキャリア周波数(補足)

LIRC や WiringPi のように、 PWM を独自で実装するときにおそらく必要になることですが、
赤外線はキャリア周波数にのせて送信されます。

上記のデータをことばそのままの意味で受け取れば、
3200 μ秒の HIGH、 1600 μ秒の LOW なのですが、
38kHz のキャリアにのせるので実際には違っています。

38kHzでデューティー比 1:3 (リモコンの仕様でそうきまっているらしい)
(パルス幅が 1/3 ということ、パルス幅 1/4 と信号なし 3/4 ではないことに注意)、
38000 = 1 / 周期、
0.000026316 秒=26μs、
これが PWM の周期です。
この 26 μ秒で HIGH と LOW を表現します。

HIGH は、 (26/3)*1=8.666666667≒9μs の HIGH26-9=17μs の LOW で表現され、
LOW26μ秒の LOW で表現されます。

たとえば、 3200 μs のパルス=HIGH は、
3200 / 26 = 123.076923077≒123 で 123回の HIGH(9μs HIGH、16μs LOW) で表現されます。
1600 μs のスペース=LOW は、
1600 / 26 = 61.538461538≒61 で 61回の LOW(26μs) で表現されます。

おまけ1

SHARP AQUOS のテレビの電源オンオフ、
付属の純正リモコンで一度テレビをつけてから、マイコンからオンオフするとうまくいきます。
それなのに、オフにしてしばらく放置してて、マイコンからオンオフするとうまくいきません。

これはいかに、と思って mode2 でみてみると送信コードはやっぱりあっていました。
違っていたのは、そのコードをマイコンは一回だけ送信していたが、
リモコンは2回?か3回くらい送信していました。
なので irsend SEND_ONCE "tv" "power" && irsend SEND_ONCE "tv" "power" とするとつきました。
なんか一回だけのはノイズかもって判断で2回連続でこないとテレビつかないような制御があるんかもですね。

おまけ2

SONY のテレビは電源オンオフがマイコンからできなかった。
SONY フォーマットが家電協とは違うといっても原理的にはそんな間違ってはないと思えるようになり、
ネチネチ見てたら mode2 でやったらこっちは 4回同じコードがとんでた。
なのでいかりの irsend SEND_ONCE "sonytv" "power" && irsend SEND_ONCE "sonytv" "power" でついた。
あ、 SEND_ONCE って回数指定できます?もしかして…。
と思いつつ。

Reference

黒豆で、wireshark で QUIC のぞいて、バイナリコピペでそのまま動かなくて試行錯誤した日々は遠くなりました。
おわり。