PR

ラズパイPico Wで赤外線リモコンを自作|受信・送信回路と38kHz PWM制御【自作スマートリモコン 第4回】

ハードウェア制御 / 電子工作

自作スマートリモコン 第4回

スポンサーリンク

はじめに:ラズパイPico Wでエアコンの赤外線リモコンを自作する

こんにちは、ニンジンです🥕

この記事では、Raspberry Pi Pico Wとおよそ数百円の電子部品で、エアコンの赤外線リモコンを自作する手順を解説します。受光モジュール(PL-IRM1838B)とトランジスタ(C1815)を使った受信・送信回路の結線図、リモコン信号を読み取るPythonコード(Get_IR.py)、38kHzのPWMキャリアで信号を送り出すコード(IR_Transmission.py)、そして「赤外線が届かない」ときの対策までを、実機の写真つきでまとめます。

本記事は「愛犬を守る!格安IoT温湿度見守りLINE Botの作り方」の第4回です。これまでの連載は以下からどうぞ。

この記事で分かること

  • 自作スマートリモコンに必要な電子部品(赤外線LED・受光モジュール・トランジスタ・抵抗)と入手先
  • PL-IRM1838BとC1815を使った赤外線の受信・送信回路の結線図と配線手順
  • エアコンのリモコン信号を読み取るMicroPythonコード(Get_IR.py)
  • 38kHzのPWMキャリアで赤外線を送信するコード(IR_Transmission.py)
  • 赤外線が届かないときの3つの原因と対策(配線・LEDの指向性・電源容量)
スポンサーリンク

LINE通知の限界:外出先からの「エアコン遠隔操作」がどうしても必要だった理由

前回までの作業で、「室温が28度を超えたらLINEに通知が来る」という監視システムが完成しました。しかし運用してみて、ひとつの大きな問題に気づきました。

「危険な温度の通知が来ても、結局その場に行かないとエアコンをONにできない!」

外出先で通知を受け取ったとき、遠隔でサッとエアコンをつけられたら最高ですよね。というわけで今回は、完成したシステムに「エアコンの赤外線リモコン機能」を追加していきます。

スポンサーリンク

今回やりたいこと:スマホのLINEから赤外線を飛ばしてエアコンを操作する

Pico Wでエアコンのリモコン信号を受信し赤外線で再送信する全体構成図

▲ 自作スマートリモコンの全体構成

スマホのLINE →(次回実装)→ Pico W → 赤外線LED → エアコン、という流れです。今回はPico Wと赤外線パーツの部分を作ります。

今回具現化したい仕様は以下の3点です。

  • エアコンのリモコン信号を、学習リモコンのようにPico Wで読み取る
  • 読み取った信号を、Pico Wから赤外線(IR)として発信する
  • 発信のトリガーは、スマホのLINEから「冷房ON」とメッセージを送ること(※LINE連携は次回の第5回で実装します)

まずは物理的に「赤外線を読み取って、飛ばす」というハードウェアのハッキングから進めていきましょう。


スポンサーリンク

自作スマートリモコンに必要な電子部品リスト(赤外線LED・受光モジュール等)

今回は電子工作感がグッと増します。以下の部品を準備してください。部品はすべて秋月電子通商で購入できます。

メイン部品

赤外線受信モジュールPL-IRM1838Bの外観

▲ 赤外線受信モジュール PL-IRM1838B

赤外線受信モジュール PL-IRM1838B
赤外線受信モジュール 37.9kHz(PL-IRM1838B)
在庫切れの場合は同じ38kHz帯の「SPS-440-1(通販コード: 100614)」も定番として使えます。

5mm砲弾型の赤外線LEDの外観

▲ 赤外線LED OSI5LA5A33A-B

赤外線LED OSI5LA5A33A-B
5mm砲弾型赤外線LED 940nm 100mW/sr 30°(OSI5LA5A33A-B)

トランジスタ2SC1815の外観

▲ トランジスタ 2SC1815

トランジスタ 2SC1815
トランジスター 2SC1815L-GR-T92
赤外線LEDを5Vで強くドライブするためのスイッチング用です。

カーボン抵抗4.7kオームの外観

▲ 抵抗① 4.7kΩ(ベース保護用)

抵抗① 4.7kΩ(ベース保護用)
カーボン抵抗(炭素皮膜抵抗) 1/4W 4.7kΩ
Pico WのGPIOピンを守る保護抵抗です。

カーボン抵抗100オームの外観

▲ 抵抗② 100Ω(赤外線LED用)

