想成為Maker,自然要從Single A (Arduino或Android皆可)進階至Double A (Android+Arduino)。今天要讓大家都學會用手機傳訊息到Arduino系統BTCom。
很多人想學Coding,各種程式語言千百種(國/英文都學不好了,還…),但不得其門而入。歐吉尚衷心建議: 跟著小學生的腳步學就對了! 別想一步登Maker! 不要想太多! 挑一個跟自己有緣的(符合自己目標需求、提供模組多的、自己會想Try看看的)工具,然後動手去Try就對了! 例如: 歐吉尚目標很明確,就是要用Android手機控制家電、遙控汽車、機器人、飛行器與一些監控器等。因此歐吉尚的第一支Double A程式,就設定為讓Android與Arduino透過Bluetooth(藍芽)通訊。
為什麼選Bluetooth? 因為逛電器行時,發現他跟我很有緣,我第一眼就喵到(我買串列埠界面的的,350元台幣,淘寶約17~30人民幣)。同時間也喵到超聲波感測器,心想,我未來的遙控飛行器應該要自動避開障礙物,…於是就直接全部打包回家了!
既然是第一支Double A程式,當然就得是「Hello World!」。只是這次是希望能從Android手機送出「Hello World!」訊息,透過藍芽,讓遠端Arduino的序列埠監控器秀出來!
BOM表
項目
|
台灣
|
淘寶(不含運費)
|
Arduino UNO R3
|
450台幣
|
12~40人民幣
|
Bluetooth HC-06
|
350台幣
|
17~30人民幣
|
MIT AI2 Companion (Android)
|
Free
| |
MIT App Inventor 2 (Windows)
|
Free
|
藍芽模組建議買內建串列埠的,因為接腳數少,Programming也較簡單。不過買的時候千萬注意型號,市面上好像有HC-05、HC-06與HC-07等,出廠設定的鮑率(Baud Rate; 每秒所送信號變化的次數)好像不太一樣。可別像歐吉尚,買回來後,很高興的照著課本Step-by-step,但始終無法成功。萬念俱灰下才發現,原來課本用的是HC-05,而我買的竟然是HC-06! (昏倒)
HC-06 藍芽模組
HC-06和Arduino的腳位對應:
HC-06藍芽模組(串列埠)
|
Arduino Uno Pin
|
VCC
|
5V
|
GND
|
GND
|
TXD
|
Pin 10 (RX)
|
RXD
|
Pin 11 (TX)
|
BTCom: Android 程式規劃
Android手機App的介面應該要包涵: 搜尋/連接藍芽裝置的選單、斷線、訊息傳送窗等原件(Button)。其中,訊息傳送窗希望能包涵提示標籤(Label)、文字輸入盒(TextBox)與傳送按鈕(Button)。而AI2新增的元件佈局(Layout)功能,剛好符合需求(使用Vertical/Horizontal Arrangement)。
腳本的安排: 利用AI2內見的藍芽模組,將搜尋到的藍芽裝置以清單列顯示,以讓使用者選擇,此時其他功能選項呈失效狀態。待使用者選擇適當的藍芽裝置(如HC-06)以後,將搜尋清單列按鈕失效,並致能其他功能選項,讓使用者可以輸入。
建立/初始化欲傳送的訊息字btCommand,設定當傳送鈕(Send)被敲下時,將訊息編輯盒(TextBox)的內容存入串變數btCommand,並透過藍芽裝置傳送。直到斷線按鈕被敲下,再致能搜尋清單列按鈕,並讓其他功能選項失效。
拼圖(Coding)完後,選擇BuildàApp (provide QR code for .pak),AI2完成編譯並產生QR Code。
如果懶得寫程式可以使用下面QR Code下載,若有Bug煩請告知,感恩!
BTCom: Arduino Uno 端程式
利用Arduino的序列埠模擬函式(SoftwareSerial)來建立與HC-06的串列通訊,使用者無須了解底層的藍芽通訊協定,只要把它當一般的串列埠就可以了! (現在的小孩寫程式好幸福啊,不但需要的函式庫都有了,連Bluetooth轉串列埠的功能,廠商都很有默契似的把它內建了!)
由HC-06擷取訊息,顯示訊息及輸入指令的工作都交給Arduino的序列埠,使用者也可以由Arduino將指令透過我們自訂的腳位寫回HC-06(不過我只用原廠設定)。因為HC-06的鮑率(Baud Rate)出廠設定為9600bps,跟我預設的串列埠監控器一樣慢,這可能使得每次傳送的訊息被切割成數筆藍芽串列埠資料的讀取,因此我用了多讀了幾次到FIFO(我只Create 128 Bytes,應該夠用來控致許多終端設備了)。
Arduino BTCom範例程式: 用串列埠顯示結果
#include <SoftwareSerial.h>
#include <Wire.h>
// the maximum received command length from an Android system (over the bluetooth)
#define MAX_BTCMDLEN 128
// 建立一個軟體模擬的序列埠; 不要接反了!
// HC-06 Arduino
// TX RX/Pin10
// RX TX/Pin11
SoftwareSerial BTSerial(10,11); // Arduino RX/TX
byte cmd[MAX_BTCMDLEN]; // received 128 bytes from an Android system
int len = 0; // received command length
void setup() {
Serial.begin(9600); // Arduino起始鮑率:9600
BTSerial.begin(9600); // HC-06 出廠的鮑率:每個藍牙晶片的鮑率都不太一樣,請務必確認
}
void loop() {
char str[MAX_BTCMDLEN];
int insize, ii;
int tick=0;
while ( tick<MAX_BTCMDLEN ) { // 因為包率同為9600, Android送過來的字元可能被切成數份
if ( (insize=(BTSerial.available()))>0 ){ // 讀取藍牙訊息
for ( ii=0; ii<insize; ii++ ){
cmd[(len++)%MAX_BTCMDLEN]=char(BTSerial.read());
}
} else {
tick++;
}
}
if ( len ) { // 用串列埠顯示從Android手機傳過來的訊息
sprintf(str,"%s",cmd);
Serial.println(str);
cmd[0] = '\0';
}
len = 0;
}
|
BTCom: 執行結果
請先手機的開啟藍芽通訊,並找到HC-06裝置並配對,原廠的初始密碼為「1234」。(噓~~不好意思,歐吉尚用的是郭董的零元手機)
開啟手機的QR Droid(可至Google Play下載)對準螢幕的QR Code識別,即可將程式BTCom下載至手機。如下如所示,執行時須先搜尋欲配對的藍芽裝置(其他功能先隱藏),而AI2專案中所使用的藍芽模組會自動將附近搜尋到的裝置整理成選單列(List)。
執行BTCom,待配對完成,Bluetooth Listener將失效,並致能其他功能(斷線與訊息編輯盒)。
開啟Arduino的串列埠監聽器,在BTCom App編輯盒中輸入「Hello World!」並敲下 Send鈕。
BTCom: 使用LCD1602顯示執行結果
記得之前Arduino開箱文有用到整合I2C 的LCD1602顯示器,趕快學以致用拿來Try。Arduino System端的程式,只要將對標準串列埠的輸出改為對LCD1602輸出即可。只要對前一個程式稍作修改,如下範例中藍色字體的部分。
Arduino BTCom範例程式: 用LCD1602顯示結果
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I
// the maximum received command length from an Android system (over the bluetooth)
#define MAX_BTCMDLEN 128
// 建立一個軟體模擬的序列埠; 不要接反了!
// HC-06 Arduino
// TX RX/Pin10
// RX TX/Pin11
SoftwareSerial BTSerial(10,11); // Arduino RX/TX
// Addr, En, Rw, Rs, d4,d5,d6,d7 backlight, polarity
LiquidCrystal_I
byte cmd[MAX_BTCMDLEN]; // received 128 bytes from an Android system
int len = 0; // received command length
void setup() {
Serial.begin(9600); // Arduino起始鮑率:9600
BTSerial.begin(9600); // HC-06 出廠的鮑率:每個藍牙晶片的鮑率都不太一樣,請務必確認
// 初始化LCD1602
lcd.begin(16, 2);
lcd.clear();
lcd.backlight();
}
void loop() {
char str[MAX_BTCMDLEN];
int insize, ii;
int tick=0;
while ( tick<MAX_BTCMDLEN ) { // 因為包率同為9600, Android送過來的字元可能被切成數份
if ( (insize=(BTSerial.available()))>0 ){ // 讀取藍牙訊息
for ( ii=0; ii<insize; ii++ ){
cmd[(len++)%MAX_BTCMDLEN]=char(BTSerial.read());
}
}
else {
tick++;
}
}
if ( len ) { // 用LCD1602顯示從Android手機傳過來的訊息
sprintf(str,"%s",cmd);
// Serial.println(str);
// 將對串列埠的輸出改為對LCD1602輸出
lcd.clear();
lcd.print(str);
cmd[0] = '\0';
}
len = 0;
}
|
拿另外一支手機來Try,9600bps其實對人來說夠快了! 操作過程幾乎在Send按下的同時,LCD1602就把訊息顯示出來了!
寫到這邊,您是否覺得眼前人生突然變成彩色的呢? 聰明的你其實很容易舉一反三,利用前面的程式,稍加修改就可以控制遠端燈光的開關了! 下次我們就來破解,最近Kickstarter有在募資(中國大陸前一陣子也在募資)的「可以用手機App遙控的無線電源插座」,超簡單! 你也可以開公司!