Raspberry Pi 3で遠隔リモコン操作に挑戦(Raspbian Scratch)

最近寒すぎて帰宅直後が辛いので、家に帰る前にエアコンをオンにしたかったお話。

参考元記事はこちら。というかこれ見れば全部オッケー(と思ってたら結構ハマったので記事を書くことにした)

Slack経由で家の外からエアコンをon, offできる装置を、Raspberry Piで作ってみた。(しかも御坂美琴ちゃんが応答してくれる) - Qiita

元記事では途中Slackを使っている部分があるけど、利便性を考えてDiscordに置き換えることに。

 

用意したもの

既に持ってたもの
・Raspberry Pi 3(押し入れで眠っていたので何か活用させたかった)
・周辺機器(電源、ケース、HDMIケーブル、ディスプレイetc)

買い足したもの
5φ赤外線LED 940nm クリアレンズ 照射角30度 503IRC2V-2AD
リモコン受光モジュール RPM7138-R

参考元記事では秋月電子が紹介されていたが、今回は同様品をマルツオンラインで購入。

秋月で買うならこのへんが対象になるのかな。
5mm赤外線LED OSI5FU5111C-40 (5個入)
赤外線リモコン受信モジュール PL-IRM2121(38kHz)

元記事では3.3Vで動く受信モジュールが使用されているけど、もう売ってなかったので代わりに5V動作するものを購入している。

あとブレッドボードは持ってなかったので空中配線で何とかする。最終的にユニバーサル基板に貼り付けてラズパイのケースに固定することにする。

 

LEDと抵抗器の準備


LEDを点灯させる際について回るのが抵抗器の話。マルツオンラインで注文したものが届くまでの間にちゃちゃっと済ませる。

抵抗器の細かい計算方法は下記サイト参考。
Raspberry Pi:ラズベリーパイを電源にしてLEDを点灯する||動画付き|IT企画研究所

今回購入した赤外線LEDは定格電圧/電流が「1.2V/20mA」で、使用する電源は3.3vなので、

(3.3v-1.2v) ÷ 0.02A = 105Ω

ということになり、100Ωの抵抗器を使えばよいことになる。
(100Ωの抵抗器ぐらい手持ちにあるだろうと高を括っていたら持ってなくて、結局47Ω+47Ω+10Ω=104Ωの組み合わせを用意する羽目になったというオチ)

なお、上記サイト曰く、「Raspberry PiのGPIOを使う場合、回路の中の電流はどこも16mAまでにする必要が」あるらしいので、20mAでは厳密にはオーバーしているのだが、回路的に余裕を取ってあるはずだし、LEDが発光するのは一瞬だけなので無視することにする。心配な場合は150~200Ωの抵抗器を使えばいいと思う。

あと、LEDを複数個設置する場合は繋ぎ方にも気をつけること。といっても、並列にしてそれぞれに抵抗器を繋ぐだけでよさそうだけども。

 

実際に接続してみる


注文していたLEDと受信モジュールが届いたのでテスト。

事前の計算通り、104Ωの抵抗を噛ますことでLEDの点灯(いわゆるLチカ)はできた。
ただ、受信の方は参考元記事の通りに設定しても全然反応しない。GPIOを変えてみたり、モジュールの仕様の問題かと思いここを参考に抵抗を噛ませてみたけどダメ。ここで丸半日が潰れた。

remo_cons.jpg
画像:テストの為に駆り出されたリモコン達

結局、Raspbianのバージョンアップに伴いLIRCの設定方法が変わっていることが分かり、下記サイトを参考に手を加えることで受信に成功した(多謝!!)

Raspbian Stretchで LIRC機能を使った学習リモコン、赤外線リモコンを動かす方法 (Raspberry Pi Raspbian Stretchで赤外線リモコンの制御アプリ LIRC 0.9.4cの設定方法)

lirc_received.png
画像:成功時のSS

