技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

Circuit Playground Express で赤外線読み取り

環境

  • Circuit Playground Express (Bootloader3.10.0)
  • Circuit Python v5

エアコンの電源を入れるコードを読み取る

import pulseio
import board
import adafruit_irremote

pulsein = pulseio.PulseIn(board.REMOTEIN, maxlen=120, idle_state=True)
decoder = adafruit_irremote.GenericDecode()

while True:
    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("----------------------------")

まずは赤外線読み取り

Heard 310 Pulses: [3504, 1726, 453, 409, 451, 1285, 447, 416, 445, 417, 444, 418, 411, 450, 412, 448, 414, 447, 415, 446, 416, 445, 417, 444, 419, 452, 410, 451, 411, 455, 408, 449, 412, 448, 414, 447, 419, 441, 417, 445, 418, 442, 420, 451, 411, 451, 412, 449, 412, 448, 415, 447, 415, 445, 417, 444, 418, 443, 419, 452, 411, 450, 1284, 449, 1287, 444, 418, 443, 420, 451, 410, 451, 412, 449, 411, 450, 9967, 3505, 1725, 444, 418, 452, 1284, 448, 414, 446, 416, 445, 417, 444, 418, 443, 421, 451, 410, 450, 411, 450, 413, 448, 414, 447, 415, 446, 416, 444, 1291, 452, 411, 450, 412, 448, 414, 447, 416, 445, 416, 445, 417, 444, 418, 443, 1293, 449, 1286, 446, 1290, 452, 410, 451, 411, 454, 1284, 444, 416, 445, 417, 444, 418, 443, 419, 452, 410, 451, 411, 450, 412, 449, 413, 447, 415, 446, 417, 444, 418, 443, 419, 452, 410, 451, 416, 446, 415, 445, 418, 443, 419, 452, 411, 450, 411, 450, 412, 449, 413, 448, 414, 447, 415, 445, 417, 444, 418, 453, 1283, 449, 1286, 446, 417, 444, 417, 443, 420, 452, 410, 451, 411, 451, 411, 449, 414, 448, 414, 446, 416, 445, 417, 443, 1293, 451, 1284, 447, 415, 445, 418, 443, 418, 453, 409, 452, 410, 451, 411, 450, 412, 448, 414, 451, 411, 446, 416, 445, 418, 443, 423, 449, 410, 451, 410, 450, 412, 449, 413, 448, 415, 446, 416, 445, 417, 444, 418, 454, 408, 453, 409, 451, 412, 449, 413, 448, 1288, 445, 417, 453, 408, 453, 410, 451, 412, 449, 412, 449, 414, 447, 415, 446, 416, 445, 417, 443, 1292, 451, 1285, 447, 415, 446, 1290, 452, 411, 450, 411, 450, 412, 449, 414, 447, 415, 447, 1288, 453, 409, 452, 1284, 450, 412, 448, 415, 445, 1290, 453]
Failed to decode:  ('Pulses outside mark/space',)
----------------------------

な…なげぇ…と思ったら、

TVや照明のリモコンが「どのボタンを押されたのか」という情報だけを赤外線信号で送っているのに対し、エアコンのリモコンは、以下の画像のような「リモコンの液晶に表示されている全ての情報」を毎回送っているためです。つまり、同じ「温度を下げる」ボタンを押した場合でも、それまでの操作によって送信される信号が異なります。

