Androidを使った実験として、今度はネットワークからの制御をしてみました。
我が家は普通のコンセントから繋いだ間接照明を利用してる為、それに使用することで、世界中誰でもブラウザで私の部屋の照明をオンオフしやがれって企画です。
Twitter等で告知して公開実験したときの特設サイト↓
手書きのラフなブロック図ですが、下記の通りとなります。
- ハードウェア&Arduino
コンセントのオンオフはリレーで行います。
リレーにはomron製G5CA-1A(5VDC入力 耐圧10A 200VAC)を使用しました。
Arduinoからコイルの直接駆動は厳しいので、トランジスタ(2SC1815)で駆動します。ベース抵抗に3K程度。
これであとは普通にArduinoのIOをoutputにし、HIGH/LOWさせればコンセントの電源をオンオフできます。
Arduinoのソースはこちら
—–
#include <LiquidCrystal.h> const int analogOutPin = 9;//LED PWM出力ピン const int relay = 13;//リレー用ピン int sensorPin = A0;//CdS入力ピン int sensorValue = 0; int outputValue = 0; int temp = 0; char sRead; char cnt=0; int reflesh=100;//LCD 照度更新レート int frame=0; //LCD設定 LiquidCrystal lcd(11, 12, 2, 3, 4, 5); void setup() { //IO初期化 pinMode(relay, OUTPUT); digitalWrite(relay, LOW); //シリアル初期化 Serial.begin(115200); //LCD初期化 lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print("Input :"); lcd.setCursor(0, 1); lcd.print("Output:"); } void loop() { //シリアル受信 //LED輝度調整とリレーオンオフを兼用 if (Serial.available()){//受信データ有り sRead = Serial.read(); if(sRead=='B'){//LED最大輝度 analogWrite(analogOutPin, 255); digitalWrite(relay, HIGH);//リレーオン }else if(sRead=='N'){//LED普通輝度 analogWrite(analogOutPin, 50); }else if(sRead=='D'){//LED暗め analogWrite(analogOutPin, 20); }else if(sRead=='O'){//LEDオフ analogWrite(analogOutPin, 0); digitalWrite(relay, LOW);//リレーオフ }else if(sRead=='R'){//CdS情報リクエスト VRout(); } if(!cnt){ lcd.setCursor(7, 0); lcd.print(" "); } if((sRead!='\r')||(sRead!='\n')){//デリミタ受信時LCD書き換え lcd.setCursor(7+cnt, 0); lcd.print(sRead);//受信データ表示 cnt++; } if((sRead=='\n')||(cnt>9)){//LCDは9文字目まで cnt=0; } } if(frame >= reflesh){ sensorValue = analogRead(sensorPin);//CdS読み取り outputValue = sensorValue/4;//10bit→8bit if(outputValue !=temp ){ lcd.setCursor(7, 1); lcd.print(" "); lcd.setCursor(7, 1); lcd.print(outputValue);//LCDにCdS値表示 temp = outputValue; } frame=0; } frame++; delay(2); } void VRout(){ Serial.println(outputValue);//CdS値をシリアル送信 }
—–
- Android
Arduinoの制御は前回記事同様にAndroid側にFTDriverを使わせていただいてUSB接続しています。
ついでに前回の名残でArduinoで取り込んだCdSセルの照度をサーバーに送信してますので、そちらも部屋の明るさログとして流用しました。
20秒毎にサーバーにアクセスするポーリング方式です。GCM APIを使えばPUSH送信のシステムも組めるようですが、今回は手っ取り早く済ませました。
Androidのソースは現在ひどい状態なので勘弁してください。
- サーバー
Androidからアクセスする先のサーバーに置いてあるperlソースはこんなかんじです。
—————————————————-
#!/usr/local/bin/perl #POST送信されたデータを受け取る if ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'}); } else { $alldata = $ENV{'QUERY_STRING'}; } foreach $data (split(/&/, $alldata)) { ($key, $value) = split(/=/, $data); $value =~ s/\+/ /g; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg; $value =~ s/\t//g; $in{"$key"} = $value; } #status.txt(照明の状態)を読み込み open(IN,"status.txt"); @file = <IN>; close(IN); #log.txt(照度ログ)を上書き open(OUT,">log.txt"); print OUT $in{'message'}; close(OUT); #POST送信元(Android端末)へのレスポンス if(@file[0] == "1"){ print"On";#Androidに"On"を返答 }else{ print"Off";#Androidに"Off"を返答 } exit;
——————————
‘message’はAndroidからのアクセス時に照度情報を送ってlog.txtに書き込んでます。(実験中につき名前の付け方がおかしいのは気にしない方向で…)
照明のオンオフはstatus.txtに入ってる1か0の数字を読み取り、1のときはAndroidに”On”、0のときは”Off”を送信。
このstatus.txtをウェブブラウザのフォームで書き換えできる、という仕組みです。
Android側は受信した”On””Off”をもとにArduinoにシリアル送信して出力制御します。
- 所感
Twitter,facebook,mixiでページを公開し、2時間ほど実験してみましたが、時折、平均すると1,2分に1度ほどパチパチされました。
物理的に自分にアクセスされることは、ネット上でコメントなどやり取りするのともまた違った感覚があって面白い体験ができました。同時にすごく見られてる感じがして落ち着かなくもありました。
- 課題
問題点は、2時間程でスマホが再起動して動かなくなってたことです。やはりAndroidは手で持って運用することが第一で、固定して遠隔操作させるには安定性など不都合が面が多いことを実感しました。組み込み用などの為にウォッチドッグ機能とかあれば心強いのですが…
また普通に家で使うならArduinoにEthernetで繋げば早いので、そもそもAndroidを使う利点も薄くなってます。
今回のシステムについて、遠隔操作で他人に弄ってもらうのは面白いのですが、面白いのは9割方私自身だという事も弱点です。
せめて7割くらいにしようとUstreamで配信していましたが、演出として実に微妙です。フィードバックが弱い→すぐ飽きるのは致命的。
- 今後の改善案
・物理的に動かしたものをみんな楽しめる
→アコースティック楽器をモーター等で鳴らして、それをwebラジオ配信、BGMとして使えるレベルに仕上げる
・操作先が多人数の施設およびイベント
→ライブ中の照明コントロール、ライブカメラ移動、音色チェンジ等…
なにかそういうもので使えるといいかなと考えてます。
あまりに混雑しても意味不明になるので参加人数調整が必要だったり、同時に弄られたときの対処、その他リアルタイム更新のブラウザ画面とか、特にコンセプトとインターフェース周りは課題は色々ありますが、とりあえず今回はAndroid実験として色々学べたので良しとします。