💨

Arduinoで赤外線送信機を作る

2023/09/20に公開

はじめに

以前赤外線受信機を作ったので今回は送信機を作りたいと思います。
以前と同じくIRRemoteライブラリを使用します。
https://github.com/Arduino-IRremote/Arduino-IRremote

また送信機には赤外線LEDを使用しますが、こちらは通常のLEDとは違うため作成の際には注意が必要です。
https://www.amazon.co.jp/VKLSVAN-VS1838B-HX1838-赤外線センサー-リモコン受光部/dp/B09NPYNSN5/ref=sr_1_5?keywords=赤外線led&qid=1695116023&sr=8-5

赤外線通信の仕組み

赤外線通信では、特定のキャリア周波数(基本38kHz)でLEDを点滅させて信号を送信します。受信側の機器がそのパターンを認識し、指定された動作を実行します。

概ね下記の流れだと思ってます。

  1. 信号開始
    通信の開始を示す合図

  2. データ送信
    アドレス: 送信元デバイスを特定するための情報
    データ: 実際のコマンド (例. 電源ON/OFFなど)

  3. 信号終了

また赤外線通信には様々なデータフォーマットがあり、例えばNECプロトコルでは下記のような設定がされているそうです。(ChatGPT調べ)

NECプロトコルの基本的な仕様:
キャリア周波数は38kHz

  1. 信号開始のための長いヘッダパルス(マーク)(9ms)とスペース(4.5ms)から始まります。

  2. データは32ビットとして送信されます
    (例:アドレス8ビット、逆アドレス8ビット、データ8ビット、逆データ8ビット)。
    各ビットは、0.5625msのマーク(LED ON)に続くスペースで表されます。'0' は0.5625msのスペースで、'1' は1.6875msのスペースで表されます。

  3. 信号終了後は、約40msのスペースが続きます。

※「マーク」とは、LEDが点灯している状態を指し、「スペース」とは、LEDが消灯している状態を指します。

IRRemoteを使用することで、既存のプロトコルを使用することも、独自でプロトコルを実装することも可能みたいです。

回路


今回はボタンを押下した際、送信するようにしています。

コード

#include <IRremote.hpp> // include the library

int SEND_LED_PIN = 4;
int BUTTON_PIN = 7;

void setup() {
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    IrSender.begin(SEND_LED_PIN);
}

uint8_t sCommand = 0x34;
uint8_t sRepeats = 0;

void loop() {

    // Receiver output for the first loop must be: Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 (32 bits)
    if (digitalRead(BUTTON_PIN) == LOW) {
       IrSender.sendNEC(0x00, sCommand, sRepeats);
    }
    delay(100);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
}

setup()内

IrSender.begin(SEND_LED_PIN);void IRsend::begin(uint_fast8_t aSendPin, bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin)

赤外線送信ライブラリ(IRsendクラス)の初期化を行います。具体的には、赤外線LEDを接続するピン、フィードバックLEDの設定などを行います。

関数の引数について:
aSendPin: 赤外線LEDを接続するArduinoのピン番号。
aEnableLEDFeedback: フィードバックLEDを有効にするかどうかの真偽値。有効の場合、赤外線が送信されるときにフィードバックLEDも点灯します。
aFeedbackLEDPin: フィードバックLEDを接続するArduinoのピン番号。

上記では特にフィードバックLEDを無効化していないので、sendPinだけ指定しています。

loop()内

IrSender.sendNEC(0x00, sCommand, sRepeats);void IRsend::sendNEC(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats)

上述したNECのプロトコルを使用する関数です。
今回はこちを使用しましたが他にも関数は用意されています。

関数の引数について:
aAddress: 送信するデータのアドレス部分。通常はリモコンや受信機の特定のモデルやブランドを識別するためのものです。
aCommand: 送信するコマンド。例えば、電源のオン/オフやボリュームアップ/ダウンなどの具体的な操作を表します。
aNumberOfRepeats: 送信するリピートフレームの数。リピートフレームは、同じコマンドを連続して送信するためのものです。引数の説明によれば、この値が0未満の場合、特殊なリピートフレームが送信されるようです。

リピートフレームとは一連のコマンドを繰り返し送信するための特殊なフレームのことを指します。
設定する目的と用途としては、下記などがあるようです。

継続的な信号送信:ユーザがリモコンのボタンを押し続けている間(例:テレビの音量を上げ続ける)、リピートフレームが継続的に送信されます。これにより、受信側のデバイスは同じコマンドを繰り返し実行します。
信号の信頼性向上:もし初回の信号が何らかの理由で正しく受信されなかった場合、リピートフレームによって信号が再送されることで、受信側がコマンドを正しく認識する確率が上がります。

今回は特にリピートさせる必要はなかったので0を設定しています。

サンプルコード

サンプルはこちらにあります。ただ、こちらは普通のLEDになっており、赤外線送信のシュミレーションは動作しません。🙇
https://www.tinkercad.com/things/0DRBRbleK1L-irremote-sender-sample

受信機があれば、実際に確認もできると思いますのでよければこちらも参考に。
https://zenn.dev/arsaga/articles/6737b5ea9fb087

参考資料

https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/examples/SimpleSender/SimpleSender.ino
https://laboratory.kazuuu.net/try-using-ir-remote-infrared-receiver-module-that-can-be-wirelessly-controlled/#toc2
https://burariweb.info/electronic-work/arduino-learning/arduino-ir-module-use.html#LED
https://burariweb.info/electronic-work/arduino-learning/arduino-ir-module-use.html#LED
https://bokunimo.net/bokunimowakaru/std-commander.html

Arsaga Developers Blog

Discussion