ESP32で赤外線通信ができるライブラリ「IRremoteESP8266」の使い方

ESP32で赤外線を送受信する「IRremoteESP8266」の使い方

Wi-Fi, Bluetooth機能がある高性能マイコンのESP32赤外線の送信・受信を試してみたので使い方を概説します!

今回使用したライブラリはIRremoteESP8266という、ESP8266,ESP32向けに最適化された赤外線送受信ライブラリです。

参考にしたサイト

準備

使用した部品

赤外線LEDと受光モジュールはAmazonで50個セットで900円弱なので、こちらでもいいかもしれません。

ライブラリのインストール

  1. IRremoteESP8266のGithubリポジトリでzipファイルをダウンロード
  2. Arduino > スケッチ > ライブラリをインクルード > ZIP形式 からダウンロードしたzipファイルを選択してインクルードする。
  3. スケッチ例に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(); //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;
}

すっきりまとまりましたね。

  1. IRrecvオブジェクト(ここではirrecvという名前)を設定。引数は順番にセンサーのOUTピン、バッファサイズ、タイムアウト時間、false)。
  2. .enableIRIn()メソッドで受信を開始
  3. loop内にirrecv.decode(&results)を置く。何かデータを受信したらこのメソッドはtrueになり、resultsにデータを格納してくれる
  4. そのままのデータは読みにくいため、resultsToHumanReadableBasic()という関数が用意されていて、これにresultsを渡すと上の画像で見たようなフォーマットなどが成形されて出てくる
  5. また、各データを別々に取得する属性も用意されている(上記プログラムを参照のこと)

これで必要なデータの取得方法が分かりました。

送信

上記で取得したコードを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という技術を使う必要があります)。お楽しみください。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です