M5AtomでIR通信でNECリモコンの照明を制御しようとした話

#背景
私は朝早起きが苦手で，いつも時間ギリギリに起きてしまいます。
噂で聞くところによると，徐々に明るくすると目覚めがいいらしいので，そのような照明を求めていました。

#目的
手元にM5Stack Liteが転がっていたので，内蔵赤外線LEDを使って照明を制御しようと思いました。
※ 使用した照明はNEC製のものです。

#結果
照明ON/OFFはできましたが，出力不足で使えたものではなかったです。

#開発環境
windows10
Visual Studio Code

#使用パーツ
M5Atom Lite
赤外線リモコン受信モジュール(OSRB38C9AA)
ブレッドボード
ジャンパワイヤー(スズメッキ線で代用)

#開発フロー
1. VSCodeをインストール
2. VSCodeにArduino拡張をインストール
3. 各種設定
4. リモコンのデータを記録し，送信データを作成
5. 照明に信号を送信し，制御を行うプログラムを作成

#詳細
##VSCodeをインストール
ArduinoIDEを使うのがつらかったのでVSCodeで開発することにしました。
私の環境では最新版のVSCodeではポート関係のバグがあるらしく[^1]，少し前のバージョンをインストールしました。
##VSCodeにArduino拡張をインストール
便利なことに，VSCodeにはMicrosoft製のArduino拡張機能が公開されています。それを入れてしまいましょう。
ただし，内部でArduinoIDEを呼び出しているらしいので，別途ArduinoIDEをインストールする必要があります。
##各種設定
Arduinoを使えるようになったら，各種設定が必要となります。
まず，必要となるボード設定とライブラリを入れましょう。
F1キーを押し，下記を行います。
1. Arduino: Board Manager　を開き，esp32を検索・インストール
2. Arduino: Board Configuration　を開き，ESP32 Dev Module(esp32)を選択（他は変えた覚えがない）
3. Arduino: Library Manager　を開き，M5Atom と　IRremoteESP8266 と　FastLED をインストール

次に細かい設定をします[^3][^4]。
###Arduinoのビルド時間短縮
C:\Users\username\AppData\Local\Arduino15\preferences.txt
の最終行に
build.path=C:\Users\username\AppData\Local\Temp\arduino_build
を追記します[^2]。
###intelliSenseEngine
左下歯車->設定->C_Cpp.intelliSenseEngine検索->Tag Parserで予測がよくなる
###ArduinoIDEの本体パス
左下歯車->設定->Arduino: PathにArduinoIDEのパスを入力
###M5Atomライブラリのエラー解消
私の環境ではM5Atomのライブラリをインクルードするとエラーが起きました。
なぜかワーニングをエラー扱いにしており，原因が理解できなかったので，その記述を削除しました。
C:\Users\username\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3\platform.txt
の下記2行を削除(これで正しいかは不明)

```platform.txt  
compiler.warning_flags.more=-Wall -Werror=all
compiler.warning_flags.all=-Wall -Werror=all -Wextra
```

#リモコンのデータを記録し，送信データを作成
照明を制御するため，まず照明のリモコンのON/OFFボタンがどのような信号を出しているか調べました。
手順は下記です

- 赤外線モジュールをM5Atom Liteに接続する  
ブレッドボードをうまいこと使って赤外線モジュールを接続しましょう。

| 信号名 | M5Atom | 赤外線モジュール |
|:-:|:-:|:-:|
| Vcc  |  3V3  |  3pin(球体を見て右) |
|  GND  |  GND |  2pin(真ん中） |
|  OUTPUT | G21  |  1pin(残り) |


- サンプルプログラムを書き込む
   Arduinoには赤外線受信用のサンプルプログラムがインストールされています（正確にはIRremoteESP8266に)
   Arduino: Examplesを開き，Examples from Custom Libraries -> IRremoteESP8266 -> IRrectDumpV3　を開きます。
   新しくウインドウが立ち上がりますので，IRrecvDumpV3.inoを開きます。
   
   ```
   const uint16_t kRecvPin = 14;
   ↓
   const uint16_t kRecvPin = 21;
   ```
   
   ```
   #include "BaseOTA.h"
   ↓
   #include "C:\\Users\\username\\Documents\\Arduino\\generated_examples\\IRrecvDumpV3_2\\BaseOTA.h"
   ```
   に書き換えます。(後者は正しい方法がわからなかったためよろしくない方法だと思う)
   
   F1->Arduino: Board Configuration -> Upload Speedを115200に変更します。(早すぎるとよくエラーが起こる)
   F1->Arduino: Select Serial Portを選択し，M5Atomが接続されているシリアルポート（私の場合はport 3）を選択します。
   F1->Arduino: Upload (.inoを開いているときに右上に現れる下向き矢印付きの箱をクリックでも可)を行い，書き込みます。
   エラー等なければそのまま実行状態に移るので，
   
   この状態でリモコンの電波をモジュールに当てると下記のような出力が表示されます。
   
