ESP32で赤外線を送受信する「IRremoteESP8266」の使い方
Wi-Fi, Bluetooth機能がある高性能マイコンのESP32で赤外線の送信・受信を試してみたので使い方を概説します!
今回使用したライブラリはIRremoteESP8266という、ESP8266,ESP32向けに最適化された赤外線送受信ライブラリです。
参考にしたサイト
準備
使用した部品
赤外線LEDと受光モジュールはAmazonで50個セットで900円弱なので、こちらでもいいかもしれません。
ライブラリのインストール
- IRremoteESP8266のGithubリポジトリでzipファイルをダウンロード
- Arduino > スケッチ > ライブラリをインクルード > ZIP形式 からダウンロードしたzipファイルを選択してインクルードする。
- スケッチ例にIRremoteESP8266があるか確認する
以上で使用するライブラリのインストールは終了です。
回路をつくる
送受信に対応した回路を以下の通りに作りました。


- 受信機のOUT: IO12
- 送信LED: IO17
ESP32のピンからは大きな電流を流せないため、LEDをトランジスタ経由で駆動しています。
これで瞬間的に1000mA程度流せるようになります。
受信
受信したデータをシリアルに表示
以下のプログラムはスケッチ例の「IRrecvDumpV2」のコメントを削除し、回路に合わせてピンの番号を書き換えたものです。
#include <Arduino.h>
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRac.h>
#include <IRtext.h>
#include <IRutils.h>
const uint16_t kRecvPin = 12;
const uint32_t kBaudRate = 115200;
const uint16_t kCaptureBufferSize = 1024;
#if DECODE_AC
const uint8_t kTimeout = 50;
#else
const uint8_t kTimeout = 15;
#endif
const uint16_t kMinUnknownSize = 12;
#define LEGACY_TIMING_INFO false
IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
decode_results results;
void setup() {
Serial.begin(kBaudRate, SERIAL_8N1);
#if DECODE_HASH
irrecv.setUnknownThreshold(kMinUnknownSize);
#endif
irrecv.enableIRIn();
}
void loop() {
if (irrecv.decode(&results)) {
uint32_t now = millis();
Serial.printf(D_STR_TIMESTAMP " : %06u.%03u\n", now / 1000, now % 1000);
if (results.overflow)
Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize);
Serial.println(D_STR_LIBRARY " : v" _IRREMOTEESP8266_VERSION_ "\n");
Serial.print(resultToHumanReadableBasic(&results));
String description = IRAcUtils::resultAcToString(&results);
if (description.length()) Serial.println(D_STR_MESGDESC ": " + description);
yield();
#if LEGACY_TIMING_INFO
Serial.println(resultToTimingInfo(&results));
yield();
#endif
Serial.println(resultToSourceCode(&results));
Serial.println();
yield();
}
}
- 結果
プログラムを走らせ、赤外線センサーの前でリモコンを押すと、以下のような情報がシリアルモニターに表示されます。