抵抗② 100Ω(赤外線LED用)
カーボン抵抗(炭素皮膜抵抗) 1/4W 100Ω
赤外線LEDに流す電流を制限します。

あると便利なグッズ

電子工作用ブレッドボードの外観

▲ ブレッドボード

ブレッドボード
ブレッドボード
配線が圧倒的に楽になります。

Raspberry Pi Pico W用のブレイクアウトボードの外観

▲ Pico W用ブレイクアウトボード

Pico W用ブレイクアウトボード
Pico W用ブレイクアウトボード
ピンの番号が一目でわかる優れものです。


スポンサーリンク

【結線図あり】ラズパイPico Wと赤外線パーツの配線・組み立て手順

Raspberry Pi Pico Wと赤外線受信モジュール・赤外線LED・C1815・抵抗の結線図
▲ Pico Wと赤外線パーツの結線図(GP16=受信 / GP17=送信)

部品が揃ったら、さっそく結線していきましょう。各パーツの足の向き(極性)には注意が必要です。

赤外線受信モジュール(PL-IRM1838B)のピン配置

正面(丸いレンズの突起がある面)を自分に向け、ピンを下にした状態のとき、左から以下の配置になります。

PL-IRM1838Bのピン配置図。左からOUT、GND、VCC

▲ PL-IRM1838Bのピン配置

  1. OUT(信号出力)
  2. GND(グランド)
  3. VCC(電源)

トランジスタ(C1815)のピン配置

平らな面(「C1815」と印字されている面)を自分に向け、ピンを下にしたとき、左から以下の配置になります。

トランジスタC1815のピン配置図。左からエミッタ、コレクタ、ベース

▲ C1815のピン配置

  1. エミッタ (E)
  2. コレクタ (C)
  3. ベース (B)

ブレッドボードへの接続手順

ブレッドボード上に組んだ赤外線受信・送信回路の実物写真

▲ ブレッドボードに組んだ赤外線リモコン回路

  1. 受信モジュールのOUTピンを、Pico WのGP16(21番ピン)に接続
  2. 受信モジュールのGNDピンを、Pico WのGND(38番ピンなど)に接続
  3. 受信モジュールのVCCピンを、Pico Wの3V3(OUT)(36番ピン)に接続
  4. Pico WのGP17(22番ピン)から4.7kΩの抵抗を経由して、トランジスタのベースに接続(Picoのピンを守る保護抵抗)
  5. トランジスタのエミッタを、Pico WのGNDに接続
  6. Pico WのVBUS(40番ピン・5V出力)から100Ωの抵抗を経由して、赤外線LEDの長い足(アノード)に接続
  7. 赤外線LEDの短い足(カソード)から、トランジスタのコレクタに接続
💡 ワンポイント:なぜ3.3VではなくVBUS(5V)を使うの?
遠くまで届く強い赤外線を出すには、より高い電圧と電流が必要です。そのため3.3Vピンではなく、USBから直接きている5V(VBUS)から赤外線LEDの電源を取っています。

スポンサーリンク

Pythonで実践!エアコンの赤外線(IR)信号の読み取りと発信テスト

回路が組めたら、実際にエアコンの信号を読み取ってみましょう。ThonnyでMicroPythonを使います。

リモコン信号の取得テスト(Get_IR.py)

Thonnyを開き、以下の受信用プログラムを実行します。

#Get_IR.py

import machine
import time

# 受光センサを接続したピンを GPIO 16 に変更
IR_PIN = 16
ir_sensor = machine.Pin(IR_PIN, machine.Pin.IN, machine.Pin.PULL_UP)

MAX_BUFF = 500  # 記録するパルスの最大数

print("=== 赤外線信号レコーダー準備完了 (GPIO16) ===")
print("リモコンをセンサに向けてボタンを押してください...")

while True:
    # 信号がLO(0)になるのを待つ
    if ir_sensor.value() == 0:
        t_start = time.ticks_us()
        times = []
        last_val = 0
        
        while True:
            t_now = time.ticks_us()
            val = ir_sensor.value()
            
            if val != last_val:
                elapsed = time.ticks_diff(t_now, t_start)
                times.append(elapsed)
                t_start = t_now
                last_val = val
                
            # 信号が約200ms途切れたら終了とみなす
            if val == 1 and time.ticks_diff(time.ticks_us(), t_start) > 200000:
                break
                
            if len(times) >= MAX_BUFF:
                break
        
        print("\n--- 信号を受信しました! ---")
        print(f"データ長 (パルス数): {len(times)}")
        print("以下データをコピーして保存してください:")
        print(times)
        print("----------------------------")
        
        time.sleep(1)
        print("\n次の信号を待っています...")
