Python
Raspberry Pi Pico
public
Raspberry Pi Pico で赤外線リモコンをつくる
赤外線信号を受信する
事前にCircuitPython を使った Raspberry Pi Pico の開発 を済ませておく。
CircuitPython の赤外線リモコンライブラリをインストールする。
Introduction — Adafruit IRREMOTE Library 1.0 documentation
Releases · adafruit/Adafruit_CircuitPython_Bundle · GitHub
libディレクトリにadafruit_irremote.mpyをコピーする。
回路を組む。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 # Circuit Playground Express Demo Code
# Adjust the pulseio 'board.PIN' if using something else
import pulseio
import board
import adafruit_irremote
pulsein = pulseio . PulseIn ( board . GP0 , maxlen = 500 , idle_state = True )
decoder = adafruit_irremote . GenericDecode ()
while True :
print ( "Wait" )
pulses = decoder . read_pulses ( pulsein )
print ( "Heard" , len ( pulses ), "Pulses:" , pulses )
try :
code = decoder . decode_bits ( pulses )
print ( "Decoded:" , code )
except adafruit_irremote . IRNECRepeatException : # unusual short code!
print ( "NEC repeat!" )
except adafruit_irremote . IRDecodeException as e : # failed to decode
print ( "Failed to decode: " , e . args )
print ( "----------------------------" )
リモコンの電源ボタンを押しながらシリアルポートを確認すると、パルス幅の情報が出力される。
赤外線信号を解読する
赤外線信号の仕組みは以下が参考になる。
必要な情報は以下となる。
赤外線信号は 点灯している時間[us] → 消灯している時間[us] → … を示している。
先頭 2 つはリーダー信号の点灯時間、消灯時間を示す。
赤外線信号のフォーマットはいくつか存在するので特定する必要がある。
エアコンのリモコンの電源 ON 操作を 3 回ほど行ってみて、信号を確認してみる。
最頻値より\(440us\) あたりが基準となるパルス幅と思われる。よって\(440us \approx 1T\) とする。
リーダー ON はおよそ\(8T\) 、リーダー OFF はおよそ\(4T\) であるからフォーマットは家製協(AEHA)フォーマットと思われる。
補足: 赤外線リモコン受信モジュール OSRB38C9AA の出力波形
赤外線受信モジュールの出力をオシロスコープで観測し、赤外線受信モジュールにエアコンの赤外線信号を受信させてみる。
オシロスコープでサンプリングしたときのサンプリングレートが低いせいで波形がなまっているが、実際は矩形波である。
このモジュールは Active Low である。(何も受信していないとき、出力電圧は High ということ)
電圧が 0 のとき ON なので、ON の時間は約 3.5ms、直後の OFF の時間は約 1.7ms であることが分かる。
\(440us \approx 1T\) であるから、3.5ms は約 8T、1.7ms は約 4T であり、これらのパルスはリーダー信号であることがわかる。
赤外線信号を送信する
上記のコードのcode = decoder.decode_bits(pulses)が受信した信号である。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import time
import adafruit_irremote
import board
import pulseio
pulsein = pulseio . PulseIn ( board . GP0 , maxlen = 500 , idle_state = True )
decoder = adafruit_irremote . GenericDecode ()
# データを送信するときは38kHzに変調したパルスを送信する。これはライブラリがやってくれる。
# header: ヘッダーを指定する。AEHAフォーマットでは[8T, 4T]
# one: 1の信号を指定する。AEHAフォーマットでは[T, 3T]
# zero: 0の信号を指定する。AEHAフォーマットでは[T, T]
# ただしAEHAフォーマットでは1T=440us
pulseout = pulseio . PulseOut ( board . GP1 )
T = 440
transmitter = adafruit_irremote . GenericTransmit ( header = [ 8 * T , 4 * T ], one = [ T , 3 * T ], zero = [ T , T ], trail = T )
data = ( 196 , 211 , 100 , 128 , 0 , 4 , 24 , 80 , 108 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 179 )
while True :
transmitter . transmit ( pulseout , data )
time . sleep ( 10 )
エアコンは AEHA フォーマットで
照明は NEC フォーマットのため、以下で動く。
T = 562
transmitter = adafruit_irremote . GenericTransmit ( header = [ 16 * T , 8 * T ], one = [ T , 3 * T ], zero = [ T , T ], trail = T )
TOGGLE_LIGHT = (65, 182, 213, 42)
NIGHT_LIGHT = (65, 182, 61, 194)
BRIGHTEST_LIGHT = (65, 182, 101, 154)
TURN_ON_COOLING = (196, 211, 100, 128, 0, 4, 24, 80, 108, 2, 0, 0, 0, 0, 0, 0, 0, 179)
参考リンク
GenericTransmit incorrect param types · Issue #65 · adafruit/Adafruit_CircuitPython_IRRemote · GitHub
Adafruit_CircuitPython_IRRemote/examples/irremote_transmit.py at main · adafruit/Adafruit_CircuitPython_IRRemote · GitHub
照明制御
re0208.py 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import adafruit_irremote
import board
import pulseio
class RE0208 :
TOGGLE_LIGHT = ( 65 , 182 , 213 , 42 )
NIGHT_LIGHT = ( 65 , 182 , 61 , 194 )
BRIGHTEST_LIGHT = ( 65 , 182 , 101 , 154 )
def __init__ ( self , pin : board . Pin ) -> None :
T = 562
self . __pulseout = pulseio . PulseOut ( pin )
self . __transmitter = adafruit_irremote . GenericTransmit ( header = [ 16 * T , 8 * T ], one = [ T , 3 * T ], zero = [ T , T ], trail = T )
def turn_off ( self ) -> None :
self . __transmitter . transmit ( self . __pulseout , RE0208 . NIGHT_LIGHT )
self . __transmitter . transmit ( self . __pulseout , RE0208 . TOGGLE_LIGHT )
def turn_on ( self ) -> None :
self . __transmitter . transmit ( self . __pulseout , RE0208 . BRIGHTEST_LIGHT )
def set_night_light ( self ) -> None :
self . __transmitter . transmit ( self . __pulseout , RE0208 . NIGHT_LIGHT )
赤外線信号送信を自身でやる
CircuitPython では 38kHz 変調が難しい。
赤外線リモコンの作り方
赤外線 LED を使った赤外線信号は 38kHz に変調されている。
赤外線信号を送信したい場合、ハードウェアは 38kHz で点滅させる必要がある。秒に直すと 26us である。
\[
周期 = \frac{1}{38 \mathrm{kHz} \times 1000} = 2.63 \times 10^{-5} \mathrm{s} = 26 \mathrm{us}
\]
26us のうちに点滅させないといけないらしいので、13us 単位で制御させないといけない。
Raspberry Pi Pico の CircuitPython では 1ms 間隔の制御も怪しい。