はじめに:赤外線リモコンとArduinoで広がるIoTの世界

テレビやエアコンを操作する赤外線リモコン。その信号を自分のマイコンで受信・解析できたら、様々なIoTアプリケーションが実現できます。

  • 家電の状態を自動記録するスマートホーム
  • 複数の家電を一括操作する統合リモコン
  • リモコン操作をトリガーにした自動化システム
  • 赤外線信号を学習・再送信する万能リモコン

今回は、Arduino UNO赤外線受信モジュール(OSRB38C9AA)、そしてIRremoteライブラリを使って、家庭用リモコンの信号を受信・解析し、その信号に応じて6個のLEDを制御するシステムを構築します。

単に「動かす」だけでなく、赤外線通信の原理信号のデコード方法実用的な制御ロジックまで、電子工作とプログラミングの両面から詳しく解説していきます。

Arduino UNO R4 Minima

Arduino UNO R4 Minima

Arduino UNO R4 Minima starter kit

Arduino UNO R4 Minima starter kit


赤外線とは?電磁波の基礎知識

赤外線の特性と可視光線との違い

**赤外線(Infrared、IR)**は、可視光線よりも波長が長い電磁波の一種です。人間の目には見えませんが、熱として感じることができ、リモコン通信に最適な特性を持っています。

電磁波のスペクトル

波長(nm)   種類          用途
200-380    紫外線        殺菌、日焼け
380-450    可視光(青)   照明、ディスプレイ
450-550    可視光(緑)   照明、ディスプレイ
550-700    可視光(赤)   照明、ディスプレイ
700-1400   近赤外線      リモコン、通信(← 今回使用)
1400-3000  中赤外線      暖房、センサー
3000-      遠赤外線      暖房、調理

リモコンに使われる赤外線の特徴:

特性 詳細 メリット
波長 約850-950nm(近赤外線) LEDで容易に発生可能
指向性 比較的直進性が高い 特定の機器だけを操作できる
減衰 壁を透過しない 他の部屋の機器に影響しない
コスト 部品が安価 大量生産に適している
消費電力 極めて低い 電池で長期間動作可能

なぜ赤外線がリモコンに使われるのか?

1. 人間の目に見えない

  • 可視光だと点滅が気になる
  • 赤外線なら視覚的なノイズがゼロ

2. 太陽光や室内照明の影響を受けにくい

  • 38kHzという特定の周波数で変調することで、ノイズと区別可能
  • フィルタ回路で不要な光をカット

3. 安価で確実な通信

  • 赤外線LEDと受信モジュールは数十円から入手可能
  • 30年以上の実績がある枯れた技術

4. 免許不要

  • 電波(Wi-Fi、Bluetooth)と違い、電波法の規制対象外
  • 申請や認証なしで自由に使用可能

電子工作の基礎知識:この工作で必要な予備知識

このプロジェクトを理解するために必要な、電子工作の基本概念を解説します。

1. デジタル信号とアナログ信号

デジタル信号(Digital Signal)

**HIGH(5V)LOW(0V)**の2つの状態だけで情報を表現します。

電圧
5V  ┌─┐    ┌─┐    ┌─┐
    │  │    │  │    │  │
0V  ┘  └──┘  └──┘  └──
      1   0  0   1  0  0  1  0  ← ビット列

今回の使用例:

  • 赤外線受信モジュールの出力 → デジタル信号
  • LED制御のdigitalWrite() → デジタル出力

アナログ信号(Analog Signal)

連続的に変化する電圧で情報を表現します。

電圧
5V   ╱╲    ╱╲
    ╱  ╲  ╱  ╲
0V ╱    ╲╱    ╲
   ← 連続的に変化

応用例:

  • 温度センサー(電圧が温度に比例)
  • 可変抵抗器(ボリューム)
  • PWM制御による疑似アナログ出力

2. GPIO(汎用入出力ピン)の基本

**GPIO(General Purpose Input/Output)**は、Arduinoのデジタルピン(D0-D13)やアナログピン(A0-A5)のことです。

入力モード(INPUT)

外部からの信号を読み取るモードです。

pinMode(A0, INPUT);           // A0を入力に設定
int value = digitalRead(A0);  // HIGHまたはLOWを読み取り

今回の使用: 赤外線受信モジュールの信号を読み取り

出力モード(OUTPUT)

外部にHIGH(5V)またはLOW(0V)を出力するモードです。

pinMode(2, OUTPUT);      // D2を出力に設定
digitalWrite(2, HIGH);   // D2に5Vを出力(LEDが点灯)
digitalWrite(2, LOW);    // D2に0Vを出力(LEDが消灯)