Thonnyのターミナルに赤外線信号の数字リストが表示された画面

▲ 信号の取得に成功(数字のリストが出力される)

実行するとターミナルに「リモコンをセンサに向けてボタンを押してください…」と表示されます。ボタンを押して、このように数百個の数字が並べば成功です。

お手持ちのエアコンのリモコンを受信モジュールに2cm以内まで近づけ、「冷房ON」のボタンを押してください。数字のリストがズラッと表示されれば信号の取得成功です。このリストは後で使うのでメモ帳などにコピーしておきます。

IR発信テスト(IR_Transmission.py)

次に、読み取った信号をPico Wから発信します。以下のプログラムの COOL_ON_DATA の部分に、先ほどコピーした数字のリストを貼り付けてから実行してください。

# IR_Transmission.py

import machine
import time

# 送信ピン(GPIO 17)の設定
TX_PIN = 17

# 先ほど取得したエアコン信号データ(冷房ON)
COOL_ON_DATA = [
    ####################ここを書き換えてください。
    4307, 4535, 480, 1667, 523, 540, 483, 1619, 528, 1659, 516, 581, 469, 569, 529, 1607, 
    521, 610, 474, 586, 474, 1680, 518, 578, 488, 578, 473, 1606, 523, 1676, 473, 575, 
    537, 1616, 519, 1602, 525, 1685, 467, 1616, 525, 568, 568, 565, 528, 510, 522, 576, 
    472, 575, 522, 572, 478, 582, 523, 570, 540, 1613, 466, 1661, 482, 1682, 475, 1618, 
    523, 1647, 521, 564, 530, 578, 478, 581, 480, 575, 584, 504, 525, 575, 472, 572, 
    527, 580, 531, 1568, 527, 1624, 527, 1664, 526, 1614, 474, 1679, 477, 1665, 520, 
    1616, 477, 1681, 473, 8031, 4350, 4448, 532, 1667, 478, 576, 528, 1622, 484, 1662, 
    486, 574, 521, 565, 530, 1590, 574, 510, 583, 511, 528, 1605, 524, 579, 575, 505, 
    526, 1600, 525, 1619, 573, 506, 578, 1544, 622, 1623, 527, 1602, 521, 1601, 529, 
    506, 581, 580, 516, 568, 485, 582, 478, 571, 538, 582, 471, 580, 528, 567, 474, 
    1666, 473, 1670, 480, 1661, 479, 1679, 474, 1681, 475, 576, 520, 564, 527, 568, 
    473, 569, 518, 570, 523, 563, 520, 571, 479, 586, 479, 1668, 523, 1612, 531, 1590, 
    533, 1677, 482, 1615, 526, 1605, 522, 1674, 474, 1661, 527, 8558, 4399, 4457, 519, 
    1672, 478, 576, 524, 1603, 529, 1629, 530, 513, 527, 585, 521, 1615, 538, 498, 
    578, 574, 472, 1599, 576, 578, 478, 581, 481, 1600, 570, 1599, 534, 579, 523, 1545, 
    573, 1607, 538, 574, 519, 1596, 583, 1608, 523, 1625, 521, 1612, 535, 1543, 575, 
    1676, 477, 504, 577, 1653, 521, 573, 487, 553, 520, 560, 531, 568, 477, 578, 527, 
    504, 578, 1604, 531, 1612, 527, 575, 531, 511, 534, 561, 521, 576, 480, 573, 508, 
    581, 530, 568, 478, 581, 531, 1604, 530, 1618, 529, 1607, 527, 1600, 570, 1610, 
    531, 1605, 519, 8020, 4321, 4526, 479, 1666, 479, 563, 529, 1618, 527, 1621, 526, 
    584, 482, 577, 487, 1676, 468, 585, 519, 578, 524, 1608, 517, 570, 479, 571, 522, 
    1627, 521, 1657, 478, 584, 521, 1613, 532, 1617, 520, 567, 530, 1598, 514, 1666, 
    482, 1668, 475, 1667, 475, 1665, 480, 1664, 540, 507, 529, 1666, 478, 573, 528, 
    571, 477, 579, 521, 568, 521, 567, 473, 580, 523, 1596, 523, 1689, 478, 586, 479, 
    568, 527, 561, 528, 563, 476, 576, 530, 568, 522, 572, 482, 583, 474, 1621, 527, 
    1670, 480, 1674, 477, 1667, 476, 1618, 528, 1664, 481
]

