赤外線リモコン受信モジュールでリモコン生データを得てHomeKitから使う

DIYする

赤外線リモコン受信モジュール (110円) をRaspberry Piに取り付けて、赤外線パターンを取得・復号できるようにしました。天井照明リモコンの点滅パターンをこれで取得して、ESP32に組み込んで、HomeKitから点灯・消灯できました。

これまでのあらすじ

前回、HomeKitからパナソニックのエアコンをコントロールするスマート赤外線リモコンが完成しました。

エアコンリモコンのHomeKitアクセサリをDIYする (後編:温度センサ他)
エアコンリモコンに相当するアクセサリを作る最終回です。今回のターゲットはパナソニックのエアコンですが、他のメーカーでも同様に作れます。下図のように、(右から)HomeKitに接続したHomebridgeサーバから、MQTT経由でコマンドを出...

エアコンをコントロールするスマートリモコンとして、Nature Remoを使っていたのですが、これをDIYしたことでほぼ使わなくなってしまいました。唯一使用している機能が、赤外線リモコンの生データをローカルAPIで取得する機能です。

Nature RemoをHomebridge / HomeKitから使う
ネットから操作できる赤外線リモコンNature RemoをHomeKitから使えるように設定します。クラウド経由の設定と、ローカルAPIを使った設定の2種類の方法があります。 追記:Matter対応新型スマートリモコン、Nature Rem...

Nature Remoにリモコンを向けてボタンを押すと、Nature Remoがパターンを取得してくれます。そのパターンはhttpアクセスで知ることができます。パターン取得機能のためだけにNature Remoを使うのは勿体無いので、今回はこれをDIYします。赤外線リモコン受信モジュールをRaspberry Piに取り付けて、赤外線パターンを取得することにしました。

赤外線リモコン受信モジュール

使用した赤外線リモコン受信モジュールは、秋月電子で110円で売られているPL-IRM0101-3という製品です。

これ1個を、3本のワイヤでRaspberry Piに取り付けるだけで、赤外線パターンが得られます。この部品のことは、赤外線リモコン自作ページでよく見かけていたので、以前から知ってました。発売日が2004年だそうですので、18年も続くロングセラーです。秋月電子のサイトには、他にも半額くらいで類似の製品がいくつかありますので、そちらでも良かったかもしれません。

サイトには電源が5Vと書いてありましたが、リンクされていたデータシートによると3Vにも対応しているようです。ただ古いロットの製品(Rev B/1)は5V限定だったようです。Raspberry PiのGPIOは3Vなので、現行のRev B/2が必要です。

https://akizukidenshi.com/download/ds/paralight/PL-IRM0101-3_20180307.pdf(https://akizukidenshi.com/)

Raspberry Piに取り付ける

PL-IRM0101-3のピンは3本で、左から、(1)信号、(2)GND、(3)Vccです。

これらの1, 2, 3番ピンをRaspberry PiのGPIOの 7, 9, 1番ピンに接続しました。

温度湿度センサの時と同様に、フラットケーブルになったジャンパ線を割いて使用しました。そして受信モジュールを、Raspberry Piケースにテープで止めしました。

生データ取得プログラム

GPIOピンの7番はGPIO 4です。データシートによると、受信モジュールは通常は1で、赤外線信号があると0になるようです。下図の上段がモジュールが受け取る赤外線強度、下段がモジュールの出力です。

GPIOをreadしたところ、やはり通常は1で、赤外線が照射されると0になりました。そこで、

  1. GPIOが10秒間1のままならば終了する
  2. GPIOが1ms以上0になったら以下の測定を開始する
  3. GPIOが変化するたびにその間隔をマイクロ秒単位で記録する
  4. GPIOが20ms以上変化しなくなるまで3を繰り返す
  5. 結果を表示する

というプログラムを、Raspberry Pi上のPython3で作成しました。以下です。

#!/usr/bin/python3
import RPi.GPIO as GPIO
import time
import sys

PIN=4

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN,GPIO.IN)
raw=[]

print("Waiting for IR signal (for 10sec)...")

time_now=time.time()
time_start=time_now

while (time_now - time_start) < 10 :
  time_now=time.time()
  if GPIO.input(PIN)==0:
    time.sleep(0.001) #1ms delay
    if GPIO.input(PIN)==0: #still 0
      break

if (time_now - time_start) >=  10 :
  print("Time out.")
  sys.exit()

time_start=time_now
gpio_last=0
while (time_now - time_start) < 0.02 :
  time_now=time.time()
  gpio_now=GPIO.input(PIN)
  if(gpio_last != gpio_now):
    raw.append(round((time_now - time_start)*1000000))
    time_start=time_now
    gpio_last=gpio_now

print(raw)

天井照明リモコンパターンを取得する

簡単な例として、毎回登場している天井照明のリモコンを試します。これのon/offボタンのパターンを取得してみます。上記のプログラムを動かすと(irreceive.pyという名前をつけました)、

$ ./irreceive.py
Waiting for IR signal (for 10sec)...
[6929, 4539, 371, 1316, 369, 494, 342, 1345, 344, 514, 368, 1319, 369, 492, 345, 1342, 345, 518, 367, 490, 366, 1324, 371, 485, 371, 490, 370, 1318, 345, 1343, 371, 1314, 372, 1323, 345]

という結果が得られました。グラフにすると以下のようです。横軸が時間で縦軸が赤外線出力です。開始のパルスは長めですし、0, 1に相当するパルス幅も広く、一般的なフォーマットとは少し違う特殊なリモコンのようです。

