2012年8月22日水曜日

エアコンのWeb UIを作った

エアコンのリモコンとか作った そのご。

Arduino IDE のシリアルモニタからしか操作出来ないのはつまんないのでUIを作ったの巻。
  1. Arduinoに赤外線LEDと温度センサーを繋げて
  2. Ubuntuに接続して
  3. PHPでWebインターフェイスを作った
という話です。

ハードウェア


  • Arduino UNO R3
  • 赤外線LED : OSI5LA5113A
  • 温度センサー : LM61CIZ
  • UbuntuがインストールされたPC

前回まではWindowsで作業していたのですが、WebサーバはUbuntuで動いているため今回はそちらで。
温度センサーの LM61CIZ は、-30℃ ~ +100℃ を 300mV ~ 1600mV で出力します。

スケッチ


温度を常時出力しながらシリアルの入力 (リモコン信号送信指示) を待ちます。
void loop() {
  digitalWrite(PIN_IR_OUT, LOW);
 
  if (Serial.available()) {
    int c = Serial.read();
    for (int i = 0; i < signalMap[i].chr != '\0'; i++) {
      if (signalMap[i].chr == c) {
        sendSignal(signalMap[i].signal);
        Serial.println("send");
        break;
      }
    }
  } else {
    // analog input value
    float aIn = analogRead(PIN_ANALOG_IN);
   
    // input voltage (mV)
    float vIn = (5000 * aIn) / 1024;
   
    // temperature (C)
    float t = (vIn - 600) / 10;
   
    Serial.println(t);
  }
 
  delay(1000);
}

ArduinoをUbuntuに接続


ドライバとかは不要です。USBケーブルを挿すだけなのでお手軽。
screen /dev/ttyACM0 9600
でシリアル通信を確認。

PHPでWebインターフェイスを作る


はじめに作ったものはこんな感じでした。

やっつけ感が溢れる

機能は、温度を表示し、エアコン ON/OFF の指示を受け付けるだけです。

シリアル通信には php-serial という ライブラリを使いました。
通常 Apache のユーザは /dev/ttyACM0 などへはアクセス出来ないと思います。
サーバの運用ポリシーに合わせて対処を考える話ですね。

さて、これでやってみたかったことは一通り出来ました。
帰宅3分前にスマートフォンで室温を見て「うわー;´д`) 」って思ったらエアコンをつけておく、なんてことも可能です!……が、スマートフォンで見てみると悲惨なことに (左上に小さく表示) なったので jQuery Mobile を使ってみました。
いい感じ

3 件のコメント:

  1. はじめまして。
    私も最近Arduinoに興味を持ち勉強しているものです。
    taqpanさんと同じようにArduinoをブラウザを通じて命令を送りたいと思っています。
    良かったら詳細をおしえていただけないでしょうか?

    返信削除
    返信
    1. はじめまして。
      かなり端折りすぎで何が何だか分からない記事ですね。。。 記事を補足する形で書かせて頂きます。参考になれば幸いです。

      直接Arduinoを操作しているのは、Arduino IDE付属のシリアルモニタと同様に(USBを通した)シリアル通信です。
      ブラウザやWEBサーバのことを考える前に、まずは手打ちのシリアル通信でArduinoを操作できるようにしています。(記事中の"ArduinoをUbuntuに接続"まで)

      スケッチの"signalMap"は、シリアル入力の文字と、それに対するリモコン操作(LED点滅)ルールを構造体の配列で定義したものです。

      そしてArduinoのシリアルモニタを使わず汎用的なコンソールでArduinoとシリアル通信を試みているのが "ArduinoをUbuntuに接続" の節です。
      ここは試すだけなので、screenで /dev/ttyUSB0 か /dev/ACM0 など(USBシリアルドライバ次第)に接続すれば用は足ります。WindowsならばUSBシリアルに割り当てたCOMポートにTeraTermなどを使って接続すればいいと思います。

      無事にPCからの文字入力でArduinoを操作できるようになったら、WEBのことを考えます。

      WEBサーバはApache, アプリケーションはPHPで作成しました。オーソドックスな Linux + Apache + PHP の構成です。
      記事にもある php-serial というライブラリを使えば、上記の手動で試したシリアル通信をPHPから実行することは容易かと思います。
      例)
      $serial = new phpSerial();
      $serial->deviceSet("/dev/ttyACM0");
      $serial->confBaudRate(9600);
      $serial->confParity("none");
      $serial->confCharacterLength(8);
      $serial->confStopBits(1);
      $serial->confFlowControl("none");
      $serial->deviceOpen();
      $serial->readPort(); // clear buffer from Arduino
      $serial->sendMessage('c');
      $serial->deviceClose();

      問題はApacheのユーザ権限でどうやってシリアル通信を行うか、ということです。
      Apacheユーザに /dev/ACM0 へのRead/Write権を与えるのであれば問題は解決、WEBアプリのコードから直接Arduinoと通信できると思います。(私はやっていませんが)
      私はApacheユーザにそのアクセス権を与えるのは嫌だったので、WEBアプリ自身がシリアル通信する方法は取っていません。代わりに以下の方法で命令を送っています。

      1. WEBリクエストに応じて特定のパスにArduinoへ送る命令が書かれたファイルを出力。
      2. WEBアプリとは別のPHPスクリプトが cron から起動。(毎分)
      3. 2.のスクリプトが、1.のファイルを読んでArduinoへ送信。

      この2.のスクリプトは、普段自分がLinuxへログインするユーザの権限で実行しています。
      またArduinoから気温が毎秒出力されていますが、それも1分ごとにcronで起動するプロセスが読み取ってファイルに書き出し、それをWEBアプリが表示しています。

      このような構成なので、実際にはWEBアプリは、ただファイルを読み書きするだけのものになっています。

      削除
    2. 返信ありがとうございます。
      参考にして頑張って作ってみようと思います。本当にありがとうございます。

       これから定期的に訪問させていただきますので、記事の更新楽しみに待っています。

      削除