うっかりエンジニアのメモ

未来の自分に宛てたメモ

twitterでエアコンの電源on/off

日本の夏。暑すぎる。

帰ってきてドア開けた時の「もわっ」っていう熱気。しんどい。

このしんどさを減らすべく、帰宅30分前くらいにエアコン付けられたらいいなぁということで、Twitterで自分宛てに命令をつぶやいて自宅のエアコンをon/offするような仕組みを作りました。

つくったもの

  • 赤外線を送受信する電子回路
  • 赤外線を受信して記憶するArduinoスケッチ
  • Twitterのつぶやきに応じて赤外線を送信するArduinoスケッチ

ソースコードはgistに公開しています。(記事下部に埋め込んであります)

必要なもの

Arduino UNO R3 (参考市価: 3,000円)

Ethernetシールド(参考市価: 4,700円)

各種電子部品

  • 赤外線LED OSI5LA5113A
  • 赤外線受信モジュール OSRB38C9AA
  • OSRB38C9AA
  • 抵抗 47Ω
  • ジャンパワイヤ沢山
  • USBケーブル
  • LANケーブル

開発用マシン: MacBook Pro(Mac OS X 10.9.3)

エディタはsublime text 2です。
StinoというArduino開発向けプラグインが最高です。

配線

配線図は後ほど公開します。
以下のように部品とピン番号が対応しています。特にこの番号である必要はないです。

  • 赤外線LED 2番
  • 赤色LED 5番
  • タクトスイッチ(デバッグ用に赤外線を送信するため) 6番
  • 赤外線受信モジュール 7番

ただし、公式ドキュメントにあるようにArduino UNOでは10-13pinは使えないので注意。

Arduino communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega. On both boards, pin 10 is used as SS.

Arduinoスケッチ

マイコンに書き込むプログラムは以下の2つです。

  • リモコンの赤外線を受信して記憶するArduinoスケッチ
  • Twitterのつぶやきを一定時間おきに確認して、テキストに応じて赤外線を送信するArduinoスケッチ

ほんとは同時にできるといいのですが。

リモコンの赤外線を受信して記憶するArduinoスケッチ

橋本商会で有名な橋本翔さんのこちらのソースコードを若干改変させていただきました。

全然関係ない話ですみません、橋本翔という同姓同名の小学生の同級生がいるので驚きました。彼は地元で居酒屋を開業しているはずなので、タンジブルテバイスの研究に携わっているはずがなかった。

Twitterのつぶやきに応じて赤外線を送信するArduinoスケッチ

以下の記事を参考にしました。

赤外線リモコンの通信フォーマット

参考記事によると、フォーマットは3種類あります。

  • NECフォーマット
  • 家製協フォーマット
  • SONYフォーマット

うちのエアコンは日立製なのでSONYフォーマットはありえないとして、NECフォーマットか家製協フォーマットかは、実際にリモコンが送信するコードを調べてみないことにはわかりません。

赤外線を受信するスケッチをArduinoに書き込んで、エアコンの起動ボタンを押して受信モジュールで記録したコードを見てみます。

340,161,48,120,48,35,48,35,48,36,48,36,48,36,...(省略)

送っているコードのonの長さとoffの長さが交互に並んでいます。単位は10μsです。

どちらのフォーマットであっても最初の2つのコードはleader code(これからデータを送信しますよ、というのを受信側に伝えるためのコード)なので、この送信時間をもとに判別することにします。

**** NECフォーマット 家製協フォーマット
T 562μs 425μs
リーダコードのonの長さ 16T (= 8992μs) 8T (= 3400μs)
リーダコードのoffの長さ 8T 4T

一目瞭然。onの長さがぴたり一致したので、エアコンは家製協フォーマットでした。

赤外線でデータを送信する

赤外線リモコンの通信フォーマットはよく考えられていて、単純に赤外線が飛んできたら1、飛んでない時は0という表現ではありません。 というのも、赤外線はリモコンだけでなく様々な物体が発しているため、すべての赤外線に反応した場合、リモコンから送信される赤外線はそれらノイズに埋もれてしまい、正常に動作することはかないません。

