remote Pi

家の外からリモコンで家電をうごかす

remoto Piは、自宅の部屋にあるシーリングライトやエアコンなど、 ふだん赤外線リモコンをつかって操作している機器を、職場や屋外から操作するために作りました。 あらかじめリモコンから出る信号を記録しておくことで、屋外からでも操作が可能になります。

下のボタンを押すと、実際にremotePiが動作し、我が家のシーリングライトなどがコントロールできます。 試していただいて構いませんが、本当に動作しているかを確認する方法は用意していません。悪しからず。

構成

remote Piは、Wifiでインターネットに接続したRaspberry Pi Zero 2とpythonプログラム、 自作の赤外線送受信ボード、そして操作したい内容を扱うWebサーバ上のphpプログラムでできています。

Raspberry Pi Zero 2

長辺65mm、短辺30㎜という、とても小さい基板がむき出しの小型コンピュータです。 HDMI出力、Wifi、USB(micro-B)端子を搭載しています。電源供給用のUSB端子(micro-B)もあります。
今回ネットワークに接続する必要があるのでWifiの機能は使用しますが、USB、HDMIコネクタは使用しません。

RaspberryPiの基板にはGPIOピンという40の端子があり、別に用意した電子回路などとつなぐことで 電気信号の入出力を行うことができます。物理的なスイッチやLEDを接続して、プログラミングしたソフトウェアで 制御することで、スイッチに反応してLEDを点灯させる、というようなことができます。

ストレージはmicroSDカードで、LinuxベースのRaspbianOSで動きます。 事前に、別PCを使用して、Wifi接続のための設定を含めたOSを焼きこんだmicroSDを作成しておくことで、 RaspberryPiの電源を入れるだけでネットワークにつながったコンピュータとして動きます。

開発時、運用時ともキーボードやマウス、ディスプレイは接続、使用しません。 開発用の別PCからSSH接続しながらファイル操作などをすることで開発を進めました。

赤外線送受信ボード

RaspberryPi以外のハードウェアとして、 リモコンの代わりに赤外線信号を発信するLEDと、既存のリモコン信号を記録するための受信モジュール、 それらを動かすために必要な部品類を1枚の基板上に集めたボードを作成しました。

GPIOピンを通じてRaspberryPiとやりとりをします。RaspberryPiにはGPIOピンヘッダが搭載されているので、 そこに差し込むソケットを基板上に設けることで、簡単に接続できるようにまとめました。

赤外線受信モジュールは電源を供給するだけで、 受け取った信号(38kHz搬送波に乗った赤外線の明滅を復調した信号)を電圧のHigh/Lowで取得できます。 この信号線を入力ピンとして設定したGPIOピンに接続しています。

赤外線送信LEDは、940nmの赤外線を出すLEDです。 送信したい信号(High/Low)と、40kHz(本当は38kHzが理想)のPWMを、 それぞれGPIOの出力ピンから受け取り、MOSFETで合成してから赤外線LEDを光らせています。

ソフトウェア(RaspberryPi上で動作)

RaspberryPi上で動作するプログラムとして、リモコン信号を記録する「recoder.py」、 記録した信号を再生する「player.py」、操作指示を定期確認する「poller.py」の3つを作成しました。 拡張子のとおり、Pythonで書かれたプログラムです。

recorder.pyは、赤外線信号を記録するプログラムです。 赤外線受信モジュールからGPIOピンに入力される信号を読み取り、High/Lowの継続時間を計測・記録します。 信号の情報は「.sig」ファイルとして保存しています。

player.pyは、保存されている.sigファイルを読み取り、赤外線信号を送出するプログラムです。 搬送波としてGPIOのPWMピンから40(ホントは38にしたい。理由は後述)kHzのPWM波形を出力するとともに、 指定された.sigファイルの信号情報をもとに、PWMとは別のGPIOピンからHigh/Lowの状態を出力します。 このように、搬送波であるPWMと信号の波形は別々に出力し、送受信モジュール上で合成する方法を取りました。

poller.pyは、定期的に指定のWebサーバのJSONファイルを取得し、求められている操作内容を確認します。 新たな操作指示があれば、それに応じた.sigファイルを指定しながら、player.pyを実行します。

ソフトウェア(Webサーバ上で動作)

家の外からRemotoPiを動かすフロントエンドとして、Webサーバ上で動作するPHPプログラムを作成しました。 実行したい操作を示す引数でPHPを叩くことでpoller.pyが取得しに来るJSONファイルを更新します。

基礎技術

Python

RaspberryPiにはPython3をインストールしています。RaspberryPi上で動くプログラムはPythonで書いています。

pigpio

pigpioは、RaspberryPiのGPIOピンをわかりやすく制御、使用するためのライブラリです。 インストールし、デーモンとして動作させておくで、Pythonプログラムからインポートし、使用できます。 GPIOピンを単純な入出力ピンやPWM出力ピンとして使うことはもちろん、 あらかじめバッファしておいた信号波形を一気に出力する機能があり、これを使用しています。 またPWM出力についても、GPIO18番ピンのようなハードウェアPWMではなく、 pigpioが用意しているPWM機能を使用しています。 PWMの周波数設定(選択肢)に限度があり、このため本来は38kHzとしたいところを40kHzにしています。

もともとRaspberryPiにあるハードウェアPWMを使用しない方法を取った理由は、 信号出力のためにpigpioのwave機能を使用すると、同時にハードウェアPWMを正しく利用できないからです。

NOTE: Any hardware PWM started by hardware_PWM will be cancelled.

wave_send_once(wave_id)

リモコンの信号

リモコンの赤外線LEDが光ることで送り出す信号は、メーカーの規格に沿った0/1のビット列です。LEDが光る、消えるの点滅で情報を送っています。

しかし、単純にLEDが消えていれば0、光っていれば1というわけではありません。1を送る間は、38kHzのリズムで点滅している必要があります。 つまり、38kHzで高速に点滅するLEDが消えているか光っているかで0/1を伝える仕組みです。

考えたこと

やりたかったこと自体は実現して機器としては完成しましたが、不満があります。それは機器の反応が悪いことです。 満足に動作するのはシーリングライトくらいです。

LED光量

LEDがちゃんと光っているかについては目視では確認できないため、スマホのカメラを通じて確認しました。 シーリングライト、エアコン、テレビのいずれのリモコンの赤外線LEDを見てみても、かなりしっかり点滅が確認できました。 しかし、今回の製作に使用したLEDは青色の樹脂レンズのもので、抵抗値を調整してみてもかなり暗く光ります。 砲弾型のLEDレンズが邪魔をするのかとヤスリできれいに削ってみましたが、多少、指向性が広がったくらいでした。

搬送波

本来は38kHzの搬送波を作る必要がありますが、pigpioのPWM機能を使用するために40kHzに固定されてしまいました。 この程度の誤差であればどの機器も動くには動くのですが、反応が鈍くなることは予想できます。

pigpioのwave機能で搬送波を含めた変調済みの信号を作ってしまうことも可能なのですが、バッファの容量の制限で、 エアコンのリモコンのような長い信号を、途切れなく一気に送出することができませんでした。

RaspberryPiに38kHzを作らせずに別回路で搬送波を用意するか、pigpio以外の方法で信号全体を出力するほうが 安定して動作するかも、と思いました。