- 実行してデータを記録
実際にデータを受信しましょう。
F1->Arduino: Open Serial Monitorでシリアルモニタを開き，赤外線モジュールに対してリモコンのON/OFFボタンを押してみましょう。
正常に動いていれば下記のようなデータが表示されるはずです。

```
Protocol  : NEC
Code      : 0x41B6D52A (32 Bits)
uint16_t rawData[71] = {9064, 4426,  648, 484,  650, 1606,  650, 480,  652, 476,  642, 488,  644, 488,  646, 482,  648, 1608,  650, 1608,  654, 480,  646, 1608,  650, 1610,  648, 484,  652, 1604,  654, 1604,  648, 484,  652, 1604,  652, 1606,  644, 486,  652, 1604,  654, 476,  652, 1606,  656, 476,  652, 1606,  644, 486,  650, 480,  648, 1610,  644, 486,  646, 1610,  644, 486,  644, 1614,  622, 508,  644, 40914,  9054, 2190,  634};  // NEC 41B6D52A
uint32_t address = 0x6D82;
uint32_t command = 0xAB;
uint64_t data = 0x41B6D52A;
```
重要なのはProtocolとCodeです。記録しましょう。
**Protocolがunknownの方は私には対処できません。私も知りたい。やり方がわかったら教えてください。（生データ送信関数使うのかな？）**

#照明に信号を送信し，制御を行うプログラムを作成
最後となりました。実際にプログラムを書いていきます。
今回はボタンを押したら照明をON/OFFする単純なものを書きます。
まず空のフォルダを用意し，ファイル->フォルダを開くで開きましょう。
次にF1->Arduino: Initializeで初期化します。
次にF1->Arduino: Board Configurationを開き，，ESP32 Dev Module(esp32)を選択，Upload Speedを115200に変更します。
次に実際にコードを書いていきます。

```Arduino:app.ino
#include "M5Atom.h"
#include "IRsend.h"

IRsend irsend(12);//赤外線LEDのピン番号

void setup()
{
	M5.begin(true, false, false);//それぞれUART, I2C, ディスプレイの使用
	irsend.begin();
}

void loop()
{
	M5.update();//必ず必要
	if(M5.Btn.isPressed()){//ボタンを押したときだけ
		irsend.sendNEC(0x41B6D52AUL);//Protocolの関数があればそれを使う
	                                 //送信数値はCodeの値+UL(64bit拡張のため)
		delay(100);//待機
	}
}

```

これを動かすと，照明の受信部にすごく近い位置にいればON/OFFできると思います（カバー外して接触させるレベル）！！！
動かない人は近づけ方が足りないかピン番号間違ってるかだと思います。

#結果
使い物になりませんでした！！！
残念！！！
外部回路でもっと強いLEDを使う等すれば簡単に使えるようになると思います。
赤外線のLEDは消費電流が大きいので，トランジスタ等をかませないとマイコンが壊れるかもしれないので気を付けてください。
私の家のもう一つの照明がDAIKOなのですが，その信号の出力方法を知っている方がいたらやり方を教えてほしいです。よろしくお願いします。


[^1]: https://qiita.com/MunoLike/items/a29cd8cb8b69dea26d5b
[^2]: https://hangstuck.com/arduino-buildpath-fix/
[^3]: https://qiita.com/mmt/items/7dd1a2f312334a6cd600
[^4]: https://qiita.com/narikei/items/847613a8f01a9e1527d7