今回の使用: LEDの点灯・消灯制御

3. 電流制限抵抗の計算方法

LEDを直接電源につなぐと、過電流で破壊されます。電流制限抵抗で適切な電流に制限する必要があります。

オームの法則による計算

R(抵抗値Ω)= V(電圧V)÷ I(電流A)

LED接続時の計算例:

Arduinoピン(5V)→ [抵抗R] → [LED] → GND(0V)

条件:
- Arduino出力電圧:5V
- LED順方向電圧(Vf):2V(赤色LED標準値)
- LED定格電流(If):20mA = 0.02A(標準的な値は15-20mA)

計算:
R = (5V - 2V) ÷ 0.02A = 3V ÷ 0.02A = 150Ω

実際の選定:

  • 計算値:150Ω
  • 実際の部品:220Ω(E12系列の標準抵抗値、安全マージン込み)
  • 結果の電流:(5V - 2V) ÷ 220Ω ≈ 13.6mA(LEDに優しい値)

抵抗値と明るさの関係:

抵抗値 電流 LED明るさ 備考
100Ω 30mA ⚠️ 明るいが過電流 長時間使用で劣化
220Ω 13.6mA ✅ 適度な明るさ 推奨値
330Ω 9.1mA やや暗い 省電力重視
1kΩ 3mA かなり暗い インジケーター用

4. ブレッドボードの構造と使い方

ブレッドボードは、ハンダ付け不要で部品を接続できる便利なツールです。

    電源ライン(縦方向で接続)
    ↓
    + + + + + + + +     ← すべて内部で接続
    - - - - - - - -     ← すべて内部で接続
    ===============
    a b c d e f g h     ← 横の5穴が内部で接続
    --------------- 
    a b c d e f g h

接続時の注意点:

  • 電源ライン(+/-)は縦方向に導通
  • 中央部は横の5穴が導通
  • 中央の溝で左右は絶縁されている
  • ジャンパー線で任意の穴を接続可能

5. シリアル通信とデバッグ

ArduinoとPCの間でデータをやり取りする方法です。

void setup() {
  Serial.begin(9600);  // 9600bpsで通信開始
}

void loop() {
  Serial.println("Hello");  // PCに文字列を送信
  delay(1000);
}

今回の使用:

  • 受信した赤外線信号を16進数で表示
  • プログラムの動作確認(デバッグ)
  • 現在のLED状態の確認

ボーレート(通信速度)の選択:

  • 9600bps:標準的、安定性重視
  • 115200bps:高速、大量データ転送時

赤外線リモコン通信の原理

家庭用リモコンは、赤外線LEDから約38kHzでパルス変調された光信号を送信します。この赤外線は人間の目には見えませんが、赤外線受信モジュールによって電気信号に変換できます。

主な赤外線通信プロトコル

家電メーカーやデバイスによって異なる通信規格が使われています:

プロトコル 主な使用機器 キャリア周波数 ビット長
NEC 汎用リモコン、照明機器 38kHz 32ビット
SONY ソニー製品(テレビ、AV機器) 40kHz 12/15/20ビット
RC-5/RC-6 Philips製品 36kHz 13/32ビット
Samsung サムスン製品 38kHz 32ビット

IRremoteライブラリは、これらの主要プロトコルを自動認識してデコードしてくれます。

赤外線受信モジュールの仕組み

OSRB38C9AAなどの赤外線受信モジュールは、以下の機能を1つのパッケージに統合しています:

  • フォトダイオード: 赤外線を電気信号に変換
  • AGC(自動利得制御): 受信感度を自動調整
  • バンドパスフィルタ: 38kHz帯のみを通過
  • 復調回路: キャリア周波数を除去してデジタル信号に変換

これにより、Arduino側ではデジタルピンで単純にHIGH/LOWを読み取るだけで、複雑な赤外線信号を受信できます。


必要な部品と技術仕様

信号受信用の部品リスト

部品名 仕様 数量 備考
Arduino UNO R3 / R4 Minima 1 R4推奨(処理速度向上)
赤外線受信モジュール OSRB38C9AA(38kHz) 1 TSOP38238等でも可
家庭用赤外線リモコン TV/照明/エアコン等 1 NEC/SONY規格推奨
ブレッドボード 標準サイズ 1 400穴タイプ
ジャンパー線 オス-オス 適量 3本以上

LED制御用の追加部品

