ダイキンエアコンのリモコン信号を解析してみた。
赤外線リモコン信号受信用ハードウェア
前にしたようにラズパイを使ってもよいが, 今回はこれ「Seeeduino XIAO」を使ってみることにする。
- スイッチサイエンス https://www.switch-science.com/catalog/6335/
- 秋月電子通商 (通販コード M-15178) http://akizukidenshi.com/
等々。
財布に優しいのでこの用途にはこれがベストでなかろうかと。
ピンをはんだ付けしてブレッドボードへ。
CircuitPython on Seeeduino XIAO
今回はCircuitPythonを使うことにする。
seeedstudioのWiki のページに従って Seeeduino XIAO に CircuitPython を入れる。
main.py
これをGitHubからダウンロードして, USBを接続したときに出てくる"CIRCUITPY"というドライブのルートフォルダに保存する。
# https://ak1211.com/7586 (main.py) | |
# Copyright 2020 Akihiro Yamamoto | |
# Licensed under the Apache License, Version 2.0 | |
import time | |
import board | |
import pulseio | |
from digitalio import DigitalInOut, Direction | |
# IRM | |
pulses = pulseio.PulseIn(board.D0, maxlen=2000, idle_state=True) | |
led = DigitalInOut(board.D13) | |
led.direction = Direction.OUTPUT | |
toggle = True | |
while True: | |
if (len(pulses) > 10): | |
pulses.pause() | |
output = '{"name":[' | |
for i in range(len(pulses)): | |
output = output + "{},".format(pulses[i]) | |
output = output[:-1] + "]}" | |
print(output) | |
pulses.resume() | |
pulses.clear() | |
led.value = toggle; | |
toggle = not toggle | |
time.sleep(1) |
ここまでうまくできていればオンボードのLEDが点滅している。
赤外線リモコン信号受信
PC - Seeeduino XIAO間の通信はUSBシリアルなので, シリアルコンソールソフトウェアが必要です。 今回はArduino IDEとRLoginを例に使います。
Arduino IDEの場合
ツール - シリアルポート メニューからCOM5を選んで(COM番号は状況によってまちまち),
シリアルコンソールウインドウを開いておいてから,
リモコン受信部に向けてこのリモコンの運転/停止を押すとこのように信号が得られる。
RLoginの場合
RLoginの場合でもこのように受け取れる。
受信したリモコン信号
|
|
解析結果
今回作ったアプリケーションで解析すると
ダイキンエアコン, 温度22℃, 冷房, スイッチON, 風向上下, 風量2, オンタイマー10時間
(リモコン画像が違うかアプリケーションがバグっているかもしれない)
赤外線リモコン信号の解析アプリケーション
赤外線リモコン信号の解析アプリケーション のページで予告した通り赤外線リモコン信号の解析アプリケーションを分割して新しく作った。
https://github.com/ak1211/miruir
これ(UWP版)もWebアプリ版も同じ解析エンジンなので当然同じように使えますよ。
使いやすい方で試してください。
ダイキン工業製エアコンの赤外線リモコン信号の解析
信号解析は以下の情報を参考にしました。
https://github.com/blafois/Daikin-IR-Reverse
Timer
There are 2 times: timer for Power On and timer for Power Off. The type of timer is coded at offset 5
The timer delay position and coding defers depending of timer type.
For Timer ON, the delay is on offset 0a and 0b, with the following coding:
Few examples:
1 2
4H = 4 * 60 = 240 minutes = 0x00f0. This will be coded as f0 00 5H = 5 * 60 = 300 minutes = 0x012c. This will be coded as 2c 01
In Java, this can be decoded using the following code snippet:
1
int timerDuration = (0x100 * message[0xb] + message[0xa]) / 60;
For Timer OFF, the delay is on offset 0b and 0c, with the following coding:
Few examples:
1 2
1H = 1 * 60 = 60 minutes = 0x003C. This will be coded as c6 03 5H = 5 * 60 = 300 minutes = 0x012c. This will be coded as 2c 01
In Java, this can be decoded using the following code snippet:
1
int timerDuration = ((message[0xc] << 4) | (message[0xb] >> 4)) / 60;
このタイマー時間の抽出部分がよくわかっていない。(Java言語むつかしいので)
とりあえず今は こんなふう に適当にお茶を濁すことにする。
デコード関数
資料に対応するデコード関数がこれね。
構造そのまま記述したから見ればわかるだろうけど,
これは11, da, 27, 00, 00(16進数)から始まる第3フレームをデコードする。
|
|
まあなんやなんやで
UIライブラリが違う(Halogen -> React)だけで, プログラムの構造は同じ。
慣れの問題だけどHaskell由来の強力な静的型付けの支援を受けながら書くプログラムは気楽でいいよ。
エントリポイントは
JavaScriptの App関数 で
PureScriptのMain.app関数を呼び出して
PureScriptのMain.app関数でJSXを作って
React Native FlatListにコールバックとして
JavaScriptの関数を渡して
FFIを通じて
JavaScriptの関数が呼ばれる
こんな構造にしてみた。
エアコンのリモコン信号解析に今回作ったUWPアプリケーションと以前のWeb版赤外線リモコン信号の解析アプリケーションをお役立てください。
UWPアプリケーションにするためにこのあたりのソフトウェアを使いました。
- JavaScript
- React
- React Native
- React Native Elements
- React Native for Windows
- PureScript
- purescript-react-basic
- purescript-react-basic-native
以上。
解析終わり。
赤外線リモコン信号の送信したい?
おまけやで。
# https://ak1211.com/7586 (main.py) | |
# Copyright 2020 Akihiro Yamamoto | |
# Licensed under the Apache License, Version 2.0 | |
from digitalio import DigitalInOut, Direction | |
import array | |
import board | |
import pulseio | |
import supervisor | |
import sys | |
import time | |
# IRM | |
irm_pulse = pulseio.PulseIn(board.D0, maxlen=2000, idle_state=True) | |
# PWM | |
# carrier: 38kHz | |
# duty cycle: 1/3 = 65536/3 = 21845 | |
pwm = pulseio.PWMOut(board.D1, duty_cycle=21845, frequency=38000, variable_frequency=False) | |
infrared_led_pulse = pulseio.PulseOut(pwm) | |
led = DigitalInOut(board.D13) | |
led.direction = Direction.OUTPUT | |
toggle = True | |
while True: | |
if (len(irm_pulse) > 10): | |
irm_pulse.pause() | |
output = '{"name":[' | |
for i in range(len(irm_pulse)): | |
output = output + "{},".format(irm_pulse[i]) | |
output = output[:-1] + "]}" | |
print(output) | |
irm_pulse.resume() | |
irm_pulse.clear() | |
# LEDを点滅させる | |
led.value = toggle | |
toggle = not toggle | |
serial_inputs = "" | |
# 時間待ちのついでにシリアル入力をしておく | |
for c in range(6): | |
time.sleep(0.2) | |
while supervisor.runtime.serial_bytes_available: | |
serial_inputs += sys.stdin.read(1) | |
# 入力文字列を配列にする | |
start = serial_inputs.find('[') | |
end = serial_inputs.rfind(']') | |
if (end-start) > 10: | |
contents = serial_inputs[1+start:end] | |
to_output_pulses = array.array( 'H', [int(v.strip()) for v in contents.split(',')] ) | |
# 赤外線リモコン信号送出 | |
infrared_led_pulse.send(to_output_pulses) |
上に書いた手順通りシリアルコンソールを開いた状態で得た信号をコピーして,
送信したいときにシリアルコンソールにペーストすると送信できる。
自分の送信信号を自分で受けてしまうから, コンソールに信号が出るけど気にしなければよいね。
逆に考えると送信回路のデバッグに便利かな。
赤外線リモコン信号送受信用ハードウェア
最初のものに追加してこうした。
トランジスタっぽく見えているのは, 机上にあったN channel MOSFETね。
赤外線LEDと赤色LEDを直列につないで, 点滅を目で見れるようにしておくとデバッグに便利ですよ。
LED駆動回路の決め方は #赤外線リモコン のタグをクリックすればそんな内容のページがあるかもね。