ひどく冷え込み、起きられない日が増えてきました。ついでに、株価も冷え込んでいます。

我が家のリビングルームのエアコンは、「ダイキンのいいやつ」らしいです。私が買ったのではなく、元からついていました。前の家主が買ったんでしょう。おそらく10年くらい動いています。このエアコンですが、リモコンの調子が悪く、とくに、温度設定のボタンが反応しないことが多くて、困っています。でも、オン・オフできるし、冷暖房の切り替えもできるので、そこまで致命的ではありません。まるで生殺しのようですが。

リモコンはそのうち買い換えるとして、もっと自由に遠隔操作したいニーズもあります。寝室から操作したり、外出先から操作したり、Google Home などから操作したり・・・です。ちょうど別の用事で赤外線LEDや赤外線受光センサーが余っていたので、手元にある部材で、自分で赤外線リモコンを作ってみようと思いました。

昔を思い出しながら、準備する

以前、ちょっとしたプロジェクトで、Arduinoを使った赤外線リモコンを作りました。だいぶ忘れてしまっているのですが、昔書いたノートや電子パーツをつなぎ合わせて作ってみたいと思います。家にあるものは・・・

Arduino Micro は、ATmega32u4を搭載したマイコンボードです。GPIOピンの一部はPWM出力もできます。電源は、Micro USBケーブルで給電します。
この Arduino Micro は、たとえばWifiなどの通信機能はありません。今回は、Raspberry Pi を母艦として使い、シリアル通信で Raspberry Pi からコマンドを送りつけて、Arduino側は赤外線LEDで信号を流します。Raspberry Piとエアコンとの間に遮蔽物があるので、てきとうな長さのMicro USBケーブルを使って、信号が届く位置にArduinoを起きます。
Raspberry Piの上では、LinuxやHTTPサーバがすでに動いています。ここに新たなインターフェースを実装して、インターネットからコマンドを受け取れるように作りたいですね。

ユーザ -> WebApp -(HTTP-API)-> インターネット -> 家ルーター -> RaspberryPi -(シリアル)-> Arduino -(IR)-> エアコン

こんな感じでしょうか。
こういったシステムを作るときは、それぞれの階層を結ぶインターフェース設計が重要になってきます。マシン間のインターフェースだけでなく、もちろんUI(ユーザーインターフェース)も重要です。
ボトムアップでArduino側から開発していくことも出来ますが、そこに集中してしまうと、ユーザー(つまり私自身ですが)から見たときに使い勝手が悪いシステムになってしまいます。そういった種類の使いにくさは、現実の製品でもよく見られることです。ハード側に寄るにつれて、設計や製造に時間がかかるし、変更がききにくいからです。
今回は、UIから温度調整などの機能も使えるようにしたいと考えています。エアコンのフル機能を再現するつもりはありませんが。かといって、学習リモコンのように、数個のプリセットから選ぶだけ・・・というのは物足りない。いや、もしかして、十分かもしれませんが。
UIは考えたいのですが、それにしても、赤外線リモコンへの理解を深めておく必要があります。ハードウェアを無視したUI設計というのもまた本末転倒なのです。
リモコン信号について、調査や実験をしてみます。

信号を読み取る

Arduinoは、USBでカンタン接続できて、しかもライブラリが豊富に公開されています。なかには、赤外線に関するライブラリもあります。さすが!

この Arduino-IRremote が、赤外線で信号の送受信ができるライブラリです。

https://github.com/z3t0/Arduino-IRremote

このデモのなかに含まれているIRecvDumpを使うことで、赤外線を受信して、ダンプすることができます。まずは感覚をつかむために、ダンプして全体の傾向を観察してみます。
GPIOの11番と、VCCと、GNDに、赤外線センサーを接続。ArduinoとMacをUSBケーブルでつなぎます。それから、ArduinoIDEで、デモコードをロードして、コンパイル、書き込み・・・。シリアルポートにターミナルをアタッチします。この流れが、だいぶ久しぶりであり、ほとんど忘れていました。

ターミナルを見てみます・・・。

なるほど、わからん・・・。

Panasonicとして解釈されたり、されなかったり。Unknownというのも頻出するし。
たかがエアコンのリモコンなので、数十バイトくらいのシンプルな信号だと思っていたのですが、出鼻をくじかれた気持ちです。ググって情報を集めることにしました。

ダイキンエアコンの解析結果

先人の知恵を借ります。

この Daikin-IR-ReverseのREADMEが、大変わかりやすく、参考になりました。
https://github.com/blafois/Daikin-IR-Reverse

赤外線リモコンは、想像できる通り光のON/OFFで信号を表します。ただし、中身はそう単純でもありません。光っている状態が1で、逆が0で、というわけではないのです。光のパターンをどのように符号化するのかは、各メーカーによって異なるようです。それから、符号を組み合わせることで、コマンドとなります。

ダイキンの場合は、HIGH(発光)はつねに一定時間になるようです。それから、消灯が2種類あり、LONGとSHORTにわけられます。つまり、長い時間消灯していたらビットが1になり、短い時間消灯していたらビットが0になります。消灯と消灯の間は、必ず一定時間の発光があります。まるで、モールス信号みたいですね。

赤外線のプロトコルを見ていると、電気信号の通信プロトコルを思い出します。例えば、I2C(アイスクエアドシー)という、ICチップ同士が基板のうえで通信するためのプロトコルがあります。I2Cでは、クロックパルス用の線と、データ用の線の、2つを使って通信します。I2Cでは、さらに、1つのバス上に、いくつものデバイスを接続することができます。データ用の線が1本なのに、どうしてデバイスを複数接続できるのか・・・というと、各デバイスがアドレスを持っているからです。信号の最初のほうがアドレス、その後にコマンドが続く、という感じになります。まさにシリアルですね。線が2本だけなので、省スペースというわけです。電気の場合はクロックパルス信号線がありますが、赤外線の場合はありませんので、モールス信号のように、時間の長さで符号を表現することになるのです。

符号化の方式が理解できたところで、それより上位のレイヤーも解析できるようになります。
Daikin-IR-Reverseによれば、ダイキンエアコンのプロトコルは3つのフレームで構成されています。

各フレームは、フレームヘッダではじまり、CRCで終わります。フレームヘッダは、固定の文字列です。CRCは、誤り検出用のデータです。

第一のフレームは、8バイトで、「おまかせ」モードのフラグがあるだけで、不変です。
第二のフレームは、8バイトで、完全に固定の内容が書かれています。
第三のフレームは、13バイトで、リモコンのパラメータがすべて入っています。冷暖房のモードや、温度や、風量、タイマーなどなどです。

このプロトコルを自分で実装してもよいのですが、すでにArduinoで実装した人がコードを公開しています。

https://github.com/danny-source/Arduino_DY_IRDaikin

かなり完成度が高いです。信号の読み取りと、送信ができます。ピンの番号とシリアルクロックだけ変えれば、すぐに動きます。これで、いま私が持っているリモコンの信号を解析できるようになりました。さらに、このArduino_DY_IRDaikinには、コマンドビルダ/コマンド解析も含まれています。

長くなってきたので、このへんで。
続きます。