部品名 仕様 数量
赤色LED Vf=1.8-2.2V 6
カーボン抵抗 220Ω(1/4W) 6
ブレッドボード 標準サイズ 1
準備した部品一式

準備した部品一式

リモコンがない場合の代替案

家のリモコンを工作に使うのが心配な方には、電子工作専用のIRリモコンモジュールがおすすめです。

電子工作用赤外線リモコン

電子工作用赤外線リモコン

今回は、家庭用のルームライトリモコン(NEC規格)を使用しました。


ステップ1:赤外線信号の受信と解析

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

Arduinoで赤外線信号を扱うには、IRremoteライブラリが必須です。

インストール方法:

  1. Arduino IDEを開く
  2. メニューから「スケッチ」→「ライブラリをインクルード」→「ライブラリを管理…」
  3. 検索窓に「IRremote」と入力
  4. shirriff/IRremote(または互換バージョン)を選択してインストール

信号受信回路の構成

赤外線受信モジュールは、以下のように接続します:

赤外線受信モジュールの配線図

赤外線受信モジュールの配線図

OSRB38C9AAのピン配置:

ピン番号 信号名 接続先
1 OUT Arduino A0ピン
2 GND Arduino GND
3 VCC Arduino 5V

重要ポイント:

  • 受信モジュールは光を受ける面を工作の外側に向けて配置
  • ケーブルが長い場合は、ノイズ対策として0.1μFのパスコンをVCC-GND間に追加推奨
  • デジタルピン(D2-D13)でもアナログピン(A0-A5)でも使用可能

信号キャプチャプログラムの実装

リモコンボタンに対応する赤外線信号を取得するプログラムです。受信した信号を**16進数(HEX)**で表示します。

#include <IRremote.h>

int RECV_PIN = A0;  // 受信ピンをA0に設定
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup(){
  Serial.begin(9600);        // シリアル通信開始(9600bps)
  irrecv.enableIRIn();       // 赤外線受信を開始
  Serial.println("IR Receiver Ready");
}

void loop() {
  if (irrecv.decode(&results)) {
    // 受信した信号を16進数で表示
    Serial.print("Received: 0x");
    Serial.println(results.value, HEX);
    
    // プロトコルの種類も表示(デバッグ用)
    Serial.print("Protocol: ");
    Serial.println(results.decode_type);
    
    irrecv.resume();  // 次の信号受信待機
  }
  delay(100);
}

プログラムの動作説明:

関数 機能
irrecv.enableIRIn() 赤外線受信を有効化(setup内で1回実行)
irrecv.decode(&results) 信号を受信したらtrue、results構造体にデータ格納
results.value 受信した信号値(unsigned long型)
results.decode_type プロトコル種類(NEC=1, SONY=2, RC5=3, etc.)
irrecv.resume() バッファクリア、次の受信準備

信号の取得と確認方法

  1. プログラムをArduinoに書き込む
  2. シリアルモニタを開く(ツール → シリアルモニタ、9600bps)
  3. 赤外線受信モジュールに向けてリモコンのボタンを押す
  4. シリアルモニタに16進数の信号値が表示される
シリアルモニタに表示された赤外線信号

シリアルモニタに表示された赤外線信号

注意事項:

  • 同じボタンを複数回押して、毎回同じ値が出るか確認
  • もし毎回違う値が出る場合は、リモコンとモジュールの距離や角度を調整
  • 長押しすると「FFFFFFFF」(リピートコード)が表示されることがある

取得した信号値の整理

ルームライトリモコンから取得した赤外線信号の一覧です:

取得した赤外線信号の対応表

取得した赤外線信号の対応表

取得した信号の例:

ボタン名 16進数コード 機能(実装予定)
点灯 0xEBB8D38E LED 3個点灯(中間)
全灯 0x1E82D3CE LED 6個点灯(最大)
消灯 0x1D41D404 LED 全消灯
明るい 0x72703D2E LED 1個ずつ追加点灯
暗い 0xEB95DB2E LED 1個ずつ消灯

ポイント:

  • これらの値はあなたのリモコン固有の値です
  • 他のリモコンでは全く異なる値になるため、必ず自分で取得してください
  • 信号は32ビット(8桁の16進数)で表現されます

ステップ2:赤外線信号によるLED制御システムの構築

信号の取得ができたら、次はその信号に応じてLEDを制御するプログラムを作成します。

LED制御回路の設計

6個のLEDを独立制御できる回路を構成します。各LEDには電流制限抵抗(220Ω)を直列に接続します。

赤外線リモコンによるLED制御回路の全体図

