ESP32で赤外線リモコンを作る方法（IRremote v4.x）

### はじめに
今回はせっかく手に入れたESP32を使って自宅にあるリモコンを解析し，赤外線LEDを使ってテレビやエアコンを操作してみようと思います。

### 実装方針
リモコンの作成には，「受信して解析→送信する」の流れで進めていきます。

### 準備するもの
* **ESP32開発ボード**：[ESP32-DevKitC-32E ESP32-WROOM-32E開発ボード 4MB](https://akizukidenshi.com/catalog/g/g115673/)
* **USBケーブル**（ESP32とPCをつなげる用）：[USBケーブル USB2.0 A-microB](https://akizukidenshi.com/catalog/g/g107607/)
* **PC**（Windows）
* **赤外線リモコン受信モジュール（IRレシーバ）**：[OSRB38C9AA](https://akizukidenshi.com/catalog/g/g104659/)
* **赤外線LED**：[5mm 940nm OSI5FU5111C-40](https://akizukidenshi.com/catalog/g/g103261/)
* **N-mosfet**：[NchパワーMOSFET 60V 25A 2SK2232](https://akizukidenshi.com/catalog/g/g102414/)
* **2.2Ω抵抗**：[1W 2.2Ω カーボン抵抗](https://akizukidenshi.com/catalog/g/g107953/)
* **10kΩ抵抗**：[1/4W 10kΩ カーボン抵抗](https://akizukidenshi.com/catalog/g/g125103/)
* **ブレッドボード**：ESP32がしっかり取り付けられるように6穴連結ピン以上で広めの面積のものを用意
* **ジャンパワイヤ**：
    * [ブレッドボード・ジャンパーワイヤ 14種類×10本](https://akizukidenshi.com/catalog/g/g100288/)
    *  [ブレッドボード・ジャンパーワイヤ(オス-メス) 15cm(白)](https://akizukidenshi.com/catalog/g/g108935/)（任意）
* **調べたいリモコン**：
(例)
    * シーリングライト（Panasonic）
    * テレビのリモコン（ORION）
    * エアコンのリモコン（日立）

### 実装環境

#### 回路作成
最終的にこんな感じの回路になりました。<br>
##### 受信する用回路
![20240917181533.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680988/2233c001-fa93-8f9c-00f3-17bcd6f39ec4.jpeg)

##### 送信する用回路
![2024091718153a3.jpg](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yhotta240/20240917/20240917132914.jpg)





#### 実行環境
* Arduino IDE v2.3.2 
https://www.arduino.cc/en/software
* ESP32 v3.0.4<br>Arduino IDEのボードマネージャからインストール
https://github.com/espressif/arduino-esp32
* 使用ライブラリ：IRremote v4.4.1<br>Arduino IDEのライブラリマネージャでインストールする。もしくは以下のリンクから`\Arduino\libraries`にクローン
https://github.com/Arduino-IRremote/Arduino-IRremote

Arduino IDE やESP32のセットアップ方法については以前のブログを参考にしてください。
https://yhotta240.hatenablog.com/entry/2024/09/09/050147?_gl=1*1fuw8x4*_gcl_au*NjYyMjcwNDM3LjE3MjU1NTAzMjg.



### 赤外線を受信

Arduino IDEを開き，赤外線を受信するスケッチを作成します。
まず[IRremote](https://github.com/Arduino-IRremote/Arduino-IRremote) のドキュメントを確認してみました。

ドキュメント[New 4.x program:（新しい 4.x プログラム例）](https://github.com/Arduino-IRremote/Arduino-IRremote?tab=readme-ov-file#new-4x-program)で以下のようなプログラムの例があったのでこれをベースにスケッチを作成していきます。<br>

<details><summary>新しい 4.x プログラム例:</summary>

```cpp
#include <IRremote.hpp>
#define IR_RECEIVE_PIN 2

void setup()
{
...
  Serial.begin(115200); // // Establish serial communication
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Start the receiver
}

void loop() {
  if (IrReceiver.decode()) {
      Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); // Print "old" raw data
      IrReceiver.printIRResultShort(&Serial); // Print complete received data in one line
      IrReceiver.printIRSendUsage(&Serial);   // Print the statement required to send this data
      ...
      IrReceiver.resume(); // Enable receiving of the next value
  }
  ...
}
```
</details>


#### 受信用のスケッチ作成：
```cpp
#include <IRremote.hpp>  // IRremoteライブラリ
#define IR_RECEIVE_PIN 13 // GPIOピン番号を定義

void setup() {
  Serial.begin(115200);  // シリアル通信の初期化
  IrSender.begin(DISABLE_LED_FEEDBACK);  // 赤外線受信の初期化
}

void loop() {
  if (IrReceiver.decode()) {  // 信号を受信したら
    Serial.print("Received Raw Data: ");
    Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);  // 生のデータを16進数で表示

    IrReceiver.printIRResultShort(&Serial);  // 受信したデータの簡潔な概要を表示
    IrReceiver.printIRSendUsage(&Serial);    // 受信した信号を送信するためのコードを表示

    IrReceiver.resume();  // 次の信号を受信できるようにする
  }
}
```
ピンとコメントのところ以外は何も変えていません。

参考

https://github.com/Arduino-IRremote/Arduino-IRremote?tab=readme-ov-file#receiving-ir-codes:embed:cite

新規のスケッチを作成して完成した受信用のスケッチを貼り付けESP32に書き込みます。

#### 受信テスト：

プログラムが実行されたら任意のリモコンをレシーバに向け，リモコンの調べたいボタンを押します。

テレビのリモコンを例に受信されたデータを見ていきます。
![202409171sp8153a3.jpg](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yhotta240/20240917/20240917174716.jpg)

▼ **電源ボタン：**
```
Received Raw Data: F00F6380
Protocol=NEC Address=0x6380 Command=0xF Raw-Data=0xF00F6380 32 bits LSB first
Send with: IrSender.sendNEC(0x6380, 0xF, <numberOfRepeats>);
```

<details><summary>１チャンネルボタン： </summary>

```
Received Raw Data: FF006380
Protocol=NEC Address=0x6380 Command=0x0 Raw-Data=0xFF006380 32 bits LSB first
Send with: IrSender.sendNEC(0x6380, 0x0, <numberOfRepeats>);
```

</details>

<details><summary>２チャンネルボタン：</summary>

```
Received Raw Data: FE016380
Protocol=NEC Address=0x6380 Command=0x1 Raw-Data=0xFE016380 32 bits LSB first
Send with: IrSender.sendNEC(0x6380, 0x1, <numberOfRepeats>);
```

</details>

### 赤外線を送信

#### 送信用のスケッチ作成（テレビリモコン電源ボタン）
```cpp
#include <IRremote.hpp>
#define IR_SEND_PIN 4  // MOSFETを制御するGPIOピン

void setup() {
  // 赤外線送信モジュールの初期化
  IrSender.begin(IR_SEND_PIN, DISABLE_LED_FEEDBACK, 0);  
  Serial.begin(115200);  // シリアル通信の初期化
}

void loop() {
  // 受信したデータを再送信
  Serial.println("赤外線送信");
  IrSender.sendNEC(0x6380, 0xF, 0);  
  delay(5000);  // 5秒ごとに信号を送信
}

```
書き込みが完了したら送信テスト行います。

#### 送信テスト
プログラムを実行し，赤外線LEDをテレビに向けたところ5秒間隔で電源をオン・オフすることが確認できました。

### 最後に
お読みいただきありがとうございます。
この記事の詳しい内容やプログラムの解説については，以下のブログにまとめていますのでぜひご覧ください。

https://yhotta240.hatenablog.com/entry/2024/09/17/183201
### 参考
https://asukiaaa.blogspot.com/2021/12/copy-and-send-ir-signal-by-esp32-arduino.html

https://github.com/Arduino-IRremote/Arduino-IRremote?tab=readme-ov-file#supported-ir-protocols

https://docs.sunfounder.com/projects/esp32-starter-kit/ja/latest/arduino/basic_projects/ar_irremote.html