そこでノイズ対策として、38kHzで赤外線を高速に点滅させてデータを表現する方式になっているようです。まず38kHzで一定時間送信された場合がon、一定時間何も送信されない場合がoffと定義されています。そして家製協フォーマットの場合、1T(=425μs)のonのあと1Tのoffが連続した時1、1Tのonのあと3T(=1275μs)のoffが連続した時0という具合です。

38kHzで赤外線を点滅させる

これが辛い。1/38kHz ≒ 26.3μsということはおおよそ半分の13μsごとにon/offを変えればいいと思うのですが

digitalWrite(PIN_IR_OUT, HIGH);
delayMicroseconds(13);
digitalWrite(PIN_IR_OUT, LOW);
delayMicroseconds(13);

とかやっても、エアコンはぴくりとも反応しません。
なんでかなーとwebを彷徨うとこんな記事が。

Arduinoの高速化 | なんでも独り言

digitalWrite命令は実行に44サイクル掛かるらしいです。Arduino UNOのCPUクロックは16MHzであることを考えると、44/16MHz = 2.75μsなので、2回のdigitalWriteで5.5μsのずれということになります。なかなか無視できない数値だと思います。

そこで、同じ記事中で紹介されていたレジスタ操作を利用したピンの状態変更を採用しました。この方法ならピンのon/offに掛かる時間は3クロックに大幅に短縮されます。実際、13μsずつのdelayでうまくいきました。

twitterのつぶやきを取得する

赤外線送信部分が実装できたら、あとはtwitterのつぶやきを取得する部分です。
TwitterREST APIを公開しているので、HTTPでレスポンスを受け取ることができれば何とかなりそうです。

ここでTwitter APIを利用するためにOAuth認証というものが必要になりますが、 このOAuth認証はなかなかリソースを食うのでArduinoの貧弱なハードには荷が重いです。

そこで、どこか外部に丸投げしようと思っていたら、素晴らしいサービスがありました。

StewGate Uはひとことで言うと、Twitter APIのプロキシサービスです。アプリ登録時にStewGateがトークンを発行してくれるので、以後そのトークンとTwitterへの命令をセットにしてStewGateのサーバにリクエストを送ると、StewGateが代わりにTwitter APIからデータを取得してこちらに返してくれます。

そしてStewitterは@arms22さん作の、Arduino向けにTwitterアクセス機能を提供するライブラリです。もちろんStewGate Uを内部で利用しています。

さて、Twitterからtweetを取得しましょう。
実はStewGate Uの制約で、2014/8現在実行できるアクションは「ツイートを投稿する」か「自分宛ての最新のmentionを取得する」の2つのみとなっています。おうふ。

ということで自分宛ての最新のmentionを取得して、自分が自分宛てに「on」とつぶやいていたら、エアコンを起動するように実装します。この辺りはソースコードを見てください。フォロワーが自分宛てに「on」とつぶやいてエアコンを起動できることがないように注意。

また、Twitter APIはrate limitといって、時間あたりのAPI問い合わせ回数に制限を設けているのでこちらも注意します。StewGate Uの内部実装は公開されていませんが、おそらくmentionの取得はTwitter APIGET statuses/mentions_timelineで行われているので、15分辺り15回が制限値です。つまり、mentionを確認する頻度が毎分1回を超えないようにします。

このスケッチのソースコード

ということで実装したソースコードがこちらです。
Stewitterのトークン(Stewitter twitter("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");)は適宜変更してください。

ハマったこと

赤外線送信時に終端コードの送信を忘れない

こんなのハマるの私だけかもしれませんが。。
家製協フォーマットは終端コードが定義されているんですね。なので、全てのデータを送信した直後に '1'を1回送信する必要があります。実装中にこれを忘れてしまい、一向にエアコンが反応しないことがありました。

赤外線LEDの角度が意外とシビア

ほんのちょっとでもエアコンの受光部から外れると信号が届きません。どうやら許容角度が5度くらいらしいです。
こういうLEDキャップ買うと許容角度が拡がるらしいので今度アキバ行ったら秋月で調達しておこう…

現状の課題

帰宅前にtwitterでつぶやくのを忘れる。

人間が一番信頼性低いっていう。
iPhoneGPSと連動させるくらいしないとダメですね。

おつかれさまでした。