あっきぃ日誌

鉄道ブログのような技術系ブログのようななにか

Raspberry Pi Picoで赤外線学習リモコン

Raspberry Pi Pico用の赤外線学習リモコンライブラリで遊んでみる話です。

Raspberry Piではlircとかir-ctlを使う感じですが、まあ、動かすまでがわりと大変という印象があります。あと、Picoで動くなら待機の消費電力を削れるはずなので、いつか試してみたいなあと思って放置していました。で、きのう改めて探してみたら、いい感じに動かせるライブラリを見つけて可能性を感じたので、それを紹介します。

RemotePyという、日本の方が作られているライブラリ。Pico(WもOKでした)とMicroPythonで動くように作られていて、使い方もシンプルでした。

qiita.com

環境

uHAT Porter Picoに載っかったPico Wに、Raspbeery Pi向けの赤外線送受信モジュールを搭載したものを使いました。HATが浮いているように見えますが、写真で見やすくするためだけにBooster Headerを噛ましてあるせいです。HATはAVANTIのInfrared pHAT。もらい物ですが非常に重宝しています。


受信

デモから抜粋した、ひたすら受信するだけのコード。uHAT Porter Picoのピン読み替えが入ってますが、普通のPicoならimportを削り、Pinのときに数字を入れればOKです。

from machine import Pin
from UpyIrRx import UpyIrRx
import uhat_porter_pico_type_p as Pin_bcm

rx_pin = Pin(Pin_bcm.BCM18, Pin.IN)
rx = UpyIrRx(rx_pin)

while True:
    print(".\n")
    rx.record(3000)
    if rx.get_mode() == UpyIrRx.MODE_DONE_OK:
        signal_list = rx.get_calibrate_list()
        print(signal_list)

実行結果。ドットが出ている範囲内でリモコンの信号を読ませると、配列になった信号データが出力されます。今Raspberry Piで使用しているir-ctlのデータと見比べると、数値の並びが似ているので、少し加工すればir-ctlにも投入できそうです。

.

.

[2040, 1020, 5610, 1020, 1530, 510, 1530, 510, 510, 510, (略)]
.

.

[2028, 1014, 5577, 1014, 1521, 507, 1521, 507, 507, 507, (略)]
.

.

送信

これもデモから抜粋しつつ、WebサーバーのAPIにしてみました。/にアクセスするとAPI呼び出しボタンだけのページが表示され、/powerで制御ができる仕組みです。

from machine import Pin
from UpyIrTx import UpyIrTx
import uhat_porter_pico_type_p as Pin_bcm
import utime
import socket
import network

ssid = "SSID"
passwd = "PASSPHRASE"

html = """<!DOCTYPE html><html lang="ja"><head><meta charset="utf-8"><title>Pico W 部屋の照明API</title></head>
<body><h1>Pico W 部屋の照明API</h1><button style="font-size:20pt;" onClick="fetch('/power');return false;">電気</button></body></html>
"""

light_power = [2032, 1016, 5588, 1016, 1524, 508, 1524, (略)]
tx_pin = Pin(Pin_bcm.BCM17, Pin.OUT)
tx = UpyIrTx(0, tx_pin)    # 0ch

def do_connect():
    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect(ssid, passwd)
        while not sta_if.isconnected():
            print(".")
            utime.sleep(1)
            pass
    print('network config:', sta_if.ifconfig())

do_connect()
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(1)

while True:
    cl, addr = s.accept()
    req = str(cl.recv(1024), "utf-8").split("\r\n")
    for l in req:
        if "GET" in l:
            path = l.split(" ")[1]
            break
    code = "200 OK"
    ct = "text/html"
    if path == "/":
        response = html
    elif path == "/power":
        tx.send(light_power)
        response = "ok"
    else:
        code = "404 Not Found"
        response = "Not Found"

    cl.send('HTTP/1.0 %s\r\nContent-type: %s\r\n\r\n' % (code,ct))
    cl.send(response)
    cl.close()

動作のようす。きちんと照明がオンオフできています。

youtu.be

他のリモコン

楽しくなって、手元にあるリモコンを引っ張りだしてみましたが、Blu-rayプレーヤーのリモコンも、エアコンのリモコンも、どれもバッチリ送受信できました。強いぞ、こいつ……!!!


ええなこれ

これは強力なライブラリを発見しましたね……!自宅でメイン機として常設しているラズピッピの一番肝になっている機能ですが、これをPicoに置き換えたらラズピッピ自体置き換えられそうな予感。まあ、他に動いているものが多いので、当面置き換えるプランはないですが。

これを常設化しようとしたときに、Pico Wで無線として動かすか、ネットワークの安定を求めてWIZNet W5500とかの有線LANモジュールでやるかは、人によって要検討かなと思います。私なら有線LANを使うかも。ちょうどこないだW5500+Tiny2040のやつを箱に詰めたばかりなので、それを使うとかはちょっと考えました。

akkiesoft.hatenablog.jp