後はirrecordコマンドで信号を記録するだけ・・・と思っていたのだが、記録時に「Signal is too long」とエラーが出てしまい失敗。室内灯のリモコンの場合は上手く行ったので、メッセージの通りエアコンは信号が長すぎてLIRCでは対応していない様子。

 

LIRCはあきらめましょう


上で紹介したサイトには

検索で出てくる他のラズパイ記事で「LIRCはあきらめましょう」と有りますが、私の環境ではラズパイ3と Raspbian Jessieの組み合わせで LIRCを無事に動かせました。

とあり、私の環境でもラズパイ3とRaspbian ScratchでLIRCを動かせたのだが、LIRCはそもそもエアコンを動かす用途には向いていないということが分かった。そうなれば進路変更をせざるを得ない。「LIRCはあきらめましょう」。

そこで見つけたのが下記サイトだ。

赤外線学習リモコン―赤外線信号送信・受信(改) | Feijoa.jp

 

結果から言うと、このサイトで紹介されている「赤外線信号受信プログラム」「赤外線信号送信プログラム」を使用することで、エアコンの赤外線信号を送ることができた。特に難しいテクニックは不要で、上記サイトに書いてあるとおりの手順で問題なかった(こちらも多謝!!)。

ただ一点、ピンを指定する際はRaspberry Pi のピン番号でもGPIO番号でもなく、WiringPiのピン番号でであることに注意。WiringPiをインストールした後、

gpio readall

コマンドでピンの対照表が表示されるので要確認。

あと、LIRCを使用する際は赤外線LEDを負論理で接続(+が3.3v、-がGPIO)していたが、このプログラムを使う場合は正論理(+がGPIO、-がGND)で接続をする必要があるので注意。

 

繋がりはしたが・・・


各参考元サイトで記載があったが、今回購入した赤外線LEDは指向性が強く、かなり厳密に向きを決めてやらないと反応しない。一般的なリモコンに搭載されているLEDとは根本的に違うのだろう。

LEDにゴムを被せて光を拡散させる方法もあるが、試してみたら飛距離が落ちすぎて使い物にならなくなったため断念。

ラズパイの位置を固定し、ピンポイントでエアコンの受光モジュールにヒットするように配置した(ズレたときが怖いが)

rasp.jpg
画像:ユニバーサル基板に乱暴に取り付けられたモジュール達。この後基盤ごと輪ゴムでラズパイに括り付けられた。

配置に伴い、HDMIケーブルが太くて邪魔だったので取り外すことに。ラズパイにxrdpをインストールしてリモート接続するようにした。

 

外部から操作したい(discordrb)


ここまでで当初の目的は半分達成したが、本来の「外部からエアコンを操作する」を達成する為にはDiscordと連携させる必要がある。

DiscordのBotをRaspberry Piでポストするまでのメモ - Qiita

上記サイトを参考に、discordrbを導入することに。

しかし、rvmインストール時に、「公開鍵がありません」でコケる。

エラーメッセージに書いてある

gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

を叩くも、GPG2が入っていないと言われる。

Ubuntu - Install GPG 2 | Programster's Blog

ここを参考にgnupg2をインストール。

したら今度は

gpg: failed to start the dirmngr '/usr/bin/dirmngr': そのようなファイルやディレクトリはありません
gpg: connecting dirmngr at '/run/user/1000/gnupg/S.dirmngr' failed: そのようなファイルやディレクトリはありません
gpg: keyserver receive failed: dirmngrがありません

と怒られる。下記サイトを参考に、dirmngrをインストール。

How to fix missing dirmngr

これでようやく

gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

が通り、rvmがインストールできた。

あとはRuby 2.1.5をインストール。

ruby.png
画像:インストール(というかコンパイル)がファッキン時間かかる。

gem install discordrb
Rubyのインストールが終わったら、上記コマンドでdiscordrbをインストール。あとはサンプルコードを実行すれば、discordrbが起動する。

 

Discord側の設定とbotによる操作

