2014年8月29日金曜日

リモコン受信 AVRマイコン編 その1

以前RaspberryPiでリモコン受信するやり方を書きましたが、今回はHA2module上のAVRマイコンでリモコン受信してコード化する方法について書きます。色々とあって長いので3回に分けて書きます。

赤外線リモコンのフォーマットは色々あって全てに対応するのは難しいですが、国内の一般的な赤外線リモコンはサブキャリアが38kHz前後で、AV機器は数十bit程度の長さが多いようです。エアコンの中にはかなり長く300bitを超えるものも存在しています。
赤外線受信モジュールはサブキャリアをフィルターしてパルスデータだけを出力してくれるので、GPIOで受けてパルスの変化のタイミングの間隔を見ていけばデコードできます。今回はAVRのPinChangeInterruptでTimerのCounter値を読んで前回の変化からの時間を記録するようにしました。
最初は自宅にある機器をメインに考えていたためAEHA,NEC,SONYのリモコンだけ対応すればよかったので、この割込みの処理の中でフォーマットの解釈もする実装にしていました。
ところが色々なリモコンを検討し始めたところ、このやり方ではダイキンやパナソニックのエアコンコードなどが対応出来ないため再度実装しなおしました。
新しい実装では、まずはじめにPinChange割込み処理中にHigh区間幅、Low区間幅のペアの頻度統計を取りながらコード化して記録します。
全体を記録し終えたところで押し続けることによる繰り返しパターンの判別をし、AEHA,NEC,SONYのフォーマットを解釈していずれかであればそのフォーマット、何れでもなければ記録したフォーマットをXBee経由で送るようにしています。
以下、実際の処理の詳細です。

□PinChange割込み中の処理
パルスをHigh区間、Low区間(実際の受光モジュールの出力は逆ですが、わかりやすいように無信号状態をLowとしています)をそれぞれ76kHzのカウント値で数えペアの値とします。このペアの値をPatternTableを検索し近い値があればそのPatternとして、なければ新規に登録して、そのPattern番号を求めます。
その番号を記録バッファに記録していくのですがそのまま番号を記録していくと4bit単位で記録していったとしても300bit越えのエアコンフォーマットだと余裕をみて196byte位必要になってしまいます。
普通のリモコンコードはデータを表すパターン2種類が0と1を表していて頻出するはずなのでこの2つを1bitの値として扱い、それ以外のパターンを特殊扱いすれば全体として短くすることが出来るはずです。ところがリモコンを受信し始めたタイミングではどのパターンがデータを表す2種類のパターンなのかは判りません。
そこで出現頻度を判断できるように先頭の64パルスを圧縮処理を遅らせるためにFIFOに登録しながら統計をとり、64パルス揃ったところで出現率の多いPatternを2つ選び、2つのうちHigh+Lowが小さい、等しい場合はHighが小さい方をパターン番号0、大きい方をパターン番号1とします。それ以外のパターンは出現順にパターン番号2から順番に登録します。普通のリモコンコードの場合、大体5〜6種類程度に収まります。
64パルス目以降はFIFOにパルス幅を登録しながらFIFOの先頭から順番に値を取り出します。
この時64パルス目のタイミングでそれまでのデータをまとめて処理してしまうと割込み中の処理が重すぎて取りこぼしが発生するので、FIFOでずらしたその割込みの64パルス前のパルスの処理だけを行うようにしています。
この説明だけでは判りにくいかと思いますが、あとで実際のエアコンのフォーマットを使って説明します。

□Timeout割込み
PinChange割込みのたびにTimerに100msのTimeoutを登録、更新します。
最後のPinChange割込みから100ms経つとTimeout割込みが入り、最終ビットパターンの処理を行い、通常Threadに処理を渡します。

長くなってきたので、一旦ここで切ります。
次回は通常Threadで後処理をするところからです。

0 件のコメント:

コメントを投稿