ESP32

ESP32で赤外線送信を試してみます

前回は、ESP32で赤外線受信モジュールを使用して、リモコンから発信する情報をモニタしました。今回は、モニタした信号を利用して、赤外線送信を試していきたいと思います。

赤外線送信を利用して、実際にテレビなどの機器制御をやっていきます。

ESP32で赤外線受信を試してみます ESP32で赤外線受信モジュールを使用して、ブルーレイレコーダーのリモコンから発信する情報を受信してモニタしてみたいと思います。 ...

ESP32と赤外線送信モジュールを接続

ESP32と赤外線送信モジュールを接続します。

準備するもの

今回使用するものは以下になります。

  • ESP32
  • ブレッドボード
  • 赤外線送信モジュール
  • ジャンパーワイヤー

赤外線送信モジュール

赤外線送信モジュールはAmazonで購入しました。

Amazonに仕様が記載されていなかったのですが、海外のサイトで同じようなものがあったので、とりあえず記載しておきます。

  • 電源電圧:5 V
  • 赤外線:38 kHz
  • 波長:940 nm
  • 距離:1~2 m

接続

以下のように接続していきます。

赤外線送信接続図

赤外線送信モジュールの接続ピンは、IRremoteライブラリで「#define」定義されていた「4番ピン」に接続しています。接続先を変更する場合は、ライブラリの定数を修正する必要があります。

プログラム作成

前回リモコンをモニタして受信した赤外線情報を そのまま送信するプログラムになります。

処理概要としては、コマンドを赤外線で繰り返し送信し続けるものになります。

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

赤外線送信処理を行うためにライブラリをインストールします。

Arduino IDEを起動して、メニューの「ツール」→「ライブラリを管理」を選択します。

表示した「ライブラリマネージャ」のテキストボックスに「IRremote」を入力します。

検索して表示された「IRremote」をインストールします。

このプログラムでは、バージョン「3.5.2」を使用しています。

ライブラリインストール

プログラム作成

一般的に、家電を操作する赤外線信号のフォーマットには、以下のような種類があります。

  • NECフォーマット
  • 家電製品協会フォーマット
  • SONYフォーマット など

詳しい赤外線通信については、Google先生に聞いてみてください。

TOSHIBAのREGZAリモコンで試したところ、受信した情報から「NECフォーマット」であることがわかりました。

NECフォーマット受信結果
  • プロトコル:NEC
  • カスタムコード:0xBC45
  • コマンド:0x01

モニタした赤外線情報から、該当するフォーマットに則って、送信処理を作成していきます・・・、といっても処理としては もの凄く短いです。

「IRremote」ライブラリをインストールした際に追加されるサンプルソースの「SendDemo」を参考に、作成してきます。

処理概要は、10秒間に1回 赤外線送信を行うといった簡単なものになります。

#include <IRremote.hpp>

int DELAY_AFTER_SEND = 10000;

void setup() {
  Serial.begin(115200);
  IrSender.begin();
}

void loop() {
  Serial.println("ir send");
  IrSender.sendNEC(0xBC45, 0x01, NO_REPEATS);
  delay(DELAY_AFTER_SEND);
}

プログラムについて簡単に説明していきます。

赤外線送信に関する部分は、7行目と12行目の処理になります。

「setup()」関数の中、7行目で「IrSender.begin()」で送信処理を開始させています。

「IrSender」は、IRremoteライブラリの中にある「IRsend」クラスのインスタンスになります。

「begin()」関数で行っている処理は、赤外線送信時のピン設定と、送信時のフィードバックを受け取るかどうかを設定しているようです。

ただ、赤外線送信ピンの設定は、ライブラリの中にある「IRTimer.hpp」というソースで「IR_SEND_PIN」が定義されています。この「#define」定義を消すか、「IR_SEND_PIN」定義の設定を変更する必要があります。単純に「bigin()」関数の引数でピン番号を設定しても正常に動作しないようでした。

#define IR_SEND_PIN 4 // can use any pin, no timer restrictions

ちなみに「IRTimer.hpp」は、私の環境では以下に配置されていました。

C:\Users\ユーザ名\Documents\Arduino\libraries\IRremote\src\private

/***************************************
 * ESP32 boards - can use any pin for timer
 ***************************************/
#elif defined(ESP32)

#  if ! defined(SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL)
#define SEND_AND_RECEIVE_TIMER_LEDC_CHANNEL 0 // The channel used for PWM 0 to 7 are high speed PWM channels
#  endif

#  if defined(SEND_PWM_BY_TIMER)
#    if !defined(IR_SEND_PIN)
#define IR_SEND_PIN 4 // can use any pin, no timer restrictions
#    endif

プログラムはバージョンによって異なる可能性があるので、ご注意ください。ちなみに使用したバージョンは、「3.5.2」です。