[https://qiita.com/gorohash/items/598d69a63bd6b4308291:title]

こ…これは…w

気を取り直して読み取ってみる。この数字は on-off のそれぞれの時間を記録してて、「3542 マイクロ秒光って、1703 マイクロ秒消えて…」てなかんじ。
で単位時間はおよそ 400 ms 位(この辺の値が多い)となると、「家製協(AEHA)フォーマット」と予測。基本単位が 425μs なので合ってそう。

ナルホドこうして操作するのか…理解はしたけど、目的はエアコンの On/Off できればいいので、気温 25 度で on がとれたならいっかー

ということで Off も記録する。

[3536, 2, 479, 383, 478, 384, 477, 387, 474, 386, 475, 387, 474, 389, 472, 390, 481, 381, 480, 383, 478, 383, 478, 385, 476, 385, 476, 388, 473, 388, 473, 389, 472, 391, 480, 381, 481, 381, 479, 384, 477, 386, 475, 386, 480, 382, 476, 388, 472, 389, 472, 390, 481, 381, 481, 382, 448, 413, 479, 383, 477, 1259, 453, 1284, 448, 413, 479, 383, 478, 384, 478, 384, 476, 384, 477, 9942, 3532, 1698, 482, 380, 480, 1255, 477, 386, 475, 387, 474, 388, 473, 390, 471, 391, 480, 382, 480, 382, 478, 385, 477, 384, 477, 386, 474, 387, 474, 1262, 482, 380, 480, 382, 479, 383, 478, 385, 476, 387, 475, 386, 474, 388, 472, 1263, 480, 1256, 476, 1259, 473, 389, 472, 391, 481, 1255, 477, 385, 476, 386, 475, 387, 474, 388, 473, 389, 482, 0, 1262, 481, 380, 486, 377, 479, 384, 478, 383, 478, 385, 476, 386, 475, 388, 473, 388, 473, 389, 472, 390, 482, 380, 481, 386, 475, 383, 478, 384, 477, 386, 475, 386, 474, 388, 473, 1263, 480, 1256, 476, 386, 475, 388, 473, 388, 473, 389, 472, 391, 481, 381, 480, 382, 479, 383, 478, 385, 476, 386, 475, 1260, 483, 1253, 479, 384, 477, 384, 477, 385, 476, 387, 474, 388, 473, 389, 482, 380, 481, 382, 479, 383, 478, 384, 477, 385, 476, 386, 475, 388, 473, 390, 471, 391, 481, 381, 480, 381, 480, 382, 479, 383, 478, 384, 476, 387, 474, 387, 475, 388, 472, 390, 471, 1264, 479, 384, 477, 385, 476, 387, 474, 387, 474, 388, 473, 389, 482, 380, 481, 381, 480, 383, 478, 1258, 475, 1260, 482, 380, 481, 1255, 477, 385, 476, 386, 475, 387, 474, 1262, 480, 1255, 477, 385, 476, 386, 475, 1261, 482, 380, 481, 382, 479, 1255, 477]
Failed to decode:  ('Both even/odd pulses differ',)
----------------------------

このデコーダ微妙…で、ソースみたら NEC しか対応してないらしい |||orz

やってみておもったのはこの赤外線読み取り安定しない…家製協(AEHA)フォーマットなのはおよそ把握できたのだけど、ヘッダの読み取りからして安定しない(8T4T が先頭に入る)どういうこっちゃ…

何回か取り直したら良さげな数字が出た

Heard 391 Pulses: [3531, 1700, 448, 415, 446, 1289, 453, 409, 452, 411, 451, 410, 451, 412, 448, 414, 448, 414, 446, 416, 445, 417, 444, 418, 453, 409, 452, 411, 450, 1285, 447, 415, 446, 416, 446, 417, 453, 408, 453, 409, 452, 411, 450, 412, 449, 1286, 447, 1289, 453, 1283, 449, 413, 448, 414, 448, 1288, 455, 407, 453, 409, 452, 411, 450, 412, 448, 414, 447, 415, 446, 416, 445, 417, 444, 418, 453, 410, 451, 410, 452, 410, 451, 411, 450, 413, 447, 415, 447, 415, 445, 418, 443, 418, 453, 409, 452, 410, 451, 411, 450, 412, 449, 414, 451, 411, 446, 416, 445, 417, 444, 423, 448, 409, 452, 410, 453, 409, 450, 1286, 448, 414, 447, 1289, 453, 409, 452, 410, 454, 408, 449, 414, 448, 413, 447, 420, 441, 417, 444, 1292, 450, 1285, 448, 1287, 445, 418, 443, 419, 452, 1283, 449, 414, 447, 415, 447, 415, 445, 417, 445, 417, 454, 408, 452, 412, 449, 412, 449, 413, 448, 415, 446, 415, 446, 416, 445, 417, 444, 418, 454, 409, 451, 411, 450, 413, 448, 1286, 446, 1289, 453, 410, 452, 411, 449, 412, 449, 1286, 447, 417, 443, 418, 453, 1282, 451, 1286, 446, 416, 445, 417, 444, 418, 454, 409, 452, 410, 450, 412, 449, 413, 448, 414, 447, 415, 446, 1290, 453, 1282, 450, 1286, 446, 1290, 453, 1282, 450, 413, 448, 1288, 445, 417, 443, 1292, 451, 412, 449, 413, 448, 414, 447, 415, 446, 417, 444, 418, 453, 410, 451, 410, 451, 411, 450, 413, 448, 414, 447, 415, 446, 417, 444, 417, 444, 418, 453, 409, 452, 410, 451, 411, 450, 412, 449, 413, 448, 414, 447, 415, 446, 417, 444, 418, 443, 419, 453, 1283, 449, 1286, 446, 416, 445, 417, 444, 418, 453, 410, 451, 411, 450, 412, 449, 413, 448, 414, 446, 416, 445, 417, 444, 418, 443, 419, 452, 410, 451, 411, 450, 412, 449, 414, 447, 415, 446, 416, 449, 413, 444, 419, 453, 409, 452, 414, 447, 411, 450, 413, 448, 1287, 444, 418, 443, 420, 453, 408, 451, 411, 451, 411, 450, 413, 448, 414, 446, 416, 445, 417, 444, 1292, 451, 1284, 447, 416, 450, 1285, 453, 409, 452, 410, 451, 411, 450, 1286, 446, 1289, 454, 410, 451, 411, 450, 1285, 447, 415, 447, 416, 444, 1291, 452]
Failed to decode:  ('Pulses outside mark/space',)
----------------------------

試しに発信してみたけど

import array
import pulseio
import board

# 50% duty cycle at 38kHz.
pwm = pulseio.PWMOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15)
pulse = pulseio.PulseOut(pwm)

