はじめに
Arduinoで赤外線リモコンの信号を読み取る方法を知っていますか?
今回は「Arduino 」と「赤外線受信モジュール」「赤外線リモコン」を使って、IR信号を生で読み取るコードを実装してみました!
赤外線通信の仕組み
赤外線リモコンは、「ON」「OFF」を繰り返すパルス信号を使って情報を送信します。この信号は、数ミリ秒単位で非常に高速に点滅しており、送信側と受信側がこのパターンを「0」や「1」として読み取ります。
信号は大きく分けて、以下の3つの要素で構成されています:
1.リーダー信号(リーダーコード)
通信の始まりを知らせる目印の信号です。
2.データ信号
アドレスやコマンドなどの情報をビット列で送信します。
3.ストップビット(Stop bit)
最後に送信される短いパルスで、通信の終了を示す信号です。
これにより受信側は「データがここで終わった」と認識でき、次の信号との区切りになります。
[リーダー信号] + [データ信号(1/0の組み合わせ)] + [ストップビット(Stop bit)]

リーダー信号とは?
リーダー信号は、赤外線通信の最初に送られる「同期用信号」です。
たとえばNECフォーマットの場合、次のようになります:
- 9ms間 ON(LED点灯)
- 4.5ms間 OFF(LED消灯)
この組み合わせを「スタートの合図」として受信側が認識します。
データ信号とは?
そのあとに送られるのが、ボタンの種類を表す「データ信号」です。
この部分は、”0″ または “1” のビット列で構成されており、たとえば次のような仕組みで送られます:
ビット値 | パルス長 |
---|---|
0 | 0.56ms ON + 0.56ms OFF |
1 | 0.56ms ON + 1.69ms OFF |
Arduino では pulseIn()
関数を使って、このOFFの長さを測ることで「0」か「1」かを判定しています。
ストップビット(Stop bit)とは?
赤外線通信では、データの終わりを示すためにストップビットが使用されます。これは、受信側に「データの送信が完了した」ことを知らせる重要な信号です。
たとえば、NECフォーマットの場合、ストップビットは以下のように構成されています:
- 0.56ms間 ON(赤外線LED点灯)
この短いON信号の後、赤外線の送信が停止します。受信側はこのパターンを検出することで、データの終わりを正確に認識し、次の処理に移ることができます。
ストップビットがあることで、受信側はデータの区切りを明確に判断でき、信号の解析が容易になります。
使用するパーツ一覧(IRリモコン制御)
- PC
- Arduino
- 赤外線受信モジュール(IR Receiver Module)
- 赤外線リモコン(IR Remote)
- ジャンパーワイヤー(メス-オス)

回路図

プログラム
以下が今回使うArduinoのコードです。
IRremoteライブラリなしで、pulseIn()
を使ってIR信号を解析しています。
// 赤外線受信モジュールを使った信号解析プログラム
int irRxPin = 11; // 赤外線受信モジュールの信号線をデジタルピン11に接続
void setup()
{
pinMode(irRxPin, INPUT); // ピン11を入力モードに設定(赤外線受信モジュールからの信号を受け取る)
Serial.begin(9600); // シリアル通信を9600bpsで初期化(PC側モニタに出力するため)
}
void loop()
{
unsigned long pulseLen; // パルス幅(HIGHの長さ)を記録する変数
unsigned long data = 0; // 受信した赤外線データを格納するための変数(最大64ビットまで)
int num; // 読み取ったビット数のカウント
// 1. 信号の始まりを待つ(赤外線が来るまで待機)
while (digitalRead(irRxPin)); // ピンがLOWになるまでループ(ボタンが押されるのを待つ)
// 2. リーダー部分のパルスを読み捨て(信号の先頭は無視)
pulseIn(irRxPin, HIGH, 30000); // 先頭の長いHIGH信号を測定(使わない)
// 3. データ部分を読み込む(最大64ビットまで)
for (num = 0; num < 64; num++) {
pulseLen = pulseIn(irRxPin, HIGH, 20000); // HIGHの長さを測定(最大20ms待つ)
if (pulseLen == 0) break; // タイムアウトしたら読み込み終了
data <<= 1; // データを1ビット左にシフト(1桁分空ける)
if (pulseLen > 900) {
data += 1; // パルスが900マイクロ秒以上なら「1」と判定(それ未満なら「0」)
}
}
// 4. 何かビットが読めた場合はシリアルモニタに表示(16進数で)
if (num > 0) {
Serial.println(data, HEX); // 例:0xFFA25D
}
delay(500); // ボタンを押し続けたときの連続リピート信号を無視するための待機
}
実行結果とポイント
このコードをArduinoに書き込み、シリアルモニタ(9600bps)を開いてリモコンのボタンを押すと、赤外線信号の16進数(HEX)コードが表示されます!
動作確認
1.シリアルモニタの確認
0、1、2…とリモコンのボタンを順番に押すと、それぞれに対応した赤外線信号がArduinoに受信され、シリアルモニタに16進数のコードとして表示されます。
たとえば、「0」のボタンでは FF6897
のようなコード、「1」では FF30CF
のような別のコードが表示されるはずです。
この出力結果を確認することで、各ボタンが異なる赤外線データを送信していることや、Arduinoと受信モジュールが正常に動作しているかがわかります。

2.リーダー信号の確認
リーダー信号は、赤外線通信の開始を示す重要な信号です。
理論値では「9ms間 ON、4.5ms間 OFF」と定義されています。今回の実測結果では、「9.04ms ON、4.56ms OFF」となっており、誤差はそれぞれ +0.04ms と +0.06ms でした。
この程度の誤差は、信号解析や通信処理に大きな影響を与えるものではなく、十分に理論値に近い精度で受信できていることが確認できます。

3.Stop bit の確認
Stop bit の波形は、通信の終了を示す重要な信号で、理論上は約0.56msのON信号です。
今回のオシロスコープによる実測では、Stop bit の長さにわずかな誤差が見られました。これは信号自体の異常ではなく、使用したオシロスコープの時間分解能があまり高くないことによる測定誤差が主な原因です。

まとめ
赤外線通信の基本は、見えない光を「点滅パターン」として送信し、受信側がそのパターンをデジタル信号として解析するという仕組みです。
Arduinoでは、それをコードで処理することで、リモコンのボタンに応じた反応をプログラムできるのが面白いポイントです!
コメント