ESP32で作るDIYスマートリモコンに組み込む

ESP32で、エアコン用のスマートリモコンを作りましたが、

エアコンリモコンのHomeKitアクセサリをDIYする (前編:赤外線送出)
エアコンリモコンに相当するアクセサリを作ろうと思いました。これでiPhone/Macの画面に上の図のようなコントローラが現れるはずです。最初のターゲットはパナソニックのエアコンです(他のメーカーでも同様に作れるはずです)。下図のように、(右...

今ここで得られた生データを送出する機能を、このESP32に追加して、天井照明もコントロールするように設定します。

エアコンのリモコンとして動作していたプログラムに、この天井照明のパターンを送出する部分を以下のように追加しました。赤外線点滅の生データを送出するためには、IRsendクラスのインスタンス(下記プログラムではirsend)を作って、これのsendRawというメソッドを使えば良いようです。このメソッドでon/offの生データを以下のように送ります。

#include <Arduino.h>
#include <ArduinoOTA.h>
//IR Remote
#include <IRremoteESP8266.h>
const uint16_t kIrLed = 4;  //GPIO for IR LED. Recommended: 4.
const char  SUBTOPIC[] = "mqttthing/irOffice/set/#";
(略)
IRsend irsend(kIrLed);  //for sending raw IR data
//ceiling light on/off pattern
const uint16_t kCeilingOnOff[35]= {
6929, 4539, 371, 1316, 369, 494, 342, 1345, 344, 514, 368, 1319, 369, 492, 345, 1342, 345, 518, 367, 490, 366, 1324, 371, 485, 371, 490, 370, 1318, 345, 1343, 371, 1314, 372, 1323, 345
};

void setup() {
(略)
}

//MQTT: subtopic call back
void onMessageReceived(const String& topic, const String& message) {
  String command = topic.substring(topic.lastIndexOf("/") + 1);
  if (command.equals("Active")) {
(略)
  }else if(command.equals("CeilingOnOff")){
    if(message.equalsIgnoreCase("true")) irsend.sendRaw(kCeilingOnOff, 35, 38);
  }
}

//MQTT: connection callback
void onConnectionEstablished() {
  ArduinoOTA.setHostname("irOffice");
  ArduinoOTA.setPasswordHash("xxxxxxxxxxxxxxx");
  ArduinoOTA.begin();
  client->subscribe(SUBTOPIC, onMessageReceived); //set callback function
}

(略)

void loop() {
  ArduinoOTA.handle();
  client->loop();
}

これで、mqttthing/irOffice/set/CeilingOnOffにtrueというメッセージが送られると、この生データを送出します。

一方、HomebridgeのMqttthingの設定部分には、以下のように追記して、このMQTTメッセージに対応するスイッチを作成しました。

{
  "type": "switch",
  "name": "Ceiling Toggle",
  "topics": {
    "setOn": "mqttthing/irOffice/set/CeilingOnOff"
  },
  "turnOffAfterms": 300,
  "accessory": "mqttthing"
}

この結果、iPhone, Macのホーム.appに、以下のように赤外線信号を送出するスイッチが追加されました。turnOffAfterms (turn off after ms) を300msに設定したので、通常はoffの状態で、

クリックすると0.3秒だけonの状態になり、またoffに戻ります。

これをクリックするたびに、上記の赤外線パターンが送出され、天井照明はon/off状態を交互に繰り返します。

デコード機能

前後しますが、上述のPythonプログラムに、赤外線パターンのデコード機能を追加しました。上記のプログラムの末尾に、以下を追加します。

T=400.0
isOn=False
evaluateNext=False
count=0
aByte=0

for x in raw:
  isOn = not isOn
  width=round(x/T)
  if(width > 3) and (isOn == False):
    count=0
    aByte=0
    print()
  if(width == 1) and (isOn == True):
    evaluateNext=True
  elif(evaluateNext):
    evaluateNext=False
    if(width == 1):
      aByte = aByte >> 1
      count += 1
    elif(width == 3):
      aByte = (aByte >> 1) + 0x80
      count += 1
    if(count >= 8):
      print(format(aByte,'02X'),end='')
      aByte=0
      count=0

print()

かなり手抜きです。Tで、短いパルス幅を指定しておきます。T幅の赤外線Onパルスが見つかったら、その次のOff幅を測定して、Tならば0、3Tならば1としています。また、それぞれのバイトのLSBから順番に送信されていると仮定してます。NECと家製協のフォーマットがこの方式なので、汎用性は高いです。

例えば、上記の天井照明リモコン (これは独自フォーマットですが0, 1 がほぼ1T, 3Tです) ならば、

$ ./irreceive.py
55F2

となります(生データのprint文はコメントアウトしました)。エアコン用スマートリモコンで使用したパナソニックのエアコンならば、

$ ./irreceive.py
0220E00400000006
0220E00400412C80AF0000066000008000068E

と表示されます。 (これは22度暖房のパターンです)

まとめ

秋月電子などで一般的に売られている赤外線リモコン受信モジュールを、Raspberry Piに取り付けて、赤外線を取得しデコードもできるようにしました。これを用いて、天井照明のリモコンのon/offパターンを測定し、ESP32から送出するようにして、HomeKitから使えるようにしました。この手順で、HomeKit対応スマート学習リモコンをDIYできます。

コメント

タイトルとURLをコピーしました