onCommand = [3503, 1727, 452, 410, 452, 1284, 447, 416, 445, 416, 445, 418, 453, 408, 453, 410, 451, 411, 450, 416, 445, 413, 448, 415, 446, 416, 445, 417, 443, 1293, 450, 411, 450, 413, 448, 414, 447, 415, 446, 416, 445, 417, 444, 418, 453, 0, 454, 409, 452, 409, 452, 411, 449, 413, 448, 414, 447, 415, 446, 416, 445, 417, 445, 1291, 451, 1285, 447, 416, 445, 417, 444, 418, 443, 419, 453, 407, 454, 9964, 3510, 1721, 447, 415, 446, 1289, 454, 408, 454, 409, 450, 412, 449, 413, 448, 414, 447, 416, 445, 416, 445, 417, 444, 419, 457, 405, 452, 410, 451, 1288, 443, 415, 446, 416, 445, 417, 444, 419, 452, 410, 451, 411, 450, 412, 449, 1286, 447, 1289, 453, 1283, 449, 413, 448, 414, 447, 1288, 444, 419, 452, 411, 451, 411, 450, 412, 449, 412, 449, 414, 447, 415, 447, 415, 445, 417, 445, 417, 453, 409, 453, 409, 451, 413, 448, 1287, 446, 415, 446, 417, 444, 418, 453, 1282, 450, 1286, 446, 416, 445, 417, 444, 418, 453, 1283, 450, 412, 449, 413, 447, 8192, 1282, 450, 413, 448, 414, 447, 416, 445, 416, 445, 418, 443, 420, 451, 410, 451, 412, 449, 412, 450, 412, 448, 1288, 445, 1290, 452, 410, 451, 412, 449, 413, 448, 414, 447, 415, 446, 416, 445, 417, 444, 418, 452, 410, 451, 411, 450, 412, 451, 411, 448, 414, 447, 416, 445, 419, 442, 418, 443, 419, 453, 409, 452, 411, 450, 412, 449, 413, 448, 415, 446, 416, 445, 417, 444, 1291, 452, 411, 450, 411, 450, 412, 449, 413, 448, 415, 446, 416, 445, 417, 444, 419, 453, 408, 453, 1287, 444, 1287, 445, 418, 443, 1292, 451, 412, 449, 413, 448, 414, 447, 415, 446, 417, 444, 1291, 452, 410, 451, 1284, 447, 415, 446, 417, 444, 1291, 451]
offCommand = [3531, 1700, 448, 415, 446, 1289, 453, 409, 452, 411, 451, 410, 451, 412, 448, 414, 448, 414, 446, 416, 445, 417, 444, 418, 453, 409, 452, 411, 450, 1285, 447, 415, 446, 416, 446, 417, 453, 408, 453, 409, 452, 411, 450, 412, 449, 1286, 447, 1289, 453, 1283, 449, 413, 448, 414, 448, 1288, 455, 407, 453, 409, 452, 411, 450, 412, 448, 414, 447, 415, 446, 416, 445, 417, 444, 418, 453, 410, 451, 410, 452, 410, 451, 411, 450, 413, 447, 415, 447, 415, 445, 418, 443, 418, 453, 409, 452, 410, 451, 411, 450, 412, 449, 414, 451, 411, 446, 416, 445, 417, 444, 423, 448, 409, 452, 410, 453, 409, 450, 1286, 448, 414, 447, 1289, 453, 409, 452, 410, 454, 408, 449, 414, 448, 413, 447, 420, 441, 417, 444, 1292, 450, 1285, 448, 1287, 445, 418, 443, 419, 452, 1283, 449, 414, 447, 415, 447, 415, 445, 417, 445, 417, 454, 408, 452, 412, 449, 412, 449, 413, 448, 415, 446, 415, 446, 416, 445, 417, 444, 418, 454, 409, 451, 411, 450, 413, 448, 1286, 446, 1289, 453, 410, 452, 411, 449, 412, 449, 1286, 447, 417, 443, 418, 453, 1282, 451, 1286, 446, 416, 445, 417, 444, 418, 454, 409, 452, 410, 450, 412, 449, 413, 448, 414, 447, 415, 446, 1290, 453, 1282, 450, 1286, 446, 1290, 453, 1282, 450, 413, 448, 1288, 445, 417, 443, 1292, 451, 412, 449, 413, 448, 414, 447, 415, 446, 417, 444, 418, 453, 410, 451, 410, 451, 411, 450, 413, 448, 414, 447, 415, 446, 417, 444, 417, 444, 418, 453, 409, 452, 410, 451, 411, 450, 412, 449, 413, 448, 414, 447, 415, 446, 417, 444, 418, 443, 419, 453, 1283, 449, 1286, 446, 416, 445, 417, 444, 418, 453, 410, 451, 411, 450, 412, 449, 413, 448, 414, 446, 416, 445, 417, 444, 418, 443, 419, 452, 410, 451, 411, 450, 412, 449, 414, 447, 415, 446, 416, 449, 413, 444, 419, 453, 409, 452, 414, 447, 411, 450, 413, 448, 1287, 444, 418, 443, 420, 453, 408, 451, 411, 451, 411, 450, 413, 448, 414, 446, 416, 445, 417, 444, 1292, 451, 1284, 447, 416, 450, 1285, 453, 409, 452, 410, 451, 411, 450, 1286, 446, 1289, 454, 410, 451, 411, 450, 1285, 447, 415, 447, 416, 444, 1291, 452]

pulses = array.array('H', offCommand)
pulse.send(pulses)

うん、エラーは出ないんだけどね…多分データがどっか破損してる。

やはりもっと精度が欲しいのか…とはいえ、うちに NEC 製のリモコンないから正しいのかも検証できなかった |||orz