赤外線には規格があり、この通信プロトコルはNECフォーマットのようです。また、それ以下には受信したデータが各種形式で表示されています。
このdata
の部分が次の送信に使うコードとなります。
受信プログラムの解説
##include <Arduino.h>
#include <IRsend.h>
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRutils.h>
const uint16_t kRecvPin = 12;
const uint16_t kIrLedPin = 17;
const uint32_t kBaudRate = 115200;
const uint16_t kCaptureBufferSize = 1024;
const uint8_t kTimeout = 50;
const uint16_t kFrequency = 38000;
decode_results results;
IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, false);
void setup() {
irrecv.enableIRIn();
Serial.begin(kBaudRate, SERIAL_8N1);
}
void loop() {
if (irrecv.decode(&results)) {
Serial.print(resultToHumanReadableBasic(&results));
decode_type_t protocol = results.decode_type;
uint16_t size = results.bits;
uint32_t value = results.value;
}
すっきりまとまりましたね。
- IRrecvオブジェクト(ここではirrecvという名前)を設定。引数は順番にセンサーのOUTピン、バッファサイズ、タイムアウト時間、false)。
.enableIRIn()
メソッドで受信を開始
- loop内に
irrecv.decode(&results)
を置く。何かデータを受信したらこのメソッドはtrueになり、resultsにデータを格納してくれる
- そのままのデータは読みにくいため、
resultsToHumanReadableBasic()
という関数が用意されていて、これにresultsを渡すと上の画像で見たようなフォーマットなどが成形されて出てくる
- また、各データを別々に取得する属性も用意されている(上記プログラムを参照のこと)
これで必要なデータの取得方法が分かりました。
送信
上記で取得したコードを1秒おきに送信するプログラムです。実はこのコードは私の部屋の明かりをオンオフするもので、実行するとめっちゃチカチカします。
もちろん、ご自分の取得したコードに書き換えて試してみてください。
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <IRutils.h>
const uint16_t kIrLed = 17;
IRsend irsend(kIrLed);
bool success = true;
decode_type_t protocol = NEC;
uint16_t size = 32;
const uint32_t value = 0x41B658A7;
void setup() {
irsend.begin();
}
void loop() {
success = irsend.send(protocol, value, size);
if (success){
Serial.println("send success");
}
delay(1000);
}
最小限のプログラムのみ載せてコメントもつけているので、解説は省きます。
赤外線リピーター
以上で送信・受信の基本的な使い方を紹介しました。
これらを使って、受信したデータを3秒後にESP32から発信する、ジャミングみたいなプログラムを書きました。スケッチ例の「SmartIRRepeater」のコメントを削除し、回路に合わせてピンの番号を書き換えたものです。
これをテレビの前にセットしておけば、「ついついテレビ見ちゃう!」という誘惑を瞬時に断ち切ることができます。
#include <Arduino.h>
#include <IRsend.h>
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRutils.h>
const uint16_t kRecvPin = 12;
const uint16_t kIrLedPin = 17;
const uint32_t kBaudRate = 115200;
const uint16_t kCaptureBufferSize = 1024;
const uint8_t kTimeout = 50;
const uint16_t kFrequency = 38000;
IRsend irsend(kIrLedPin);
IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, false);
decode_results results;
void setup() {
irrecv.enableIRIn();
irsend.begin();
Serial.begin(kBaudRate, SERIAL_8N1);
while (!Serial)
delay(50);
Serial.println();
Serial.print("SmartIRRepeater is now running and waiting for IR input "
"on Pin ");
Serial.println(kRecvPin);
Serial.print("and will retransmit it on Pin ");
Serial.println(kIrLedPin);
}
void loop() {
if (irrecv.decode(&results)) {
decode_type_t protocol = results.decode_type;
uint16_t size = results.bits;
bool success = true;
if (protocol == decode_type_t::UNKNOWN) {
Serial.println("unknown");
uint16_t *raw_array = resultToRawArray(&results);
size = getCorrectedRawLength(&results);
delay(3000);
irsend.sendRaw(raw_array, size, kFrequency);
delete [] raw_array;
} else if (hasACState(protocol)) {
delay(3000);
success = irsend.send(protocol, results.state, size / 8);
} else {
delay(3000);
success = irsend.send(protocol, results.value, size);
}
irrecv.resume();
uint32_t now = millis();
Serial.printf(
"%06u.%03u: A %d-bit %s message was %ssuccessfully retransmitted.\n",
now / 1000, now % 1000, size, typeToString(protocol).c_str(),
success ? "" : "un");
}
yield();
}
まとめ
ESP32で赤外線通信ができるIRRemoteESP8266を使って赤外線通信を行いました。
今回は知られているフォーマット(NEC等)と、知らないフォーマットでの受信・送信も行えるプログラムになっています。
つまり、PICマイコンなどで生成した独自のデータをデコードして、ESP32で受信してデータを集約するなんてことも可能です。
またESP32のインターネットにつながる特徴を生かして、LINEなどから明かり・テレビ・エアコンをつけることもできますね(MQTTという技術を使う必要があります)。お楽しみください。
目次
ESP32で赤外線を送受信する「IRremoteESP8266」の使い方
Wi-Fi, Bluetooth機能がある高性能マイコンのESP32で赤外線の送信・受信を試してみたので使い方を概説します!
今回使用したライブラリはIRremoteESP8266という、ESP8266,ESP32向けに最適化された赤外線送受信ライブラリです。
参考にしたサイト
準備
使用した部品
赤外線LEDと受光モジュールはAmazonで50個セットで900円弱なので、こちらでもいいかもしれません。
ライブラリのインストール
以上で使用するライブラリのインストールは終了です。
回路をつくる
送受信に対応した回路を以下の通りに作りました。
ESP32のピンからは大きな電流を流せないため、LEDをトランジスタ経由で駆動しています。
これで瞬間的に1000mA程度流せるようになります。
受信
受信したデータをシリアルに表示
以下のプログラムはスケッチ例の「IRrecvDumpV2」のコメントを削除し、回路に合わせてピンの番号を書き換えたものです。
#include <Arduino.h> #include <IRrecv.h> #include <IRremoteESP8266.h> #include <IRac.h> #include <IRtext.h> #include <IRutils.h> const uint16_t kRecvPin = 12; //受信ピン const uint32_t kBaudRate = 115200; //シリアルの通信レート const uint16_t kCaptureBufferSize = 1024; //受信データのバッファサイズ #if DECODE_AC const uint8_t kTimeout = 50; #else const uint8_t kTimeout = 15; #endif const uint16_t kMinUnknownSize = 12; #define LEGACY_TIMING_INFO false IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true); //受信用オブジェクト decode_results results; //結果格納用 void setup() { Serial.begin(kBaudRate, SERIAL_8N1); #if DECODE_HASH irrecv.setUnknownThreshold(kMinUnknownSize); #endif irrecv.enableIRIn(); } void loop() { if (irrecv.decode(&results)) { //データを受け取った場合 uint32_t now = millis(); //現在の時間を取得 Serial.printf(D_STR_TIMESTAMP " : %06u.%03u\n", now / 1000, now % 1000); if (results.overflow) //データがオーバーフローしたとき Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize); Serial.println(D_STR_LIBRARY " : v" _IRREMOTEESP8266_VERSION_ "\n"); Serial.print(resultToHumanReadableBasic(&results)); //結果を人間が読める形にしてシリアルに表示 String description = IRAcUtils::resultAcToString(&results); if (description.length()) Serial.println(D_STR_MESGDESC ": " + description); yield(); //WatchDogTimerを正常に動作させるため(?) #if LEGACY_TIMING_INFO Serial.println(resultToTimingInfo(&results)); yield(); #endif Serial.println(resultToSourceCode(&results)); Serial.println(); yield(); } }
プログラムを走らせ、赤外線センサーの前でリモコンを押すと、以下のような情報がシリアルモニターに表示されます。
赤外線には規格があり、この通信プロトコルはNECフォーマットのようです。また、それ以下には受信したデータが各種形式で表示されています。
この
data
の部分が次の送信に使うコードとなります。受信プログラムの解説
##include <Arduino.h> #include <IRsend.h> #include <IRrecv.h> #include <IRremoteESP8266.h> #include <IRutils.h> const uint16_t kRecvPin = 12; //受信ピン const uint16_t kIrLedPin = 17; //赤外線LEDのピン const uint32_t kBaudRate = 115200; //Serial通信速度 const uint16_t kCaptureBufferSize = 1024; //バッファサイズ const uint8_t kTimeout = 50; //タイムアウト時間 const uint16_t kFrequency = 38000; //赤外線周波数 decode_results results; //結果格納変数 IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, false); //受信オブジェクト void setup() { irrecv.enableIRIn(); //受信を開始 Serial.begin(kBaudRate, SERIAL_8N1); //シリアル開始 } void loop() { if (irrecv.decode(&results)) { //データを受け取った場合 Serial.print(resultToHumanReadableBasic(&results)); //結果を人間が読める形にしてシリアルに表示 //下記のように各データを取得する関数もある decode_type_t protocol = results.decode_type; //赤外線のプロトコルを取得 uint16_t size = results.bits; //データサイズを取得 uint32_t value = results.value; }
すっきりまとまりましたね。
.enableIRIn()
メソッドで受信を開始irrecv.decode(&results)
を置く。何かデータを受信したらこのメソッドはtrueになり、resultsにデータを格納してくれるresultsToHumanReadableBasic()
という関数が用意されていて、これにresultsを渡すと上の画像で見たようなフォーマットなどが成形されて出てくるこれで必要なデータの取得方法が分かりました。
送信
上記で取得したコードを1秒おきに送信するプログラムです。実はこのコードは私の部屋の明かりをオンオフするもので、実行するとめっちゃチカチカします。
もちろん、ご自分の取得したコードに書き換えて試してみてください。
#include <IRremoteESP8266.h> #include <IRsend.h> #include <IRutils.h> const uint16_t kIrLed = 17; //赤外線LEDのピンを取得 IRsend irsend(kIrLed); // 送信オブジェクト bool success = true; decode_type_t protocol = NEC; uint16_t size = 32; const uint32_t value = 0x41B658A7; //部屋の明かりをつけるコード void setup() { irsend.begin(); // 赤外線LEDの設定 } void loop() { success = irsend.send(protocol, value, size); //送信 if (success){ Serial.println("send success"); } delay(1000); }
最小限のプログラムのみ載せてコメントもつけているので、解説は省きます。
赤外線リピーター
以上で送信・受信の基本的な使い方を紹介しました。
これらを使って、受信したデータを3秒後にESP32から発信する、ジャミングみたいなプログラムを書きました。スケッチ例の「SmartIRRepeater」のコメントを削除し、回路に合わせてピンの番号を書き換えたものです。
これをテレビの前にセットしておけば、「ついついテレビ見ちゃう!」という誘惑を瞬時に断ち切ることができます。
#include <Arduino.h> #include <IRsend.h> #include <IRrecv.h> #include <IRremoteESP8266.h> #include <IRutils.h> const uint16_t kRecvPin = 12; //受信ピン const uint16_t kIrLedPin = 17; //赤外線LEDのピン const uint32_t kBaudRate = 115200; //Serial通信速度 const uint16_t kCaptureBufferSize = 1024; //バッファサイズ const uint8_t kTimeout = 50; //タイムアウト時間 const uint16_t kFrequency = 38000; //赤外線周波数 IRsend irsend(kIrLedPin); //送信オブジェクト IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, false); //受信オブジェクト decode_results results; //結果格納変数 void setup() { irrecv.enableIRIn(); //受信を開始 irsend.begin(); //送信準備 Serial.begin(kBaudRate, SERIAL_8N1); //シリアル開始 while (!Serial) delay(50); Serial.println(); Serial.print("SmartIRRepeater is now running and waiting for IR input " "on Pin "); Serial.println(kRecvPin); Serial.print("and will retransmit it on Pin "); Serial.println(kIrLedPin); } void loop() { if (irrecv.decode(&results)) { //データを受け取った場合 decode_type_t protocol = results.decode_type; //赤外線のプロトコルを取得 uint16_t size = results.bits; //データサイズを取得 bool success = true; //送信の成否の変数 if (protocol == decode_type_t::UNKNOWN) { //知らないプロトコルの場合 Serial.println("unknown"); uint16_t *raw_array = resultToRawArray(&results); //生のデータを格納 size = getCorrectedRawLength(&results); //正しいデータサイズを取得 delay(3000); irsend.sendRaw(raw_array, size, kFrequency); //取得した生データを送信 delete [] raw_array; //生データ格納配列を削除 } else if (hasACState(protocol)) { //プロトコルがACの場合 delay(3000); success = irsend.send(protocol, results.state, size / 8); //送信 } else { //NECやTOSHIBA等の知られたフォーマットの時 delay(3000); success = irsend.send(protocol, results.value, size); //送信 } irrecv.resume(); //受信再開 uint32_t now = millis(); //現在の時間を保存 Serial.printf( "%06u.%03u: A %d-bit %s message was %ssuccessfully retransmitted.\n", now / 1000, now % 1000, size, typeToString(protocol).c_str(), success ? "" : "un"); //送信データの詳細をシリアルモニタに出力 } yield(); }
まとめ
ESP32で赤外線通信ができるIRRemoteESP8266を使って赤外線通信を行いました。
今回は知られているフォーマット(NEC等)と、知らないフォーマットでの受信・送信も行えるプログラムになっています。
つまり、PICマイコンなどで生成した独自のデータをデコードして、ESP32で受信してデータを集約するなんてことも可能です。
またESP32のインターネットにつながる特徴を生かして、LINEなどから明かり・テレビ・エアコンをつけることもできますね(MQTTという技術を使う必要があります)。お楽しみください。