Discordのbot追加方法についてはこちらを参考にした。

DiscordのBotを作ってみよう! | 東京工業大学デジタル創作同好会traP

Discord側の設定は上記サイトの通りのため割愛。初めTokenの取得方法が分からなかったが、「Create a Bot User」ボタンを押すことで取得できた。

あとはDiscordサーバーに追加したbotに話しかけることで、任意のコマンドが実行できるようになった(本当に任意のコマンドが実行できてしまうので注意)。

discord.png
アイコンをマスクしているので分かり辛いが、botに対してDMを送ることでコマンドを実行する。

ラズパイ側の実行ログはこちら。
discordrb.png

参考元サイトのサンプルコードを元に、エラー時のメッセージ表示や実行結果の返信、特定のユーザーのみ実行可能にするなどの手を加えた。
参考に、今回作成したRubyコードを以下においておく。

discordrb.txt
evalといいつつSystem関数を使用しているため、本当にどんなコマンドでも実行できてしまうため注意。

 

まとめ


Raspbian ScratchになってLIRC周りの仕様が変わっているが、適切な設定を施すことでLIRCを使用することは可能。ただし、LIRCは64bitまでのコードにしか対応しておらず、エアコンでは使えない事が多く適していない。
エアコンはリモコン信号が長いためLIRCで扱えない可能性が高いです(機種によると思いますが)。具体的にはLIRCで扱えるのは64bitまでですが、うちで使用しているエアコンの信号は80bitとか144bitだったりしています。
(参考:Raspberry Pi で赤外線リモコン - 猫ぱーんち!

そのため、今回はFeijoa.jpで提供されているプログラムを使用した。このプログラムは送信回数などの細かい設定ができるため、LIRCより使い勝手の面でも優れている。

そこから先は、Slack Outgoing WebHooks、Discord botなど、外向きにアクションを行うことができるプロトコルを好みに合わせて選ぶことができる。httpサーバーでもよいが、セキュリティ面を考えるとサードパーティーのAPIを活用したほうが良さそうだ。

 

補足


今回はdiscordrb側に汎用性を持たせる為、Linuxコマンドをそのまま入力する仕様にしたが、セキュリティ的にも使い勝手的にもあまり宜しくない。可能であれば処理ごとに専用のコマンドを作成し、コマンドの簡略化&想定外の動作を防ぐ必要がある。
しばらく使用してみて、特に問題がなければそのようにする予定。だけど、面倒なので結局そのままになる可能性も十分にある。
あと、赤外線LEDの認識率についても疑問が残る。「赤外線信号送信プログラム」で1回だけ送信した場合はそこそこの認識率だが、取りこぼしがあるため10回連続して信号を送るように変更したら、そのうち2,3回ぐらいしか認識しない(たまに10回全部失敗する)。ソースをいじってusleepの値を増やしてみたが変わらず。

なお、起動時にdiscordrbを起動する場合は、こちらを参考にLXDEのautostartに

@lxterminal -g ruby "/home/pi/bot.rb"

と追加してやればいい(処理結果をターミナル画面に表示させる為、あえてlxterminalを起動している)。


 

ちなみに

同様の機能を持つ既製品はいくつかある。

手軽に同様の機能が欲しければ検討する価値は十分にある(エアコンに対応しているか等のスペックについては不明)。

また、単純に電源をON/OFFしたいだけなら、こういう既製品も存在する。

スマホアプリと連動して、コンセントの電源を入れたり切ったりすることができる。
ヒーターのような大量に電力を消費する機器に使う場合、最大アンペア数が15Aあるこっち↓の方がいい。

ただ、本当に電源のON/OFFしかできないので、電熱ヒーターやホットカーペット等、電源オン即動作する機器でないといけない。
(エアコンのようにリモコン操作が必須の機器は、本記事のように赤外線操作が必要になる)

一見使い勝手が良さそうで、案外ヒーターぐらいしか使い道が無いのが玉に瑕。

コメントする