赤外線リモコンによるLED制御回路の全体図

回路設計のポイント:

  • LED接続ピン: デジタルピンD2〜D7(6個)
  • 電流制限抵抗: 各LEDに220Ω(計算式:(5V - 2V) / 0.015A ≈ 200Ω)
  • 受信モジュール: A0ピン(そのまま継続使用)
  • 配線の整理: ブレッドボードの電源ラインを活用してGNDを共通化

リモコンボタンと制御動作の対応表

実装する機能を整理します:

リモコンボタンの機能マッピング

リモコンボタンの機能マッピング

リモコンボタン 信号コード 実装動作 LED状態
点灯 0xEBB8D38E LED 3個点灯(中間の明るさ) D2,D3,D4=ON
全灯 0x1E82D3CE LED 6個全点灯(最大の明るさ) D2-D7=ON
消灯 0x1D41D404 LED 全消灯 D2-D7=OFF
明るい 0x72703D2E 点灯LEDを1個ずつ増やす 段階的に明るく
暗い 0xEB95DB2E 点灯LEDを1個ずつ減らす 段階的に暗く

制御ロジックの設計思想:

  • 変数jで現在の明るさレベル(1〜7)を記憶
  • 「明るい」「暗い」ボタンで段階的に調整可能
  • 上限・下限でリミット処理を実装

LED制御プログラムの完全版

赤外線信号を受信してLEDを制御する完成版プログラムです:

#include <IRremote.h>

// ピン定義
int RECV_PIN = A0;
int i, j;  // i:ループ用, j:現在の明るさレベル(1-7)

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup(){
  Serial.begin(9600);       // デバッグ用シリアル通信
  irrecv.enableIRIn();      // 赤外線受信開始
  
  // LEDピン(D2-D7)を出力モードに設定
  for (i = 2; i <= 7; i++) {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);   // 初期状態:全消灯
  }
  
  j = 1;  // 明るさレベル初期値
  Serial.println("LED Control System Ready");
}

void loop() {
  if (irrecv.decode(&results)) {
    // デバッグ:受信した信号をシリアル表示
    Serial.print("Received: 0x");
    Serial.println(results.value, HEX);
    
    irrecv.resume();  // 次の信号受信準備
    
    // switch文で信号に応じた処理を実行
    switch (results.value) {
      
      case 0xEBB8D38E:  // 【点灯】ボタン
        // D2,D3,D4をON / D5,D6,D7をOFF
        for (i = 2; i < 5; i++) digitalWrite(i, HIGH);
        for (i = 5; i < 8; i++) digitalWrite(i, LOW);
        j = 4;  // 明るさレベルを4に設定
        Serial.println("Mode: Normal (LED 0-2 ON)");
        break;
      
      case 0x1E82D3CE:  // 【全灯】ボタン
        // D2-D7を全てON
        for (i = 2; i < 8; i++) digitalWrite(i, HIGH);
        j = 7;  // 明るさレベルを最大に
        Serial.println("Mode: Full Brightness (All LEDs ON)");
        break;
      
      case 0x1D41D404:  // 【消灯】ボタン
        // D2-D7を全てOFF
        for (i = 2; i < 8; i++) digitalWrite(i, LOW);
        j = 1;  // 明るさレベルを最小に
        Serial.println("Mode: OFF (All LEDs OFF)");
        break;
      
      case 0x72703D2E:  // 【明るい】ボタン
        // 現在のレベルjのLEDを点灯し、jをインクリメント
        j++;
        if (j > 7) j = 7;  // 上限チェック
        digitalWrite(j, HIGH);
        Serial.print("Brightness UP: Level ");
        Serial.println(j - 1);
        break;
      
      case 0xEB95DB2E:  // 【暗い】ボタン
        // 現在のレベルjのLEDを消灯し、jをデクリメント
        digitalWrite(j, LOW);
        j--;
        if (j < 1) j = 1;  // 下限チェック
        Serial.print("Brightness DOWN: Level ");
        Serial.println(j - 1);
        break;
      
      default:
        // 未登録のボタンが押された場合
        Serial.println("Unknown button");
        break;
    }
    
    delay(300);  // チャタリング防止
  }
}

プログラムの重要ポイント:

  1. 状態管理変数j

    • 値の範囲:1(全消灯)〜 7(全点灯)
    • LEDピン番号(D2-D7)と対応させるため、実際のピン番号-1で管理
  2. 段階的調光の実装

    • 「明るい」:digitalWrite(j, HIGH); j++;
    • 「暗い」:digitalWrite(j, LOW); j--;
    • リミッタ処理で配列外アクセスを防止
  3. チャタリング対策

    • delay(300)で連続押下を防止
    • より高度な実装ではmillis()を使った非ブロッキング処理も可能
  4. デバッグ機能

    • Serial出力で現在の状態を確認可能
    • 本番環境ではSerial関連のコードを削除して軽量化可能