「#define」定義を消した場合は、「setup()」関数で、以下のbegin()を呼び出すようにします。

void IRsend::begin(uint8_t aSendPin, bool aEnableLEDFeedback, uint8_t aFeedbackLEDPin);
  • 第1引数:aSendPin・・・送信ピンNo
  • 第2引数:aEnableLEDFeedback・・・送信時フィードバック有無
  • 第3引数:aFeedbackLEDPin・・・送信時フィードバック時の点灯LEDピンNo

注意点としては、処理がPWMになるので、PWM出力ができるピンを割り当てる必要があります。

「loop()」関数の中、12行目の「IrSender.sendNEC()」で赤外線送信を行っております。

sendNEC(uint16_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats, bool aIsRepeat = false)

引数の定義は以下になります。

  • 第1引数:aAddress・・・カスタムコード
  • 第2引数:aCommand・・・コマンド
  • 第3引数:aNumberOfRepeats・・・リピート回数(送信間隔あり)
  • 第4引数:aIsRepeat・・・間隔をあけずに1回リピート送信する(省略可)

実際にリモコンをモニタした際のデータを元に、カスタムコード:「0xBC45」、コマンド:「0x01」を設定しています。リピート回数には、「NO_REPEATS = 0」を設定しています。

動作確認

実際に動作を確認してみます。

赤外線送信動作確認

テストに使用した送信コマンドは、リモコンの「チャンネル1」のボタンを押したものと同等になります。

送信機をブルーレイレコーダーの方に向けると、10秒間に1回チャンネルが切り替わることが確認できました。

ただ、思ったよりも信号が弱く、距離が1m以上離れると反応しなくなります。ESP32 1台で複数の家電を制御するためには、赤外線の送信距離をもう少し伸ばさないと難しそうです。勉強不足なので、今後の課題として検討していきたいと思います。

プログラム改造(Panasonic製品で確認)

続きまして、プログラムを改造して Panasonic製テレビのリモコンでも同様に赤外線通信の確認をしていきたいと思います。

リモコから受信した情報で、「Panasonic」製品を使用したことが わかりましたが、フォーマットが何かわかりませんでした。Google先生に聞いてみるとPanasonic製品は、「家電製品協会フォーマット」のようです。

家製協フォーマット受信結果

ただ、「IRremono」のライブラリでは 特に意識する必要がなく、赤外線を送信する関数を「sendPanasonic()」に変更するだけで良さそうです。

実際のプログラムは、以下になります。

#include <IRremote.hpp>

int DELAY_AFTER_SEND = 10000;

void setup() {
  Serial.begin(115200);
  IrSender.begin();
}

void loop() {
  Serial.println("ir send");
  IrSender.sendPanasonic(0x08, 0x3D, NO_REPEATS);
  delay(DELAY_AFTER_SEND);
}

変更した部分は、12行目のIrSender.sendPanasonic()の部分だけになります。

sendPanasonic(uint16_t aAddress, uint8_t aCommand, uint_fast8_t aNumberOfRepeats)

引数の定義は、以下になります。

  • 第1引数:aAddress・・・アドレス
  • 第2引数:aCommand・・・コマンド
  • 第3引数:aNumberOfRepeats・・・リピート回数(送信間隔あり)

家電製品協会フォーマットだと、第1引数と第2引数を合わせてデータ部となっているようでした。プログラムの構造的に分かれているだけで、アドレスとコマンドという意識は特になさそうです(間違っていたらすみません)。

とりあえず赤外線受信をして、表示された値をそのまま設定するのが良さそうです。

アドレス:「0x08」、コマンド:「0x3D」を設定しています。リピート回数には、「NO_REPEATS = 0」を設定しています。

動作確認

送信コマンドは、Panasonicテレビの電源ONボタンと同等になります。

こちらも、送信機をテレビに向けると電源ONすることが確認できました。赤外線送信関数を変更するだけで、異なったフォーマットの信号制御がお手軽にできるようです。

まとめ

ESP32で赤外線送信をためしてみました。

「IRremote」ライブラリを使用することで、赤外線送信も受信と同様に簡単に動作させることが出来ました。

今回は「NECフォーマット」のTOSHIBA製品と、「家電製品協会フォーマット」のPanasonic製品の確認を行いましたが、機会があればSONY製品も試してみたいと思います(家にSONY製のリモコンがありませんでした)。

ただし、今回使用した赤外線送信モジュールだと、距離が1m以上離れると制御できなくなるようなので、複数の機器をESP32単体で制御するのは物理的な距離の制限で難しそうです。

別途、赤外線の制御距離を延ばす方法を検討していきたいと思います。

赤外線のコマンドを学習して、リモコンのように操作できるようなアプリを作成してみるのも面白そうです。