2015年2月16日 星期一

Android 手機透過Bluetooth+Arduino 控制開關

用藍牙控制馬達這是已經十分常見的Arduino專題了:
(1) 首先在Android 上用 APP inventor 去發送藍牙的訊號,
(2) 然後 Arduino 接一個藍牙模組收到手機的訊號後,再命令使馬達動作。

嚴格來說這篇在技術上沒有什麼特殊焦點,
最主要展現的概念是,家用開關的自動化能不能直接疊上去?

當一般民眾不願意自己去拆帶有電流的開關時,
他能不能直接買一個「貼」上去?

當然這有點脫褲子放屁,要嘛就直接換一個手機可以控的開關就好。
例如有一個認識的朋友就在做這一類:
http://www.aengin.com/proinfo.php?id=4

但想到脫褲子放屁的不是只有我,你看看Lockitron
不是叫你換掉鎖,而是幫你再貼一個電子開關上去。
https://lockitron.com/ 

總之無線開關的需求是因為我窩在被窩裡不想起來關燈。
出遠門時天黑時,需要連上網打開家裡的電燈,或設定自動開燈的時間。

然後我也到kickstarter上看到類似相關的募資,用遙控器控制家用開關的

募資金額……0  (哀傷~~~)

所以我就放棄把機構改更好的動力了 (不然我是已經有新的機構的想法)。也不要建議我去做系統了,所有大的廠商都在做平台了 google nest、sentri、apple home skit、Samsung smarthome、小米…這是一個打群架的時代了,我們這種小人物能做的,只有小眾單品。

不過身為一位 Maker,做這樣的東西有時就只是為了趣味。我還是會把這樣的東西完成,自己做一個家裡的中控中心,開始用建置家裡的防火防盜Sensor與自動化系統。

---------------------------- 以下是做的過程與相關的筆記與參考資料---------------------------------
參考資料:
http://appinventor.mit.edu/explore/
http://blog.cavedu.com/programming-language/appinventor/appinventorandarduinowithbluetooth/
http://blog.cavedu.com/programming-language/appinventor/appinventorandarduinowithbluetooth2/

首先先上app inventor的網站註冊,在網路上直接寫程式,getting start的文章網路上很多,查一下就可以寫出來,我寫的內容如下:

再來把寫好的程式,用QR code顯示出來,用手機掃描之後,連上該網址下載該程式。安裝好之後就可以用了!手機上的畫面應該如app inventor所設定的一樣。

然後,再來做arduino的部分,藍牙也是用序列通訊RxD、TxD 連進 arduino的板子裡,可是因為arduino的板子原本RxD和TxD是要給待會從電腦進來的資料用,所以我們另外訂在別的Pin腳來做給藍牙幅換RxD和TxD。而在程式裡要用<SoftwareSerial.h>來協助換腳。另外再用<wire.h>來做真正的I2C通訊。實體接出來如下圖,Arduino部分用pro mini比較小一點

程式碼如下:
#include <SoftwareSerial.h>
#include <Wire.h>  
#include <Servo.h>         //引用三個函式庫 SoftwareSerial、Wire、Servo

SoftwareSerial I2CBT(10,11); //定義PIN10及PIN11分別為RX及TX腳位
Servo motor_1;                               //定義有幾個servo
Servo motor_2; 

void setup() {
   Serial.begin(9600);                       //Arduino起始鮑率:9600
   I2CBT.begin(9600);                     //BT boud rate (有的可能會不一定,要注意一下)
   motor_1.attach(3);
   motor_2.attach(5);
   motor_1.write(90);
   motor_2.write(90);
}

void loop() {
byte cmmd[20];
int insize;
while(1){
   if ((insize=(I2CBT.available()))>0){  //讀取藍牙訊息
      Serial.print("input size = ");
      Serial.println(insize);
      for (int i=0; i<insize; i++){
Serial.print(cmmd[i]=char(I2CBT.read()));
Serial.println(" ");
      } // get signal from BT 
   }
   switch (cmmd[0]) { //讀取第一個字
      case 97: //97為"a"的ASCII CODE
         motor_1.write(68);
         break;
      case 98://98為"b"的ASCII CODE
         motor_1.write(108);
         break;
      case 99://99為"c"的ASCII CODE
         motor_2.write(70);
         break;
      case 100://100為"d"的ASCII CODE
         motor_2.write(108);
         break;
   } //Switch
   } //while
delay (1000);
motor_1.write(90);
}

2 則留言: