本文將示範讓兩個Arduino控制板透過藍牙連線傳遞訊息。
本單元的實驗材料:
- 兩個Arduino控制板
- 兩個藍牙模組:其中一個必須是HC-05,另一個可以是HC-05或HC-06。
- (選擇性的)兩個1KΩ(棕黑紅)~4.7KΩ(黃紫紅)電阻
- Android或iPhone手機一支
讓HC-05與另一個藍牙模組在通電時自動配對
藍牙模組有「主控端」和「從端」兩種模式,在配對時,一定是由「主控端」主導,探索其他「從端」並與之配對連線;從端無法彼此互連。
HC-05模組可以透過AT命令,設定成「主控端(Master)」或「從端(Slave)」;HC-06模組只能當「從端」。因此在配對連線實驗中,至少要有一個HC-05模組。
每個藍牙模組都有一個唯一的位址,主控端模組可透過AT+BIND命令(註:“bind”代表「繫結」)紀錄要配對的從端位址,設定好之後,它就能在通電(開機)時,自動探索並和指定位址的從端相連,這中間的過程,不需要Arduino介入,也就是不必寫任何程式碼。
一旦藍牙自動連線完成,Arduino控制板就能透過藍牙傳輸訊息。
使用手機的「藍牙掃描器」App取得藍牙裝置的位址
進行配對之前,我們得先知道從端的位址。取得位址的方法有兩種:
- 使用手機App掃描
- 透過AT命令讀取(僅適用於HC-05模組,參閱下一節說明)
在一般情況下,開啟手機藍牙時,手機應該會找到並顯示探索到的設備位址,接著顯示它的名稱。為了方便檢視探索到的藍牙裝置位址,請先在手機上安裝藍牙掃描器軟體,請到Google商店或者Apple的App Store搜尋“Bluetooth Scanner”,便能找到相關App(筆者安裝的是這個Bluetooth Scanner)。
接著,請參考底下的接線,利用Arduino控制板的5V電源供電給藍牙模組:
線路接好之後,插上Arduino的USB線讓模組通電,接著開啟手機的藍牙,透過手機探索藍牙設備。
底下是在Android手機上,透過Bluetooth Scanner軟體搜尋到的HC-06模組畫面,從中可看到此模組的名稱、位址和無線信號強度:
請先把這個位址抄寫下來。
透過AT命令取得從端位址
如果「從端」也是HC-05模組,除可透過手機App取得它的位址之外,還能透過“AT+ADDR?”命令顯示位址(註:HC-06不具備這個指令;HC-06模組的AT命令,請參閱「HC-05與HC-06藍牙模組補充說明(三):使用Arduino設定AT命令」)。
請參考底下的接線,HC-05模組的Key腳位在開機時,必須處於「高」電位,模組才能進入AT命令狀態。
我們將透過Arduino的序列埠監控視窗設定藍牙模組的AT命令,請先將底下的程式上傳到Arduino。此程式碼的相關說明,請參閱這一篇文章。
#include <SoftwareSerial.h> // 引用程式庫 // 定義連接藍牙模組的序列埠 SoftwareSerial BT(8, 9); // 接收腳, 傳送腳 char val; // 儲存接收資料的變數 void setup() { Serial.begin(9600); // 與電腦序列埠連線 Serial.println("BT is ready!"); // 設定HC-05藍牙模組,AT命令模式的連線速率。 BT.begin(38400); } void loop() { // 若收到「序列埠監控視窗」的資料,則送到藍牙模組 if (Serial.available()) { val = Serial.read(); BT.print(val); } // 若收到藍牙模組的資料,則送到「序列埠監控視窗」 if (BT.available()) { val = BT.read(); Serial.print(val); } }
程式上傳完畢後,打開「序列埠監控視窗」,輸入AT命令看看,藍牙模組將回應OK:
如果沒有回應OK,代表此模組沒有進入AT命令模式,請確認模組的Key腳位有接高電位。
輸入AT+ADDR?命令,它將傳回模組的位址:
藍牙裝置位址
透過手機App和AT指令查詢到的位址格式不同,兩種寫法都行,但採用AT命令設定位址時,必須使用下圖右邊的格式:
補充說明:藍牙裝置位址(Bluetooth Device Address,簡稱BD_ADDR)由一連串16進位數字組成,總長48位元。裝置位址相當於藍牙裝置的序號,每個裝置都不同,它可細分成三個部份:
- NAP:未定義位址部分(Non-significant Address Part),由IEEE分配給製造商的編碼。
- UAP:較高位址部分(Upper Address Part),用於產生錯誤偵測碼以及藍牙裝置的跳頻順序。
- LAP:較低位址部分(Lower Address Part),製造商設定的編碼。
將藍牙模組設定成Master(主控端)並紀錄Slave(從端)的位址
請將要當作主控端的HC-05模組按照上一節的電路接好,Arduino控制板同樣執行上一節的程式。
HC-05模組在出貨時,通常都是「從端」模式。必須先用AT指令改成「主控端」,請開啟「序列埠監控視窗」,輸入AT+ROLE=1,藍牙將傳回OK,代表已經設定成主控端;日後若要改成「從端」,請輸入AT+ROLE=0。
接著輸入AT+BIND=命令,後面跟著要配對的從端設備位址,只要位址格式無誤,HC-05將回應OK,代表位址紀錄完成。
以上設定都會永久保存在藍牙晶片,直到你重新設定。
一對一藍牙無線通訊實驗
本單元將實驗透過藍牙連結兩個Arduino控制板,其中一個板子充當「命令發送者」,發出‘1’或‘0’訊息,藉以控制另一個板子上的LED開關。
請將兩個Arduino都依照底下的接線組裝好:
在準備充當「命令發送者」的Arduino上傳底下的程式碼,不一定要是連接HC-05模組的那個Arduino,因為藍牙模組之間的配對連線,跟Arduino沒有關係。對Arduino來說,這兩個相連的藍牙模組,就相當於在Arduino之間用導線連接一樣。
#include <SoftwareSerial.h> // 引用程式庫 // 定義連接藍牙模組的序列埠 SoftwareSerial BT(8, 9); // 接收腳, 傳送腳 char val; // 儲存接收資料的變數 void setup() { Serial.begin(9600); // 與電腦序列埠連線 Serial.println("BT is ready!"); // 藍牙透傳模式的預設連線速率。 BT.begin(9600); } void loop() { // 若收到「序列埠監控視窗」的資料,則送到藍牙模組 if (Serial.available()) { val = Serial.read(); BT.print(val); } // 若收到藍牙模組的資料,則送到「序列埠監控視窗」 if (BT.available()) { val = BT.read(); Serial.print(val); } }
接著在另一個,充當「接收命令者」的Arduino板上傳底下的程式碼:
#include <SoftwareSerial.h> // 引用程式庫 // 定義連接藍牙模組的序列埠 SoftwareSerial BT(8, 9); // 接收腳, 傳送腳 char val; // 儲存接收資料的變數 const byte LED_PIN = 13; // 定義LED腳位 void setup() { // 設定HC-05藍牙模組,AT命令模式的連線速率。 BT.begin(38400); pinMode(LED_PIN, OUTPUT); } void loop() { // 若收到藍牙模組的資料,則送到「序列埠監控視窗」 if (BT.available()) { val = BT.read(); if (val == '1') { digitalWrite(LED_PIN, HIGH); // 回應命令發送端,告知「已開燈」 BT.println("LED ON"); } else if (val == '0') { digitalWrite(LED_PIN, LOW); // 回應命令發送端,告知「已關燈」 BT.println("LED OFF"); } } }
開啟兩個Arduino板的電源(先後順序不重要),觀察主控端藍牙的LED狀態燈,將先快速閃爍,與從端建立連線後,閃爍速度會變慢。
請先確認Arduino編輯器的序列埠連線是在「命令發送者」的板子:
接著開啟「序列監控視窗」,輸入‘1’和‘0’試試看:
老師您好:
最近小的在做一個專案,想透過lcd讓使用者自己選擇要連的藍牙,能請問老師給小的一些建議嗎?謝謝
請參考這一篇留言。
thanks,
jeffrey
你好 我參考這邊文章,再編譯 接收命令者 程式碼時 出現錯誤,請問我是不是有什麼地方有錯誤
Arduino:1.6.3 (Windows 8.1), 板子:”Arduino Uno”
HC_RX.ino:17:1: error: stray ‘\’ in program
HC_RX.ino:17:1: error: stray ‘\’ in program
HC_RX.ino:17:1: error: stray ‘\’ in program
HC_RX.ino:18:1: error: stray ‘\’ in program
HC_RX.ino:18:1: error: stray ‘\’ in program
HC_RX.ino:18:1: error: stray ‘\’ in program
HC_RX.ino:19:1: error: stray ‘\’ in program
HC_RX.ino:19:1: error: stray ‘\’ in program
HC_RX.ino:19:1: error: stray ‘\’ in program
HC_RX.ino:20:1: error: stray ‘\’ in program
HC_RX.ino:20:1: error: stray ‘\’ in program
HC_RX.ino:20:1: error: stray ‘\’ in program
HC_RX.ino:21:1: error: stray ‘\’ in program
HC_RX.ino:21:1: error: stray ‘\’ in program
HC_RX.ino:21:1: error: stray ‘\’ in program
HC_RX.ino:23:1: error: stray ‘\’ in program
HC_RX.ino:23:1: error: stray ‘\’ in program
HC_RX.ino:23:1: error: stray ‘\’ in program
HC_RX.ino:24:1: error: stray ‘\’ in program
HC_RX.ino:24:1: error: stray ‘\’ in program
HC_RX.ino:24:1: error: stray ‘\’ in program
HC_RX.ino:25:1: error: stray ‘\’ in program
HC_RX.ino:25:1: error: stray ‘\’ in program
HC_RX.ino:25:1: error: stray ‘\’ in program
HC_RX.ino:26:1: error: stray ‘\’ in program
HC_RX.ino:26:1: error: stray ‘\’ in program
HC_RX.ino:26:1: error: stray ‘\’ in program
HC_RX.ino:27:1: error: stray ‘\’ in program
HC_RX.ino:27:1: error: stray ‘\’ in program
HC_RX.ino:27:1: error: stray ‘\’ in program
HC_RX.ino: In function ‘void loop()’:
HC_RX.ino:17:2: error: ‘u3000’ was not declared in this scope
HC_RX.ino:17:8: error: expected ‘;’ before ‘u3000’
HC_RX.ino:18:8: error: expected ‘;’ before ‘u3000’
HC_RX.ino:23:21: error: expected ‘}’ before ‘else’
HC_RX.ino:24:2: error: ‘u3000’ was not declared in this scope
HC_RX.ino:24:8: error: expected ‘;’ before ‘u3000’
HC_RX.ino:25:8: error: expected ‘;’ before ‘u3000’
HC_RX.ino:27:8: error: expected ‘;’ before ‘u3000’
HC_RX.ino: At global scope:
HC_RX.ino:29:1: error: expected declaration before ‘}’ token
編譯時發生錯誤
這份報告的詳情將會在
“編譯時顯示詳細輸出資訊”
在檔案 > 偏好設定裡啟用。
hi loeb:
想必是我在編寫文章時,不小心在程式碼中插入了「全形」空格。內文的程式碼已經更新,請重新貼入Arduino測試。
thanks,
jeffrey
謝謝你 編譯沒問題了,
可否在請教一下 開啟終端機後 輸入 0 或 1都無反應,只有顯示 BT is ready!
有發現程式碼中命令傳送者的BT.begin(9600); 而 命令接收者的BT.begin(38400);
兩著不一樣 會有影響嗎?
在請教一個小問題
藍芽模組裡的at+uart?顯示出來的速率 要跟程式碼的BT.begin(38400); 設定一樣嗎?
謝謝你的指導.
你好 我把命令接收者的BT.begin(38400); 改成BT.begin(9600);
以及兩片HC-05也改成9600 並重新啟動,貌似就可以了,謝謝指導.
半年前做過類似作品(1個HC-05加上1個HC-06),當時也遇到同樣問題,自己也摸索了好久,最後才搞好,當時不以為意,沒想到半年後的今天,重作一次又花了好多時間,因此PO文說一說心得,加深自己的印象,免得下次又要搞半天:首先HC-05和HC-06的鮑率要設為一致(我用9600),發送端的HC-05AT命令是要用BT.begin(38400)沒錯,但在執行老師的程式時,必須將發送端的38400改為9600,這樣做就可以從接收端(也就是HC-06那一端)的序列埠監控視窗看到對應的LED ON,LED OFF了。但是改成9600後,就沒辦法下達AT指令了,如果想再下AT指令,必須將發送端的程式再改回BT.begin(38400),以上拙見。
hi 阿雄:
非常感謝你的補充說明!
thanks,
jeffrey
老師你好:
我們想用兩個(Arduino+NRF24L01)
一個當接收一個當發送
請問該怎麼讀取他們之間的訊號強度
我們的程式碼是參考上面的網站
根據NFR24系列晶片的原廠技術文件第25頁的”6.4
Received Power Detector measurements”單元,”nRF24L01+”這個型號具備一個Received Power Detector(接收功率偵測器,簡稱RPD)暫存器,但是它只佔一個位元,只能判斷接收功率是否大於或小於-64 dBm。
因此nRF24L01通訊模組可能不適合用於妳的專題。
thanks,
jeffrey
老師你好 我現在再做arduino紅外線的專題
我想要把arduino感測到的序列阜值經過藍芽傳到手機上顯示
請問我該怎麼做
專題製作就是讓你把過去所學的,透過一個作品展現出來。以Android程式為例,假設你學的是Java語言,你可以找到Android的Java藍牙相關程式庫;Arduino控制板的程式範例也很多,建議你先從讀取感測器資料,並透過序列埠傳送下手,相關的細節可以和你的專題指導老師討論。
good luck!
jeffrey
老師您好
我想問一下,我的藍芽(HC-05)跟arduino 都沒有問題
然後再跟手機跟藍芽連結的時候,可以配對,但是無法連結 ,請問該如何解決
hi zeng:
請用電腦測試或者換一支手機測試 🙂
thanks,
jeffrey
Hi, cubie
Your code “AT+ROLL=1 ” is wrong.
It should be “AT+ROLE=1”. BTW, thanks for the introduction to BT connection with 2 Arduino, your article saves me a lots of time for this.
Best,
AK
hi AK:
感謝糾錯,內文已改正,謝謝!
thanks,
jeffrey
老師您好! 我使用HC-05藍芽模組, 用手機app發送 “a”字元到arduino的藍芽接收, 但是序列監控讀出來都是”120″和”248” 兩個數值(有故意不轉成char來檢查 不然會是亂碼) ,其他的英文字母或數字也都相同,讀到的都是多個數字組, 請問一下是哪裡出錯了呢? 謝謝!!!
hi yonoodle:
藍牙序列通訊板只是負責轉發微控制器和其他裝置(如:手機)的訊號,如果Arduino收到非預期的字元,問題應該是出在App上,請確認你的App程式傳出ASCII字元。
thanks,
jeffrey
老師您好,若想購買《超圖解》中的HC-05晶片,請問該如何選擇?
網路上發現若是”主從一體”的價格,比單純”主端”或”從端”的價格低上許多,不知性質差在何處? 謝謝。
hi dun:
HC-05模組的基本差異是在出貨時,事先幫你設定好從端或主控端,硬體和韌體都是一樣的…建議直接購買「主從一體」型即可。
thanks,
jeffrey
老師您好
照著”使用手機的「藍牙掃描器」App取得藍牙裝置的位址”的接法後,發現手機掃不到此HC-05的資訊耶,請問我是哪裡出錯了呢? 謝謝老師
hi dun:
請問你有事先在Android系統的「設定」裡的「藍牙」中,將手機與HC-05配對嗎?因為該程式讀取的是手機的已配對藍牙裝置資料。
thanks,
jeffrey
原來如此,謝謝老師
老師您好
我想請問如果我用HC05 跟BTbee HC06的
這2個是否能建立無線連接
hi 力元:
hc05和hc06可以建立連線,hc05要當主控端。
thanks,
jeffrey
老師您好!
如果我有多個感測器(4個左右) ,那我可以用兩個藍芽+兩個arduino把感測器分成2個2個,並把抓到的數值顯示在同一台手機的app上嗎?
因為如果一個藍芽模組配多個感測器,掉資料的機率很大,導致我可能抓不到正確的數值,最近正在想辦法解決這問題。
請問老師有什麼好的建議嗎?
謝謝老師!
再問一個問題
照著以上步驟
到序列監控視窗,輸入‘1’和‘0’時
一直沒有出現LED ON或OFF
是可能哪個步驟有出錯嗎?
謝謝!
也許是配對的位址設定錯了?
謝謝老師!!
成功了
老師您好,
前半段照著老師的步驟都沒問題,
但到了最後的序列監控視窗,
輸入‘1’和‘0’時,
一直沒有出現LED ON或OFF,
我也重複認過配對的位址沒有錯誤,
想請問是不是還有可能是哪個步驟出了問題?
謝謝!
hi michael:
請分開測試兩組程式,例如,接收端部份,請改用有線序列連接,也就是移除藍牙模組,直接把Arduino和電腦相連,透過序列埠監控視窗測試,看看是哪個部份有問題。
thanks,
jeffrey
老師你好!
最近手邊有4顆hc-05藍芽 所以我配成了兩組自動配對的藍芽
上面的測試都沒有問題
但我發現配成主端的hc-05不管是哪一個都會在通電時會自己找另外兩個從端自己配對,和我預期的不太一樣,預期上我以為它們只會配對我設定的從端位址,兩個主端我分別都用(AT+BIND=從端位址)設定了一組從端資料進去,它也有回應OK
但結果和我想得不太一樣,是文章中哪個部份我理解錯誤了嗎?還是”AT+BIND=”設定的東西和我想的不一樣?
煩請老師替我解答
hi coobe:
有個叫做”CMODE”的AT指令,能夠設定是否連接任何藍牙從端,或者只連接到已配對的從端:
【已修正錯誤】
AT+CMODE=0 #代表只與已配對的從端相連
AT+CMODE=1 #代表能與任何從端相連
thanks,
jeffrey
老師你好!
經過測試沒有問題了 不過和老師解答的內容剛好反過來了這裡可能要和你說一下,查了一下網路上的AT指令集,AT+CMODE=0是和綁定的從端連接,AT+CMODE=1是和隨意從端連接
另外我想請問HC-05使用”AT+BIND=”只能綁定一組藍芽麼? 我試過複數藍芽位址但用”AT+BIND?”查詢時始終只會顯示一組藍芽位址
謝謝!
欸~仔細看了AT指令說明書第9頁,我上個留言確實寫反了,感謝糾正!
AT+BIND只能綁定一組藍牙位址(請參閱說明書第10頁)。
thanks,
jeffrey
老師您好,
前半段照著老師的步驟都沒問題,
但到了最後的序列監控視窗,
輸入‘1’和‘0’時,
一直沒有出現LED ON或OFF,後用兩台電腦將ho5 fo6都改為38400
分別接 uno 和 nano上,兩台都灌入您的控端程式,分別從兩台電腦上序列埠監控及輸入資料,結果發現不論從哪邊輸入,另一邊都出現亂碼,(分別都有進入AT 模式 指令都 OK),
想請問是不是還有可能是哪個步驟出了問題?
HC-06的預設連線速率是9600bps,你有試過直接用有線方式測試嗎?
thanks,
jeffrey
老師您好,
如果我想在arduino裹知道藍牙模組有沒有裝置連接
在code中應該如何寫??
何否用以下模式寫??
if (deviceconnected ==1){ digitalWrite(ledpin,HIGH);}
else {…….}
謝謝老師
hi jason:
請參閱「HC-05與HC-06藍牙模組補充說明(一)」,如果你的藍牙序列通訊板子上有STATE(連線狀態)引腳,可將它接到Arduino;若STATE腳持續輸出HIGH,就代表已連線。
thanks,
jeffrey
老師您好,我依照上面AT設定好at+bind和at+role,
但兩塊HC-05一直無法連線(快速閃燈)
請問是甚麼原因?
謝謝
hi alvin:
請確認藍牙的Key腳沒有接高電位、從端的位址輸入正確,嘗試在主控端輸入底下的AT命令,再測試看看:
AT+CMODE=0 #代表只與已配對的從端相連
thanks,
jeffrey
老師您好,
上述的程式本人已經成功,
接下來我想利用單顆按鈕來控制LED的亮滅,
想利用傳值的方式,
卻一直無法成功
老師可給個建議?
我主端程式後半部是
void loop() {
buttonstate=digitalRead(buttonpin);
// 若收到「序列埠監控視窗」的資料,則送到藍牙模組
if (buttonstate == HIGH) {
val = 1;
BT.print(val);
}
else{
val = 0;
BT.print(val);
}
// 若收到藍牙模組的資料,則送到「序列埠監控視窗」
if (BT.available()) {
val = BT.read();
}
}
hi rasico:
在接收端加入digitalWrite()敘述即可,例如:
if (BT.available()) {
val = BT.read();
if (val == ‘1’) {
digitalWrite(LED_PIN, HIGH);
}
}
thanks,
jeffrey
老師您好,
可請問一下-48的用意為何?
還有digitalWrite(val)後是不是要加個high?
-48是為了把字元轉成數字(相關說明請參閱10-10頁「透過序列埠調整燈光亮度」單元),請忽略之前的寫法,上個留言的程式敘述已更新,LED_PIN常數代表預設的LED連接腳位。
thanks,
jeffrey
老師您好,
關於您的主控端程式
void loop() {
// 若收到「序列埠監控視窗」的資料,則送到藍牙模組
if (Serial.available()) {
val = Serial.read();
BT.print(val);
}
// 若收到藍牙模組的資料,則送到「序列埠監控視窗」
if (BT.available()) {
val = BT.read();
Serial.print(val);
}
}
我發現是兩邊資料互相接送
那我上兩個留言的主控端程式
是否不能這樣打呢
目前情況是led亮的有點詭異
不符合情況
如果你只需要由一方控制另一方,那麼序列接收程式就不必送回訊息,例如:
我不了解「led亮的有點詭異」的意思。
thanks,
jeffrey
謝謝老師,
我成功執行利用利用按鈕控制LED的亮滅了,
最後是在主控端的程式,
加上上拉電阻digitalWrite(2, HIGH);
可以讓LED穩定工作了
感謝告知!所以原先的問題是出在開關?因為直接把開關串接在Arduino,然後接地,而非透過外接的上拉電阻…
thanks,
jeffrey
您好,請問有什麼方法可以讓藍芽模組傳輸兩組數值
並且接收端也接收兩組數值呢?
因為有兩個變數要傳輸。
你可以自訂傳送的訊息格式。
假設我要透過序列埠傳送兩個馬達控制訊號,左馬達我叫它”L”,右馬達用”R”代表。這個序列資料:
“L50\nR128\n”
代表左馬達輸出50、右馬達輸出128。
接收端程式用String物件解析比較方便,請參閱書本17-22頁的調光器範例(程式說明在17-24頁)。
thanks,
jeffrey
您好,老师。 我想请问下, 我有1个代码是用arduino mega上面的1个电位器通过串口通信来控制舵机控制板上的1个舵机。 我有两个HC-05 的蓝牙模块, 分别用AT指令设置成了主端和从端了,并且都成功配对连接上了,每个蓝牙都分别连接在一个arduino mega上 我想问下如何把以下的代码分别写到两个arduino mega 里,让两个arduino能够成功的连接在一起。
#include //包含舵机库
int pos = 0; // 设定舵机的转动位置为变量
void setup()
{
Serial.begin(115200); //舵机控制板的速率
}
void loop()
{
int value = analogRead(A0); //读取A0口输入的模拟值
pos = map(value,0,1023,0,180); //将读到的模拟值0~1023映射为0°~180°
Serial.println(String(“#10P”) + (pos) + 0);
delay(100); //延时一段时间让舵机转动到对应位置
}
hi,
Arduino Mega 2560控制板包含额外的Serial对象:
假设你的蓝牙模块接在Serial1,修改上文的代码,便可从Serial1收发蓝牙资料:
thanks,
jeffrey
非常感谢您的回复, 只是我还是不太清楚 如何把我的代码分别截成相应的两断然后放到两个arduino mega里面。 具体说的话就是 int value = analogRead(A0); 这句是作为主端arduino mega 上的电位器的输入值。 pos = map(value,0,1023,0,180); 这句是相互对应输入和输出的值, 最后这句Serial.println(String(“#10P”) + (pos) + 0); 则是做为另一个从端的arduino mega 上的舵机输出值。 能分别帮我改成一个主端命令, 和一个从端接受蓝牙的代码吗。 非常感谢。
OK, 這個程序需要執行下列幾個事項:
傳送端:通過Serial1.print()送出旋轉角度值。
接收端:
1. 通過Serial.availible()檢查序列埠是否有數據
2. 通過Serial1.read()讀取轉動值
2. 把轉動值(字符串)轉換成數字
3. 調用Servo對象的write()方法轉動角度。
代碼請自己完成。
thanks,
jeffrey
老師,您好:
拜讀您的大作,受益良多。
透過您這篇文章,成功連結兩個arduino 的藍芽模組;
連結android手機及arduino 的藍芽模組也沒有問題。
可是當兩個arduino 的藍芽模組連結後,
卻無法使用android手機去讀取主端或從端的arduino 的藍芽模組。
請問老師是否有解決方案?
謝謝!
hi 阿漂:
設定成主控端的藍牙板可能連不上Android手機,但從端應該沒問題,請開啟「設定→藍牙」,重新搜尋、配對看看。
thanks,
jeffrey
請問 app invertor 2 如何同時連接多個hc-05 謝謝
hi 小郭:
你可以嘗試在App Inventor的編輯畫面拖放多個Bluetooth Server元件,分別設置連線程式看看,我沒有實際試過。
thanks,
jeffrey
老師,您好:
從端是已可以配對,此時由從端將主機接收的資料傳送出去,讓手機也可以收到主機端傳來的資料,
我將從端資料透過同一COM 同時傳送給主機端跟手機,
但是只要主機端傳送資料給從端時,
從端傳送的資料會被主機端鎖定,無法同時傳送資料給手機端;
若手機端讀取從端傳送資料時,主機端無法同時傳送資料給從端。
請問資料傳送的方向 可以是 主機->從端->手機 ?
我試過很多次始終沒有辨法達成?
不吝賜教! 謝謝!
SoftwareSerial BT(10, 11); // 接收腳, 傳送腳
char val; // 儲存接收資料的變數
void setup() {
pinMode(RelayPin, OUTPUT); //繼電器設定
digitalWrite(RelayPin, HIGH);
Serial.begin(9600);
BT.begin(38400);
}
void loop()
{
if (BT.available()) {
val=BT.read();
if (val==’d’) {
digitalWrite(RelayPin, LOW);
return;
}
BT.write(val); //讓手機可以收到
}
}
藍牙從端一次只能與一個主控端相連,就像藍牙滑鼠不能同時連接兩台PC。
所以你只能朝這些方向進行:
1. 把Android當成從端,連接到HC-05主控端,但是,我不確定HC-05的韌體是否有支援連接多個從端的功能。
2. 把Android當成主控端,連接其他HC-05藍牙裝置,但是這會變成以Android主導,若Android中斷連線,其他藍牙也就失去連線。
3. 理論上,兩個藍牙主控端可相互連線,但是必須韌體支援”scatternet”通訊協定,所以這個方法不可行。
thanks,
jeffrey
老師你好:
手機app 連結HC-05 之前使用皆正常但卻突然為何出現ERROR 516 Unable to write Broken pipe 是何原因 謝謝
哪種藍芽最穩定
hi 小郭:
Android系統的”Unable to write Broken pipe”錯誤訊息,代表連結目標的藍牙裝置突然中斷連線,程式無法順利送達訊息,通常是因為藍牙模組隔太久時間沒有和App聯繫導致。
請試著在App Inventor中加入底下的錯誤捕捉程式區塊,它應該能在發生516編號錯誤時,中斷藍牙連線。這是中文版畫面:
這是英文版:
thanks,
jeffrey
老師你好:
可否請老師介紹何種適合arduino控制12v/24v 輸出電流為3a之馬達正逆轉 ic 具 pwm功能 謝謝
你可以採用MC33926, LMD18245或LMD18200馬達驅動IC的控制板。
thanks,
jeffrey
老師你好: 不好意思再次打擾, 問題是app 已連結藍芽 但卻忘了登出待下次使用app時卻無法連線因 藍芽已處於連線狀態 所以想請教老師 app invertor 2是否有解決之法 謝謝
你可以在關閉App時,透過Disconnect指令中斷藍牙連線。這篇文章有一個按下Back鍵,詢問用戶是否關閉App的範例。你可以在其中的”AfterChoosing”區塊,執行藍牙的Disconnect。
thanks,
jeffrey
謝謝老師教導, 另問如何再掏寶網購物 謝謝
老師你好:
我用藍芽HC-05模組接86-duino educake
想看看能否自傳自收寫了下面的程式
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println(“READY”);
Serial1.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.write(2);
Serial1.write(3);
Serial.println(Serial1.read());
Serial.println(Serial.read());
delay(100);
}
結果打開序列監控視窗顯示的是:
-1
-1
-1
-1
為什麼會是-1以及有個-1前面會多個空格呢?
Serial.write() 送出的是ASCII值,所以序列埠監控視窗接收到的是控制字元,-1代表序列埠緩衝記憶體裡面是空的,尚未收到資料。
thanks,
jeffrey
老師你好:
我想請問一下如果要在兩個模組間傳送一組sensor感應到的數據
程式碼要怎麼改
才能傳送指定的數據
藍牙傳送序列訊號,跟使用USB序列埠傳送訊號的程式是一樣的,你可以直接用10-10頁「透過序列埠調整燈光亮度」的例子來修改,只是把「燈光亮度」訊息改成「感測訊號值」。
thanks,
jeffrey
老師你好:
不好意思想請問 app 三段指令意思
(1) if callbluetoothclient1.BytesAvailableToRecevive>0 是何意
(2) then Setglobaltext to callbluetoothclient1.ReceviveText NumberOfBytes 1 其中數字1 是何意
(3) if getglobaltext <0 是何意
謝謝
如果把程式設計比喻成拼圖遊戲的話,你這個問題就好像從一大盒拼圖裡面取出幾片丟給我,要我猜猜這是什麼主題的拼圖一樣…
幸好,程式語言的指令,以及程式設計師在寫程式的時候都會遵循一定的命名規則,而且它們都是有意義的英文單字組成。就像callbluetoothclient1,就是call bluetooth client 1,其後的指令也就是bytes available to receive,你查一下英文字典就能得知這些單字的意思了。
have fun!
jeffrey
請問老師,如果要讓手機app傳送資料>>主機>>從端
要用app inventer的Bluetooth sever還是Bluetooth client
我想做一個手機連接一個HC-05主機端,傳送資料分別控制2個從端
請拖放兩個bluetooth server元件測試看看。
thanks,
jeffrey
老師您好,我的專案有分為”傳送端”,”控制端”分別使用兩台86duino和兩片HC-05的藍芽模組,使用可變電阻的感測器
我問題是:我成功了很多次,但是等下一次再進行測試的時候,就會跟上一次的結果不一樣,不是亂抖動,就是會很久才有反應.
或是一開始很正常,測試5分鐘後就不太正常了變的反應很慢或亂抖動,測試正常的時候偶爾也是會抖一下.
我不知道是不是我一直讓它一直傳送數值而讓藍芽塞車?我希望可以讓我的機械手穩定一點,不知道是我的寫法不好還是哪裡出錯了?
我試過改變了很多組的delay參數組合,每次的結果也都很不同,有時候這組超正常以為成功,再隔一天測試又不行了.希望可以有人指導我.
以下是我最基礎的程式碼
傳送端:
接收端:
hi 小郭:
你可以先著手修改兩個部份:
1. 傳送多筆資料值,請將所有資料都組成一個字串,同時傳送。例如,原本的程式逐一傳送Data[0], Data[1], Data[2],…
請把這些資料組成如下的字串,每筆資料中間用逗號或其它字元分隔,最後可加上’\n’結尾:
11,22,33,…\n
接收端程式再透過String物件,即可分割、取出個別的資料,相關範例可參閱17-21頁的「動手做17-3」。
2. 伺服馬達的轉動延遲時間,應該要依照你採用的規格來調整,例如,普通的9g微型伺服馬達旋轉60度約需時0.12秒,轉動180度就需要0.36秒。你的延遲時間不應該小於這個數值,否則馬達可能無法轉到定位。
have fun!
jeffrey
請問hc-06的藍芽模組可以接到linkit one嗎?
那它要怎麼和連接hc-05模組的arduino互通?
hi joanne:
凡是具有RxD和TxD序列傳輸介面的微電腦板,都能連接藍牙序列模組,包括linkit one在內。
至於和其他控制板互通,那是程式的問題,Arduino板就用Arduino的C程式來寫,至於linkit one,應該是透過Node.js,抱歉我沒用過linkit one。
thanks,
jeffrey
我們找到了下面的程式,並且燒製linkit one的hc-06,但它一直無法與arduino的hc-05相連?
char val; // 儲存接收資料的變數
void setup() {
Serial.begin(9600); // 與電腦序列埠連線
Serial.println(“BT is ready!”);
// 設定藍牙模組的連線速率
// 如果是HC-05,請改成38400
Serial1.begin(9600); // 與電腦序列埠連線
}
void loop() {
// 若收到「序列埠監控視窗」的資料,則送到藍牙模組
if (Serial.available()) {
val = Serial.read();
Serial1.print(val);
}
// 若收到藍牙模組的資料,則送到「序列埠監控視窗」
if (Serial1.available()) {
val = Serial1.read();
Serial.print(val);
}
}
從你上個留言看來,我覺得你的實驗順序搞錯了。你應該先了解並搞定控制板的序列通訊程式,並透過電腦或手機的藍牙連線測試,兩個控制板的序列連線分別測試成功之後,再嘗試用藍牙連接兩個控制板。
兩個藍牙序列通訊板之間的配對連線,透過AT命令操作,跟控制板上的程式沒有關聯。
have fun!
jeffrey
老師您好,若想要使用多台Arduino + HC-05,
在主從模式變換中,互相偵測對方的RSSI值,
並以無線方式,將收到的資料傳給筆電,
在筆電中,使用類似Putty等軟體,掃描com port,
但問題是螢幕顯示出相同的RSSI值,並不斷重複
表示sensor只偵測一次RSSI,請問是哪裡出錯了呢?
還是需要一台sensor先以有線方式連接筆電,其他sensor再將資料轉傳呢?
SoftwareSerial BTserial(10, 11);
void loop()
{
當BTserial.available()時 //讀取BT module中的資料
char c = BTserial.read();
String += c; //將讀到的資料寫進String中
BTserial.print(“AT+ROLE=1\r\n”);
BTserial.print(“AT+INQ\r\n”);
BTserial.print(String); //印出從BT module來的資料
BTserial.print(“AT+ROLE=0\r\n”);
}
hi dun:
HC-05模組的RSSI相關命令我沒有測試過,這是我之前回覆的相關留言,提供你參考。
thanks,
jeffrey
之前用兩個arduino板子已成功將兩個藍芽模組配對成功,到linkit one上還要再配對一次?
如同我上一則回應,「兩個藍牙序列通訊板之間的配對連線,透過AT命令操作,跟控制板上的程式沒有關聯。」
既然你已經在Arduino上連線測試成功,那就代表藍牙也已配對連接成功,不需要重新配對,跟微電腦控制板沒有關係。所以問題出在你的linkit one程式…你有事先單獨測試linkit one的序列通訊程式是否如預期般運作嗎?
have fun!
jeffrey
主端傳送資料時,在serial monitor上顯示正常,但在從端的serial monitor上卻是顯示亂碼,請問這樣實際上接收到的值會是正確的嗎?要怎樣才能讓從端的serial monitor顯示正常的值?
接收端的「亂碼」應該是字元的ASCII編碼,假設接收字元的變數是val,執行char(val),將能把資料轉換成字元。
thanks,
jeffrey
老師您好,我最近遇到兩個HC-05配對通信的問題。兩個HC-05一主一從,波率同都是9600,配對成功,但主控端發送的數據,從控端一直接收不到。請問老師,這可能是什麽原因?
hi koen:
請問你有分別測試接收和發送端程式,確認無誤嗎?
thanks,
jeffrey
您好
想請問我想用 iphone 4S 藍牙4.0 連接ARDUINO UNO 作一些簡單的遙控開開關關的動作
應該要選擇甚麼樣的藍牙模組(BLE or HC-05)來實驗?
您書上用的是HC-05,用在安卓手機上自然是沒問題
但爬過GOOGLE後
http://thinkingiot.blogspot.tw/2015/11/bluetooth-mfi.html
似乎 IOS 封鎖了藍牙上的SPP,若真如上面連接所言
照您書上的藍牙範例要iphone以SPP方式透過HC-05豈不是無法連上arduino ??
或是我有哪些地方誤解?
苦惱中
hi rainey:
我在 Cordova (PhoneGap) 上採用的藍牙外掛是Bluetooth Serial Plugin for PhoneGap,在該專案網頁有提到Android和Windows手機採用的是普通的藍牙模組(也就是HC-05或HC-06等藍牙序列模組),iOS則需要使用藍牙低功耗(Bluetooth Low Energy, BLE),也就是藍牙4.0模組,提供你參考。
thanks,
jeffrey
老師您好:
我現在有兩個HC-05,已經設定好主從端了
也綁定好位址了
因為我想利用感測器透過ARDUINO傳送資料(無線)到電腦
所以我想問如果主端的HC-05有辦法透過行動電源供電,然後連接我的ARDUINO跟感測器
將資料傳到從端的HC-05
然後透過ACCESSPORT把資料讀出
想問一下藍芽模組有辦法這樣嗎?
hi lee:
可以,藍牙模組透過SoftwareSerial連結Arduino板,AccessPort透過Arduino預設的序列埠相連即可,程式範例如同《超圖解Arduino互動設計入門》14-10頁所示。
thanks,
jeffrey
請問如果我的arduino板子要擴接藍芽模組跟RFID模組….,多模組的話可以這樣做?
hi condy:
可以,因為你提到的模組都是用序列方式連接,只要用SoftwareSerial個別定義接腳即可。
thanks,
jeffrey
請問 我設計好 app invertor 2 的APP, 可以和 3個 HC-05 都配對成功,個別連線控制也可以,現在的問題是要 同時控制3個的話,也就是群控,可以做的到嗎? APP要怎麼選拼塊來改? 謝謝!
hi cliff:
如果每次切換不同的藍牙模組都要先切斷前一個模組的連線,那恐怕就不行了,否則,你可以嘗試用迴圈處理。
thanks,
jeffrey
老師您好,我們在做專題時遇到了問題,要使用2個HC06或HC05分別傳送不同訊息到android手機端,目前寫的是一對一程式是可以通訊的,但2個HC06或HC05可以利用上面的方式傳輸嗎,還有能分別出我哪一端傳送甚麼資料到android端嗎?
hi shawn:
你可以在Android上透過藍牙裝置的名稱和UUID識別碼來分辨不同的藍牙周邊。
thanks,
jeffrey
老師您好,我是SHAWN,這樣還需要用到HC06連接HC05這個嗎,還是我可以分別HC06接手機跟HC05接手機。
我android已經有寫UUID:00001101-0000-1000-8000-00805F9B34FB,HC06跟HC05應該都是這個UUID,這樣還能夠分辨不同的嗎,還是一個是用UUID一個是用藍芽裝置名稱這樣子的寫法
拍謝,上個回文寫錯了,是名稱和MAC位址。
thanks,
jeffrey