実行結果と動作確認

実際に動作させた様子を動画で確認できます:

動作のポイント:

  • リモコンボタンを押すと、瞬時にLEDが応答
  • 「明るい」「暗い」ボタンで段階的に調光可能
  • 通信距離は約3〜5m(環境により変動)
  • 斜めからでも約45度の角度まで受信可能

応用例とカスタマイズ

実用的な応用アイデア

このシステムは、基礎としてさまざまなプロジェクトに発展できます:

1. 学習リモコンの作成

  • 受信した信号を不揮発性メモリ(EEPROM)に保存
  • 赤外線LED送信回路を追加して信号を再送信
  • 複数のリモコンを1つに統合

2. スマートホーム連携

  • ESP32/ESP8266でWi-Fi接続を追加
  • MQTTやHTTPでスマホアプリと連携
  • Google HomeやAlexaからの音声制御

3. 家電の自動化

  • 特定の時刻に信号送信(タイマー制御)
  • 温度センサーと連携して自動でエアコン操作
  • 人感センサーで照明の自動ON/OFF

4. データロギング

  • リモコン操作履歴をSDカードに記録
  • 使用頻度分析による省エネ提案
  • 高齢者見守りシステム(操作がない場合にアラート)

プログラムのカスタマイズ方法

未使用ボタンへの機能追加:

case 0x12345678:  // あなたのリモコンの信号コードに変更
  // ここに新しい機能を実装
  // 例:点滅パターン、ランダムカラー、etc.
  break;

PWM制御による無段階調光:

// LEDピンをPWM対応ピン(D3,D5,D6,D9,D10,D11)に接続
case 0x72703D2E:  // 明るい
  brightness += 25;
  if (brightness > 255) brightness = 255;
  analogWrite(LED_PIN, brightness);
  break;

複数デバイスの制御:

// サーボモーター、リレー、LCD表示などを追加
case 0x1E82D3CE:
  myServo.write(90);  // サーボを90度に
  digitalWrite(RELAY_PIN, HIGH);  // リレーON
  lcd.print("Device ON");
  break;

トラブルシューティング

よくある問題と解決方法

症状 原因 解決方法
信号が受信できない 配線ミス、電源不足 VCC/GND/OUTの接続を再確認、USBケーブルを交換
毎回違う値が表示される リモコンの距離・角度 10-30cm、正面から信号送信
連続で同じ動作が繰り返される リピートコード受信 if(results.value != 0xFFFFFFFF)で除外
LEDが点灯しない ピン設定ミス、抵抗値 pinMode設定確認、抵抗値を100Ωに変更して試行
動作が遅い delay()が長すぎる delay値を50-100msに短縮、または非ブロッキング処理に変更

リピートコード対策

長押しすると「0xFFFFFFFF」が連続で送信されます。これを無視する処理:

if (irrecv.decode(&results)) {
  if (results.value != 0xFFFFFFFF) {  // リピートコード除外
    // 通常の処理
  }
  irrecv.resume();
}

まとめ:赤外線リモコン受信システムの可能性

今回構築したシステムのポイントをまとめます:

📡 習得した技術

  • IRremoteライブラリの使用方法 - 主要プロトコルの自動認識
  • 赤外線信号のデコードと16進数表示 - 信号解析の基礎
  • switch文を使った信号マッピング - 実用的な制御ロジック
  • 状態管理変数による段階制御 - LEDの無段階調光の基礎

🚀 次のステップ

  • 赤外線送信 - IRremote.cppを使って信号を送信する側も実装
  • EEPROMへの保存 - 学習リモコンの作成
  • センサー連携 - 温度/湿度/人感センサーとの組み合わせ
  • 無線化 - ESP32/Wi-Fi/Bluetoothでスマホ連携

🔧 実用化に向けて

  • ケースの設計 - 3Dプリンタでオリジナル筐体を作成
  • 電源の最適化 - バッテリー駆動やUSB給電の選択
  • 複数デバイス制御 - リレーモジュールで家電をON/OFF

赤外線リモコン受信は、IoT電子工作の第一歩として最適なテーマです。ここで学んだ技術を基に、あなただけのスマートホームデバイスを作ってみてください!