def send_ir(data):
    # 38kHzのPWMキャリア信号を設定(Duty比を約33%に設定)
    pwm = machine.PWM(machine.Pin(TX_PIN))
    pwm.freq(38000)
    
    # 状態(ON=38kHzパルス出力、OFF=完全停止)を切り替える関数
    def pwm_on():
        pwm.duty_u16(21845) # 65535 の約1/3
    def pwm_off():
        pwm.duty_u16(0)

    # データの長さに合わせてON/OFFを繰り返す
    is_on = True
    for us in data:
        if is_on:
            pwm_on()
        else:
            pwm_off()
        time.sleep_us(us)
        is_on = not is_on
        
    # 送信終了後は必ずOFFにする
    pwm_off()
    pwm.deinit()

print("赤外線信号を送信します...")
send_ir(COOL_ON_DATA)
print("送信完了しました!")
Thonnyのターミナルに「送信完了しました!」と表示された画面

▲ 「送信完了しました!」と出て、エアコンが冷房ONになれば成功

「ピッ!」という音とともにエアコンが冷房ONになれば大成功です。反応しない場合は次のトラブルシューティングへ。

トラブルシューティング(赤外線が届かない原因と対策)

「赤外線が出ているはずなのにエアコンが反応しない」ときは、以下の3点を確認してください。

  • ① 配線の再確認:抵抗の値(4.7kΩと100Ω)が逆になっていないか、トランジスタの向きが合っているかをもう一度確認します。
  • ② LEDの指向性(物理の要因):赤外線LEDは指向角が15〜30度と狭く、スポットライトのように真っ直ぐしか飛びません。LEDの頭をエアコンの受光部(黒い窓のような場所)へ正確に向けてください。
  • ③ 5V(VBUS)電源の容量不足(回路の要因):PCのUSBポートは供給電流が制限され、LEDの最大出力が出ないことがあります。実運用では2A以上出せるスマホ用の急速充電器(ACアダプタ)から給電してください。当ラボの環境では5mまで届くことを確認しています。

スポンサーリンク

【ちょっと脱線】なぜリモコンは「38kHz」じゃないとダメなの?

「エアコンを動かすには、赤外線を38kHzで振動させないと認識しない」という話を聞いたことはありませんか。少しだけ、その裏側を説明します。

私たちの部屋には、蛍光灯や太陽光など目に見えない赤外線がそこら中に飛び交っています。もし赤外線LEDをただ「ピカーッ」と光らせるだけだと、エアコンは「これはリモコンの命令? それともただの部屋の明かり?」と区別がつきません。

そこでリモコンの光を「1秒間に3万8000回(38kHz)で点滅する特殊な光」にすることで、エアコンに「これは間違いなくリモコンからの信号だ」と認識させています。今回の小さな回路では、3つのパーツが連携してこれを実現しています。

  • ① Pico WのPWM機能(頭脳と心臓):コード中の pwm.freq(38000) という1行が「1秒間に38,000回の波を作れ」という命令です。Pico Wは内部の高速タイマーで、Pythonの処理速度と無関係に正確な38kHzの波を生成します。
  • ② トランジスタ C1815(筋肉):Pico Wから出た38kHzの波はそのままでは電流が弱すぎます。C1815がこの弱い波を受け取り、強力な5V電源を高速でスイッチングして、強い電流の波に増幅します。
  • ③ 赤外線LED(発声器官):増幅された強い38kHzの電流を受け取り、激しく点滅する「光の波」に変えてエアコンへ届けます。

Pico Wが波のタイミングを作り、トランジスタがパワーを増幅し、LEDが光として放つ。このチームワークで、小さな部品の集まりが大きなエアコンを操作できるわけです。


スポンサーリンク

次回予告:GAS+LINEで遠隔操作できる完全自作スマートリモコンへ

今回は、ハードウェアを組み上げてエアコンの信号を読み取り、Pico Wから直接赤外線を飛ばすところまで完成しました。ただ、このままでは「PCからプログラムを実行しないと動かない」状態です。

次回(第5回)は、いよいよこの回路とLINEを連携させます。Google Apps Script(GAS)でネットワークの壁を越え、スマホから遠隔操作できる「完全自作スマートリモコン」を完成させます。


スポンサーリンク

よくある質問(信号が取れない・赤外線が届かない)

