本文將示範讓兩個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’試試看:
老師您好,請問我藍芽模組有互相連到(藍芽模組的燈閃爍頻率一樣,且閃爍兩下),測試從序列埠控制LED開關也正常,但從藍芽控制就無法只顯示BT is ready ,操控0與1沒有反應,請問是什麼問題呢?
命令發送端的程式碼
#include
SoftwareSerial BT(9,10);
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);
}
}
接收命令端程式碼
#include
SoftwareSerial BT(9, 10);
const byte LED_PIN = 13;
char val;
void setup() {
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”);
}
}
}
請將接收端的速率38400改成9600試試。
thanks,
jeffrey
老師請問能從主控端發送訊息給從端嗎
可以
請問老師藍芽能一對二溝通嗎?若可以,想從主控端分別發送訊息至兩個從端,那麼主控端與從端的程式碼分別該怎麼寫呢?
HC-05藍芽模組僅支援一對一連線。
thanks,
jeffrey
請問老師藍芽模組能一對二溝通嗎
如果你有這樣的需求,建議使用樹莓派之類的高階微電腦板。
thanks,
jeffrey
那HC-08呢
沒試過~
老師您好,我在網上有購買一個BLE CC2541的藍芽模組,請問他是屬於HC05跟HC06的類型嗎?
我照著HC05的操作做到輸入AT指令時沒有反應,是不是他不屬於這2種呢?
嗯,BLE CC2541是藍芽4.0模組,控制方式和HC-05/06不同。
thanks,
jeffrey
老師您好 您說發出0.1訊息 藉以控制另一個板子上的LED開關。 那個開關是指從端地哪裡~?
你誤會了,「控制另一個板子上的LED開關」當中的「開關」是動詞,不是名詞。
也就是:點亮或關閉另一個板子上的LED…你接線實驗就知道了。
thanks,
jeffrey
我能不能再AT這邊輸入0/1控制從端LED 變成我手上遙控開關 讓從端的LED亮滅呢?
我猜想你的意思是:不連接微控制器,單獨使用藍牙模組來控制另一個模組。HC-05/06藍牙晶片本身有控制IO接腳的功能,但它內建的韌體把模組當作序列傳輸介面,你要的功能應該只能透過改寫韌體達成。
thanks,
jeffrey
老師您好,我也是遇到藍芽已相連,輸入0/1沒反應的問題,已將slave端接收速率改成9600,但仍然沒反應,請問要怎麼解決?
MASTER:
#include // 引用程式庫
// 定義連接藍牙模組的序列埠
SoftwareSerial BT(10,11);
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);
}
}
SLAVE:
#include // 引用程式庫
// 定義連接藍牙模組的序列埠
SoftwareSerial BT(10, 11);
const byte LED_PIN = 8;
char val;
void setup()
{
BT.begin(9600);
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”);
}
}
}
THANKs~~
我曾經重做過這個實驗數次,並沒有出現類似的狀況;假使有問題的話,我應該會先把藍牙模組都復原成出廠狀態,然後先個別用電腦或手機連線測試,最後做配對實驗。
thanks,
jeffrey
我也發生已經連線但是無法設定LED燈狀態,將Master的BT.print(val);改為BT.write(val);就OK了
非常感謝Jason的補充說明~
thanks,
jeffrey
老師請問我這樣有寫錯嗎 我想要把三軸感測器的數值用HC-05傳到另一個HC-05
這邊是MASTER的程式:
#include
SoftwareSerial BTSerial(10, 11); // RX | TX
const uint8_t zAxis = A2;
const uint8_t yAxis = A1;
const uint8_t xAxis = A0;
//Min and Max values after calibration:
int16_t zLow = 283, zHigh = 419, xHigh = 399, xLow = 264, yHigh = 396, yLow = 260;
void setup()
{
Serial.begin(9600);
Serial.println(“Enter AT commands:”);
BTSerial.begin(9600); // HC-05 default speed in AT command more
}
void loop()
{short angleX = map(constrain(analogRead(xAxis), xLow, xHigh),xLow,xHigh,-90,90);
short angleY = map(constrain(analogRead(yAxis), yLow, yHigh),yLow,yHigh,-90,90);
short angleZ = map(constrain(analogRead(zAxis), zLow, zHigh),zLow,zHigh,-90,90);
String dataString = String(angleX);
dataString +=”,”;
dataString += String(angleY);
dataString +=”,”;
dataString += String(angleZ);
Serial.println(dataString);
char a=Serial.println(dataString);
delay(100);
// Keep reading from Arduino Serial Monitor and send to HC-05
if (Serial.available())
BTSerial.write(a);
delay(100);
}
這邊是Slave:
#include
SoftwareSerial BTSerial(10, 11); // RX | TX
void setup()
{Serial.begin(9600);
BTSerial.begin(9600);
Serial.println(“Enter AT commands:”);
}
void loop()
{
if (BTSerial.available())
{
delay(200);
Serial.println(BTSerial.read());
delay(100);}
}
我都收不到訊息
老師您好:
我的兩個HC-05已經可以連接上(閃燈同步,快閃兩次停2秒),但是訊號卻不能傳遞,想請問要如何解決?
用主端向從端發1/0,結果都是回覆ERROR:(0),接受命令一方的led也沒有反應。不知道是什麼問題。
老師您好!
我用了兩台電腦並使用TTL線連接兩塊ARDUINO板子,用來發送端使用HC-05(目前狀態:快閃兩次停2秒)
接收端使用HC-06(一直維持恆亮),接線方式都是使用5V及PIN3,4腳.
HC-05使用AT指令將該設定的都設令了(AT+ROLE=1,鮑率=38400),HC-06只有4跟PIN腳,所以不會調(鮑率=9600)
接收端Code:
#include
// 定義連接藍牙模組的序列埠
SoftwareSerial BT(3, 4); // 接收腳, 傳送腳
char val; // 儲存接收資料的變數
void setup() {
Serial.begin(9600); // 與電腦序列埠連線
Serial.println(“BT is ready!”);
// 藍牙透傳模式的預設連線速率。
BT.begin(38400);
}
void loop() {
// 若收到「序列埠監控視窗」的資料,則送到藍牙模組
if (Serial.available()) {
val = Serial.read();
BT.print(val);
//BT.write(val);
}
// 若收到藍牙模組的資料,則送到「序列埠監控視窗」
if (BT.available()) {
val = BT.read();
Serial.print(val);
}
}
發送端Code:
#include // 引用程式庫
// 定義連接藍牙模組的序列埠
SoftwareSerial BT(3, 4); // 接收腳, 傳送腳
String val; // 儲存接收資料的變數
const byte LED_PIN = 13; // 定義LED腳位
void setup() {
// 設定HC-05藍牙模組,AT命令模式的連線速率。
Serial.begin(9600);
BT.begin(9600);
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”);
}
BT.write(“LED OFF”);
Serial.println(val);
}
}
但接收端的Serial視窗沒有資料
建議在接收端加入BT.println(val),確認到底有沒有收到資料。
thanks,
jeffrey
老師你好, 我是一個初學者
我看了你的內容我想了解, 是不是我可以使用一個MIT App Inventor 2 軟體直接控制2 個 “HC05 +AMTAGEA 328P” 藍芽模組
很久以前在App Inventor的貼文中有讀者問過類似的問題,我記得是可以拖曳兩個藍牙元件;我自己沒有嘗試過…拍謝,很久沒用App Inventor了。
thanks,
jeffrey
老師你好:
我想請問下我有2個hc-05,1個arduino,一個LCD12864,這樣我能透過電腦傳程式到LCD上嗎?
跟上面有什麼差別呢?
您好~請問 兩個版子藍芽溝通能否不透過電腦來實現(程式先燒錄好之後) 版子直接接上9V通電
因想利用ARDUINO藍芽模組 直接讀取類比值訊號後, 並將此類比發送到另一個ARDUINO藍芽模組 來點亮LED元件
可以
老師您好~參考您的程式後
(主端) 讀取一個類比訊號
#include // 引用程式庫
// 定義連接藍牙模組的序列埠
SoftwareSerial BT(8, 9); // 接收腳, 傳送腳
void setup() {
Serial.begin(9600); // 與電腦序列埠連線
// 藍牙透傳模式的預設連線速率。
BT.begin(9600);
pinMode(A0, INPUT); // 電壓訊號A0讀入
}
void loop() {
int val; //A0讀到的數值
val = analogRead(A0); //讀0~1023
}
——————————————————————————-
從端>接收數據端
#include // 引用程式庫
// 定義連接藍牙模組的序列埠
SoftwareSerial BT(8, 9); // 接收腳, 傳送腳
const byte LED_PIN = 13; // 定義LED腳位
int val; // 儲存接收資料的變數
void setup() {
// 設定HC-05藍牙模組,AT命令模式的連線速率。
BT.begin(38400);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
val = analogRead(A0);
if (val>=100) {
digitalWrite(LED_PIN, HIGH);
// 回應命令發送端,告知「已開燈」
} else if (val<100) {
digitalWrite(LED_PIN, LOW);
// 回應命令發送端,告知「已關燈」
}
}
讀取道的類比訊號這樣子 是否有丟到另一塊板子讓LED做點亮功能
再麻煩指教 ! 謝謝!
老師您好:
我是程式超級新手~我只會一點點的PLC~但我看你這篇文章讓兩個ARDIUNO的藍牙互相連接了
非常感謝您的這些教學文章
我現有一個問題有點亂
就是我要讓從端的1V~5V的SENSOR類比訊號轉成數位訊~透過藍芽傳到主端的ARDIUNO
再從ARDIUNO的數位訊號透過另一塊板子轉成1V~5V類比訊號
這部分我就有點不知如何著手
我覺得這樣的安排有點怪…類比訊號進入Arduino轉成數位訊號,傳給另一個Arduino再還原成類比訊號…經過兩次轉換之後,訊號的誤差就變大了。
傳送序列資料或者數字資料轉換的方式,書本都有提到。
thanks,
jeffrey
老師為啥 我的主控端HC05和HC06連上嘞 卻沒辦法控制LED
HC05程式
#include // 引用程式庫
// 定義連接藍牙模組的序列埠
SoftwareSerial BT(8, 9); // 接收腳, 傳送腳
char val; // 儲存接收資料的變數
void setup() {
Serial.begin(9600); // 與電腦序列埠連線
Serial.println(“BT is ready!”);
// 設定藍牙模組的連線速率
// 如果是HC-05,請改成38400
BT.begin(9600);
}
void loop() {
// 若收到「序列埠監控視窗」的資料,則送到藍牙模組
if (Serial.available()) {
val = Serial.read();
BT.write(val);
}
// 若收到藍牙模組的資料,則送到「序列埠監控視窗」
if (BT.available()) {
val = BT.read();
Serial.print(val);
}
}
HC06程式
#include // 引用程式庫
// 定義連接藍牙模組的序列埠
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”);
}
}
}
連上的意思是HC-05有收到HC-06的回應嗎?那應該要檢查線路有沒有問題。
thanks,
jeffrey
老師想請問一下
若是像文內有兩張版子兩個藍芽 是否能傳遞訊號?
我的構想是
第一張版子連結超音波收到訊號後給藍芽傳輸至第二張版子藍芽收到後讓蜂鳴器叫
這樣是有辦法做到的嗎 網路上搜尋到的資料都是只有傳送文字而已 訊號有辦法傳送嗎?
在Scratch內找不到藍芽傳輸的東西 有點頭痛
謝謝老師回答
超音波模組的輸出訊號是高低電位的數位訊號,我不明白你指的訊號是什麼?聲波嗎?
如果要用藍牙傳送,直接從一個控制板傳遞超音波感測到的「距離值」給另一個控制板就可以了,沒有必要傳送原始數位訊號。
至於Scratch…拍謝,它跟我不熟。
thanks,
jeffrey
老師您好,請問我藍芽模組有互相連到(藍芽模組的燈閃爍頻率一樣,且閃爍兩下),測試從序列埠控制LED開關也正常,但從藍芽控制就無法只顯示BT is ready ,操控0與1沒有反應,請問是什麼問題呢?
很多人有這問題,困擾我6小時,終於可以了。設定HC-05藍牙模組,AT命令模式的連線速率。
BT.begin(38400)—–> BT.begin(9600),主從都一樣。有此問題的可試試。
非常感謝您的補充說明,因為藍牙模組的廠商或韌體版本不同,所以導致通訊速率設定不一樣,再次感謝!
thanks,
jeffrey
老師您好:
不知您是否有遇過這類問題,不論輸入甚麼AT指令,其輸出如OK皆顯示亂碼,鮑率確定都是38400,可能像是雜訊彈跳問題,最近一直是不出來,想請教一下。
沒有遇過,我下週試試。
其實只要空程式,也能觸發藍芽內的AT指令。關於AT指令的程式其實大同小異,不過還是有少數人遇到跟我一樣的狀態,這算另一種方法
感謝您的補充。比較詳細的說明是,把Arduino板子的Reset腳接地,RX和TX接藍牙序列通訊模組;因為Reset接地,Arduino板子上的處理器就不會運作,只有板子上的USB轉序列晶片仍在運作,負責把在電腦上輸入的命令傳送給藍牙晶片或相反。
老師您好,我的藍芽模組(BT05)有互相連到(藍芽模組的燈恆亮),但我想把從端的紅外線數據透過藍芽印在主端(有接電腦)的序列阜,但主端都沒顯示任何文字,而且主端對從端下指令(輸入1)也沒有反應,請問老師要怎麼解決?
請先確認RX, TX接線正確,線路沒有斷線。
若接線無誤,先拆掉兩個Arduino板子上的藍牙模組,再將兩個板子直接用導線串連看看程式能否如期運作。
如果可以運作,那就是藍牙並沒有互連。
謝謝老師回覆。
不過我現在把主端Arduino板的RXD(D9)接到從端板子的TXD(D10),TXD(D10)接到從端板子的RXD(D9),請問老師這個方法能測試程式有沒有寫錯嗎?
目前我使用這個方法,從端讀到的數值確實可以傳到主端並印出來。不過只要換成藍芽的程式就沒辦法跑出數據,這是為什麼?(藍芽的燈有恆亮,而且每次接通電路兩個藍芽模組馬上就會恆亮)
請問老師有什麼建議使用的藍芽模組嗎?(傳輸距離需要40公尺,要可以設定主從端,主端要接電腦,接收從端的資料並印在序列阜)
40公尺…建議用Wi-Fi
一個master可以同時跟多個slave通訊嗎?比如一個esp32同時跟兩塊arduino nano BLE通訊
恐怕不行,ESP32的BluetoothSerial的connect()方法,只能連接一個藍牙序列週邊。
請問有辦法分類傳輸的種類嗎? 我有兩塊板子互連,然後我想將一塊板子所測得的兩個感測器數值傳到另一塊板子上顯示出來,但我不知道如何區分出傳過來的感測器數值是水位的還是濕度的 請不吝賜教 非常感謝
1. 把數據轉成字串,然後在數據前面加上識別字,例如,控制板A的資料12.3變成”A12.3″、控制板B的資料45.6變成 “B45.6″,收到資料的一方再還原成數字。
2. 把資料包裝成JSON格式,例如:{“A”:12.3}, {“B”:45.6}。《超圖解ESP32深度實作》第七章有類似範例解說。
老師您好,我目前在做液位傳感器透過藍芽(HC-05)傳到另一個(HC-05)並顯示在電腦當中。
//發送端
#include
SoftwareSerial BT(8,9); // 接收腳, 傳送腳
char val;
void setup() {
Serial.begin(9600);
BT.begin(9600);
while (!Serial) {
;
}
}
void loop() {
{
float voltage = 40-(200.0/48*20* analogRead(A0) / (1023));
//Serial.println(voltage*100/100);
val = voltage;
Serial.println(voltage);
BT.print(val);
Serial.flush();
}
}
——————————————————–
//接收端
#include // 引用程式庫
// 定義連接藍牙模組的序列埠
SoftwareSerial BT(8, 9); // 接收腳, 傳送腳
float val; // 儲存接收資料的變數
void setup() {
// 設定HC-05藍牙模組,AT命令模式的連線速率。
Serial.begin(9600);
BT.begin(9600);
}
void loop() {
// 若收到藍牙模組的資料,則送到「序列埠監控視窗」
if (BT.available()) {
val = BT.read();
//val = BT.write();
Serial.println(val);
Serial.flush();
}
}
——————————————–
以結果來說,發送端的訊號數值在16.33上下,但接收端的數值始終只能呈現16.00,數值變動過程都僅呈現無條件捨去的數值結果,目前大致理解是char/float/string等不同字元能夠涵蓋的範圍與傳輸形式的不同,尤其我在傳輸端採用char定義val,但因為我試過其他的定義,接收端要碼出現ASCII碼,要碼出現直條的輸入
5
.
0
4
這樣的方式更新,因此想請問老師,不知道應該具體怎麼定義變數,才能順利將十位數包含兩位小數的數值準確的傳到接收端上,謝謝老師。
感測器端請改成傳送整數值(0~1023)再由接收端轉換
如果不能自動配對,嘗試 AT+PAIR=, 在HC-05
(Param1:远程设备蓝牙地址,Param2:连接超时(秒)最大配对超时 20秒)
与远程蓝牙设备:12:34:56:ab:cd:ef 配对,最大配对超时 20秒
AT+PAIR=1234,56,abcdef,20
如果 AT+PAIR 回應 FAIL ,請檢查兩個模組的密碼是否相同。
感谢您的分享!
請問主端和主端可以連接嗎?
請把其中一個設成從端
不好意思,請問我的從藍芽模組位址是98D3,61,FSC820,我在主藍芽用AT+BIND=98D3,61,FSC820,這樣就可以嗎? 還是有需要像老師您轉換成數字呢?
因為我現在照著老師的方式卻不能讓兩個藍芽相連,所以在想是不是這個問題
也許是韌體版本不同,AT命令不一樣,請參閱這篇「HC-05與HC-06藍牙模組補充說明(三)」貼文,查看韌體版本,再搜尋對應的AT命令說明文件。
我買了超圖解ESP32深度實作,我的問題也沒解決,😭,esp32與ps3斷線時電機停止運做,老師可解我問題嗎?
請問是什麼問題沒解決?PS3是指Sony PlayStation 3的無線控制器嗎?
是的老師
https://github.com/jvpernis/esp32-ps3
我的小車過遠藍芽斷線,小車還是依直往前衝,序列埠都是列印出最後連線的數值
Ps3.attachOnConnect(onConnection)為false也沒動作,很多人遇到這問題,
有人說可以用getLastMessageTime()我不會用與取值
我沒有PS3控制器,剛剛看了那個程式庫的問題討論頁,
https://github.com/jvpernis/esp32-ps3/issues
建議在Arduino開發板管理員中,選取安裝的ESP32版本不要高於1.0.5版
謝謝老師
我都有看過大家的問題都差不多一樣,老師有出millis()函数的書嗎?(arduino的書也可以)
我需要的是擷取事件發生時的時間,或最後傳送資料的時間擷取
millis()將傳回從微電腦開機到現在所經過的微秒數,我的每一本談到Arduino的書籍都有用到,它是延時處理的基礎。
請問你的主題是「藍牙無線控制小車」還是「PS3控制器訊號解析」?
因為各家遊戲機的控制器,多少都會包含廠商自訂的協議和命令,所以網路上會有一些大神以逆向工程方式解析、破解各種訊號的格式和功能。
如果你的主題不是研究PS3控制器,它也非必要、不可替代的元件,在不太理解運作原理的情況下盲目除錯,你感受到的挫折會遠大於DIY的喜悅。
或許你已經完成整個專案,只是想再加上PS3控制的功能。
如果不是的話,建議把PS3當作備案,先用手機或甚至另一個ESP32當作控制器,以藍牙或Wi-Fi方式控制小車。
謝謝老師的意見與提醒,我設計一台機器一開始使用無線PS2搖桿,案某些地方被干擾,會亂跑。後來改升級為PS3搖桿,其他都沒問題就只差距離斷線,所以現在在研究內碼(完全沒經驗),另在找如何取得PS3搖桿最後回傳訊息時間來使機器停止動作。
謝謝老師了,我找朋友的朋友C++很厲害的,幫我找到問題了,Ps3Controller.h的C語言有問題,少了斷線重置,朋友以補上,實機測試時又發現另一問題,analogWrite.h也有問題…….(analogWrite.h用在PWM)後續有機會在跟老師說
請問老師,如果需要一個主端藍芽模組連結兩個藍芽模組情況,該如何去做?
拜託老師了
HC-05藍芽模組僅支援一對一連線。