赤外線リモコンデコーダ

# はじめに
- M5Stack用PLUSエンコーダ（2019年の正月休みのオモチャとして購入）には赤外線LEDが搭載されています。
- そこで、M5Stackを使った汎用リモコンを作ってみようと思い立ちました。（だいぶ枯れた題材だと思いますが）
- まずは、ウチに転がっている各リモコンがどんな信号を出しているかを調べようと作成したのが、今回の「赤外線リモコンデコーダ」です。
    - こちらの記事（[M5Stack 赤外線リモコンデコーダ](https://qiita.com/tt-yawata/items/92adb5ddb19ff1d07178)）を参考にさせていただきました。

---
# 仕様
- [赤外線リモコンの通信フォーマット](http://elm-chan.org/docs/ir_format.html)で解説されている、NECフォーマット／AEHAフォーマット／SONYフォーマットの3種に対応する。
    - ウチにあるリモコンのうち、ひとつだけがこれらのフォーマットに合致しなかったんですが、使用していないエアコン用のリモコンなのでスルーしました。
- 表示内容（下記情報を受信ごとにスクロール表示）
    - 受信した赤外線パターン（8bit単位で表示）
    - フォーマットタイプ（NEC／AEHA／SONY）
    - カスタマーコード（SONYフォーマットではアドレス）
    - データ
- 受信時の状況はこんな感じ
<img width="768" alt="IMG_0286.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/166435/865a7ebc-6659-9dca-6a69-acf77f88362f.jpeg">


---
# 受信信号の解析について
1. 赤外線の変調単位Ｔの算出
    - 受信信号を平均して算出することにする。
        - いくつかのリモコンを読み込ませて実測したところ、規定値とのずれがそれなりにあった。（サンプルタイミングを調整すれば定数（例えば、NECフォーマットでは約560μs）比較でもよいのかもと思ったんですが、面倒だったので。）
    - 信号の特徴から、発光部分か無発光部分のどちらかはパルス幅が一定になる（はず）。
        - ので、特異値（極端に長い幅）を含まない方の平均値を変調単位Ｔとして採用する。
        - 例えば、NECフォーマットでは無発光部分の幅がbit値によって変化する。（発光部分のパルス幅の平均値をＴとする）
1. フォーマットタイプの判定
    - 受信信号の先頭データ（Leader）の発光部分のパルス幅で判定する。
        - 変調単位Ｔの10倍（規定では16倍）以上なら、AEHAフォーマット
        - 変調単位Ｔの6倍（規定では8倍）以上なら、NECフォーマット
        - 変調単位Ｔの2倍（規定では4倍）以上なら、SONYフォーマット
        - 上記以外は、フォーマット不明としてエラー扱い
1. bit値（1/0）の判定
    - NEC／AEHAフォーマットの場合、無発光部分のパルス幅がＴの1.5倍より大きい（1）かどうかで判定。
    - SONYフォーマットの場合、発光部分のパルス幅がＴの1.5倍より大きい（1）かどうか判定。
1. カスタマーコード（16bit）のＬ／Ｈ判定
    - 明確に定義された資料を見つけられなかったので、Ｌ→Ｈの順に16bitコードが転送されていると解釈することにした。
        - 解説記事によると、bitパターンはLSBファーストで転送される。
        - 素直に考えれば、リトルエンディアン（Ｌ→Ｈの順）となるのでは。
1. パリティチェック
    - AEHA
        - 先頭2byteと続く1byteの下位4bitをnibble単位（計5nibble）でxorし、0になればOK
    - NEC
        - 3byte目と4byte目のxorがFFになればOK
    - SONY
        - なし
       
---
# 解析例
- 作成したデコーダでの解析結果（抜粋）

    |機器メーカ|フォーマットタイプ|カスタマーコード／アドレス|ボタン|データ|機器|備考|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|日立|AEHA|1001|運転／停止|0048B701FE|空気清浄機|データの後半4byteは2byteごとに反転|
|日立|AEHA|1001|モード|0048B704FB|空気清浄機||
|日立|AEHA|1001|風量|0048B702FD|空気清浄機||
|パナソニック|AEHA|522C|全灯|002C25|天井灯||
|パナソニック|AEHA|522C|消灯|002F26|天井灯||
|パナソニック|AEHA|522C|省エネ|002D24|天井灯||
|ビームテック|NEC|E384|全灯|20|天井灯||
|ビームテック|NEC|E384|消灯|24|天井灯||
|ビームテック|NEC|E384|お好み|2A|天井灯||
|東芝|NEC|BF40|電源|12|テレビ||
|東芝|NEC|BF40|入力切替|0F|テレビ||
|東芝|NEC|BF40|１|01|テレビ||
|SONY|SONY|093A|PLAY|32|プレステ２|DVD操作用（093A）とコントローラ用（1B5A）でアドレスが違う|
|SONY|SONY|093A|STOP|38|プレステ２||
|SONY|SONY|1B5A|×|32|プレステ２||

---
# 課題
- リモコンの中にはLeaderを持たないものがあるらしいが、対応できていない。
- 発光部分と無発光部分の両方の幅が変化するタイプのリモコンには、対応できない。

---
# 実装コード
- [GitHub](https://github.com/katsumin/irDecoder)で公開しています。

---
# リモコン送信実験
- 試しに、東芝製テレビの電源ボタン相当のコードだけ送信するプログラムを書いて、動かしてみました。
- 結果は、テレビの受光部から20cmほどまで近づけないと反応しませんでした。
- PLUSエンコーダ上の赤外線LEDは、ちょっとパワーが弱いようです。
    - 電流制限抵抗に470Ωが使われているようなので、小さくしてどうなるか試してみようと思っています。
    - まず、順方向電流（IF）を実測してみました。
        - 測定箇所は、赤外線LEDの＋側になります。
        - 変調周波数は約38kHzで、無発光時の電圧が3.52V、発光時の電圧が1.36Vとなっていることがわかります。
        - 発光時に流れる電流は、2.16/470＝4.6mAとなります。（かなり絞っている印象）
         ![SDS00032.jpg](https://qiita-image-store.s3.amazonaws.com/0/166435/99158060-536f-ee6c-504c-f3e53c5a35d9.jpeg)
    - 抵抗を変えてみました。
        - 100Ω（約22mA）にしたら、テレビまで1.3m離れたところで反応するようになりました。
        - 22Ω（約87mA）にしたら、テレビまで1.9m離れたところで反応するようになりました。
            - 発光時の電圧は1.6Vになりました。（1.92/22＝87mA）
            - 一般的な赤外線リモコンだと、もう少し離れても反応しますが、床に座った状態で天井灯をON／OFFするくらいにはなったので、これでよしとしました。