繼上一回BTCom Project--用Android手機傳送命令(簡訊)到Arduino板子後。這一回,我們要讓Arduino根據我們手機傳送的命令作動作,而最簡單的方式就是控制電源開關。
假設家裡有電視(TV)、音響(Sound)、房間燈光(Room)與電扇(Fan)想要透過手機App遙控開關。為了延用之前的藍芽簡訊程式 BTCom,我們必須先定義Android與Arduino的通訊協定(Protocol),就是讓Arduino看懂我們的指令(Instruction)。
硬說是通訊協定,也沒那麼偉大,簡單說就是從手機傳給Arduino的指令格式,定義為:
<DeviceName><逗號><ON/OFF>
其中<DeviceName>可以是 {tv, sound, room, fan} 其中一個。例如,想要開啟電視,我們傳送的指令為「tv,on」;相反地,「tv,off」指令會把電視關掉。這樣子的用法,設計者可以設計自己專屬的指令格式,而且可沿用之前開發的Android App,並保持未來做更複雜控制指令的彈性。當然,設計者也可以使用不同的按鍵(Button)對應不同的命令,但App的用途就受到限制(不能Reuse)。
實作的部分則偷懶一下,用四顆LED燈泡表示欲被遠端手機App遙控的電器設備。實際運作則需搭配繼電器(Relay),此時驅動LED燈泡的訊號則接至繼電器的訊號端。
可以的話直接買多路的繼電器開關比較划算,可以控制較多的家電。以下BOM表參考一下,以後建商或室內設計師跟你吹牛說送你的「智慧家電控制中心」多高貴,那肯定是騙很大! (若是在大陸製造,成本可以控制在100塊人民幣以內)
BOM表
項目
|
台灣
|
淘寶(不含運費)
|
Arduino UNO R3
|
450台幣
|
12~40人民幣
|
Bluetooth HC-06
|
350台幣
|
17~30人民幣
|
單路
|
90~180台幣
|
3.5~12人民幣
|
4路
|
195台幣
|
13~24人民幣
|
MIT AI2 Companion (Android)
|
Free
| |
MIT App Inventor 2 (Windows)
|
Free
|
BTCom: Android程式規劃
不過這支App會被Android手機歸屬於來路不明的程式,安裝前請先將安全性設為允許不明來源的安裝,請放心! 不會收集用戶端資訊的! 安裝完成請記得取消允許不明來源的安裝,以免產生安全漏洞。
BTCom: Arduino Uno 端程式規劃
Arduino BTCom範例程式:
#include <SoftwareSerial.h>
#define MAX_BTCMDLEN 128
#define BTSW_TV 7 // pin7 當 BlueTooth Switch for TV
#define BTSW_Sound 6 // pin6 當 BlueTooth Switch for Sound
#define BTSW_Room 5 // pin5 當 BlueTooth Switch for Room
#define BTSW_Fan 4 // pin4 當 BlueTooth Switch for Fan
// 建立一個軟體模擬的序列port
SoftwareSerial BTSerial(10,11); // HC-06/TX-->PIN10(Arduino/RX), HC-06/RX-->PIN11(Arduino/TX);
byte btCmdBuff[MAX_BTCMDLEN]; // up to 128 bytes BT command received from the Android system
int btCmdLen = 0; // received BT command length
void setup() {
//Serial.begin(9600); // serial port for debugging
BTSerial.begin(9600); // 建立藍芽軟體串列埠
pinMode(BTSW_TV,OUTPUT); // 設定電視開關
pinMode(BTSW_Sound,OUTPUT); // 設定音響開關
pinMode(BTSW_Room,OUTPUT); // 設定房間開關
pinMode(BTSW_Fan,OUTPUT); // 設定風扇開關
digitalWrite(BTSW_TV,LOW);
digitalWrite(BTSW_Sound,LOW);
digitalWrite(BTSW_Room,LOW);
digitalWrite(BTSW_Fan,LOW);
}
void loop() {
listenBTCmd();
//showBTCmd(); // for debugging
executeBTCmd();
}
void executeBTCmd() {
char cmd[MAX_BTCMDLEN];
if ( btCmdLen>0 ) {
sprintf(cmd,"%s",btCmdBuff);
//Serial.println(cmd);
if ( strcmp("tv,on",cmd)==0 ) {
digitalWrite(BTSW_TV,HIGH);
}
if ( strcmp("tv,off",cmd)==0 ) {
digitalWrite(BTSW_TV,LOW);
}
if ( strcmp("sound,on",cmd)==0 ) {
digitalWrite(BTSW_Sound,HIGH);
}
if ( strcmp("sound,off",cmd)==0 ) {
digitalWrite(BTSW_Sound,LOW);
}
if ( strcmp("room,on",cmd)==0 ) {
digitalWrite(BTSW_Room,HIGH);
}
if ( strcmp("room,off",cmd)==0 ) {
digitalWrite(BTSW_Room,LOW);
}
if ( strcmp("fan,on",cmd)==0 ) {
digitalWrite(BTSW_Fan,HIGH);
}
if ( strcmp("fan,off",cmd)==0 ) {
digitalWrite(BTSW_Fan,LOW);
}
}
}
void listenBTCmd() {
char tmp;
btCmdLen = 0;
memset(btCmdBuff,0,MAX_BTCMDLEN);
while( BTSerial.available()>0 ) {
if( (tmp=BTSerial.read())=='O' ){
btCmdLen = 0;
}
btCmdBuff[(btCmdLen++)%MAX_BTCMDLEN] = tmp;
}
}
void showBTCmd() {
char cmd[MAX_BTCMDLEN];
if ( btCmdLen>0 ) {
sprintf(cmd,"%s",btCmdBuff);
Serial.println(cmd);
}
}
|