QGet_IR.pyを実行してもリモコンの信号(数字のリスト)が表示されません

A受光モジュールのピン配置を確認してください。正面から見て左からOUT・GND・VCCで、OUTをGP16、VCCを3V3(OUT)、GNDをGNDに接続します。コードのIR_PINが16になっているか、machine.Pin.PULL_UPが指定されているかも確認します。リモコンはレンズに2cm以内まで近づけてください。蛍光灯の下だとノイズを拾いやすいので、照明を落として試すと安定します。

QIR_Transmission.pyは実行できるのに、赤外線がエアコンに届きません

A3点を確認します。①抵抗の取り違え:ベース側が4.7kΩ、赤外線LED側が100Ωです。②LEDの向き:指向角が15〜30度と狭いので、LEDの頭をエアコンの受光部へまっすぐ向けます。③電源:VBUSをPCのUSBから取ると電流不足になりがちです。2A以上のACアダプタから給電すると飛距離が伸びます(当環境で5m)。

QGP16とGP17は何に使っていますか?別のピンに変更できますか?

AGP16が受信(Get_IR.pyのIR_PIN)、GP17が送信(IR_Transmission.pyのTX_PIN)です。空いているGPIOなら変更できます。送信側はPWMが使えるピンを選んでください(Pico Wはほぼ全ピンがPWM対応)。コード先頭の定数(IR_PIN / TX_PIN)を書き換えるだけです。

Qエアコン以外(テレビ・照明)のリモコンでも使えますか?

A使えます。Get_IR.pyで対象リモコンのボタン信号を読み取り、その数字リストをIR_Transmission.pyのCOOL_ON_DATAに貼り替えるだけです。ボタンごとに配列を用意すれば複数操作もできます。メーカーによっては1回の送信で反応しにくいことがあり、その場合は同じ信号を2回続けて送ると安定します。

Q受信モジュールが「PL-IRM1838B(37.9kHz)」ですが、38kHzのリモコンを受信できますか?

Aできます。赤外線リモコン用の受光モジュールは中心周波数の前後数kHzに受信帯域があり、37.9kHzのモジュールで一般的な38kHz帯の家電リモコンを問題なく受信できます。在庫切れのときは同じ38kHz帯のSPS-440-1でも代用できます。



ニンジン🥕アイコン

Follow me on X

本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕

@ninjin_py_vba をフォロー

この記事が役に立ったら、シェアしてもらえると嬉しいです🥕

Xでポスト はてブ LINE Pocket

PROJECT LOG — SERIES INDEX
スポンサーリンク

シリーズ記事一覧

電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。


GPSロガーのCSVを地図に表示する方法|Pico 2 WでGT-502MGG-NとATGM336Hを車に積んで走行・トンネル比較【Python・folium】
GPSロガーで記録したCSVを、Pythonのfoliumと地理院タイルで地図に表示する方法。GT-502MGG-NとATGM336Hを車に積んで4回走り、再起動の原因やトンネルでの違いも比べました。
今週の注目ガジェット〜10/19週〜|電子工作・自作向け新製品まとめ(Romu/W1700K SDR ほか)
大手が拾わないニッチな新製品を毎週チェック。今週はe-Paper開発キット、超小型USBボード、自作SDRなど5本立て。
GT-502MGG-NとATGM336Hの使い方|Raspberry Pi Pico 2 WとMicroPythonでGPSを受信して2台を比較
GT-502MGG-NとATGM336Hの使い方を、Pico 2 W×MicroPythonで解説。北斗で衛星数が多いATGM336H、信号が強いGT-502MGG-N。単精度floatで緯度経度が約1.4m刻みになる落とし穴も紹介します。
今週の注目ガジェット〜10/12週〜|電子工作・自作向け新製品まとめ(Q8botOne/Sipeed SLogic32U3 ほか)
大手が拾わないニッチな新製品を毎週チェック。今週は四足歩行ロボット、ロジックアナライザー、広告ブロッカーなど5本立て。
MOSFETはPicoの3.3Vで足りる?DCソレノイド駆動でゲート電圧不足を実測【Pico 2 W】
Pico 2 WとMOSFET(IRLU3410)で12VのDCソレノイドを駆動。ゲート3.3Vでは発振し、オン抵抗も約2.4倍に。レベル変換で5V駆動にした比較と、電流が8割止まりだった本当の原因を実測で紹介します。
まとめハブ
ハードウェア制御 / 電子工作
スポンサーリンク

コメント