手機與Arduino藍牙串口通訊實驗及完整例程


安卓手機與Arduino之間采用藍牙串口通訊,是很多智能裝置和互動裝置常用的控制方法,簡單而有效,無需網絡環境,很實用的技術。

實驗采用Arduino UNO板,加了一塊1602LCD屏做顯示(因為只有一個串口,用來做藍牙通訊,再用串口助手不方便,也不直觀)。藍牙模塊使用十幾元一個的HC-06。一個LED接在11腳作為演示。手機端做了一個簡單的界面,有按鍵和滑動條。用按鍵控制LED點亮和熄滅,演示開關量控制。滑動條控制LED的亮度,演示模擬量控制(0-100范圍)。LCD屏實時顯示傳送的數據。模塊接線按標准接法,大家都玩過的,請參考各種教程或書籍。硬件圖片如下。

<ignore_js_op>

關於藍牙串口通訊的幾個要點:

1. Arduino的串口,print()和println()函數都是用ASCII字符的方式傳送數據,無論是int、float還是string,都自動轉換成ASCII碼傳送。其中println()函數在傳送的數據后面加了回車和換行符("\r"和"\n")。換行符正好可以作為結束符來讓手機端識別。

2. 藍牙串口是異步傳輸方式,每次Serial.read()只讀一個字節,在一個loop()循環中可能收不全一條數據信息,必須要有一個全局變量來收集接收到的字符。如果要通訊可靠,使用結束符來確定收到了一條完整的信息,是非常必要的。手機端也是一樣。

3. 例程中用的Serial.parseInt()函數,作用是在收到的字符流中,找到數字字符,並累積在一起,直到收到一個非數字字符時,將前面收到的數字字符轉換成一個整數。如果要傳送多個數值,中間用逗號等分隔符隔開即可。比如三個數值,”12,325,993“,后面加一個自定義的結束符,作為字符串發給Arduino。(例程中用字符"X”作為結束符。)這樣接收數據完整而可靠。接收float可以用Serial.parseFloat()函數,用法一樣。

安卓手機端可以用藍牙串口助手APP。但是建議自己寫一個簡單的APP,才真正完整的知道怎么通訊。再說了,如果真的做一個產品或服務,總是要自己做手機端APP的,藍牙串口助理不能當產品用。

Arduino完整例程如下。IDE 1.6.3編譯通過,運行正常。歡迎大家修改使用,完全開源。例程內有詳細注釋。

/* 本例程演示從手機藍牙串口接收指令,點亮或熄滅11腳的LED,或者調整亮度。
 
* 接收指令格式:“101X”點亮,“102X"熄滅,”000X"調整亮度。(000為0-100的整數,表示亮度值,X是結束符。)
 
* 串口是異步接收的,用parseInt()查找第一個有效整數,檢測到結束符后開始處理。
 
* 接收數據顯示在1602LCD屏上。
 
* 點亮或熄滅LED后,將收到數據回傳給手機。用pringln()函數,數據后面加了"\r"和"\n"兩個字符,可以用作結束符。
 
* 串口傳送的是ASCII字符,數據格式可以自動轉換。
 
*/
   
 
#include <Wire.h>                  // 包含LCD庫。
 
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27,16,2);  // 初始化LCD對象,地址為0x27,每行16個字符,共兩行。
 
int p;                             // 定義整數型全局變量,保存接收的數據。
   
 
void setup() {
 
  lcd.init();                      // 初始化LCD。
 
  lcd.backlight();                  // 打開LCD背光。
 
  Serial.begin( 9600);              // 打開串口(藍牙)
 
  pinMode( 11,OUTPUT);              // 定義11腳為輸出。(數字或PWM)
 
}
   
 
void loop() {
 
   while (Serial.available() > 0) {   // 串口收到字符數大於零。
 
    p = Serial.parseInt();            // 在串口數據流中查找一個有效整數。
 
    if (Serial.read() == 'X') {      // 收到結束符后開始處理數據。
 
      lcd.clear();                   // LCD清屏。
 
      lcd.print(p);                   // LCD顯示收到的數據(整數)。
 
       switch (p) {                   // 判斷數據內容。
 
       case 101:
 
        digitalWrite( 11,HIGH);       // 點亮LED。
 
        Serial.println(p);            // 回傳數據。
 
         break;
 
       case 102:
 
        digitalWrite( 11,LOW);        // 熄滅LED。
 
        Serial.println(p);            // 回傳數據。
 
         break;
 
       default:
 
        p = map(p,0,100,0,255);      // 轉換數據范圍到PWM輸出值。
 
        analogWrite( 11,p);           // 調整LED亮度。(PWM)
 
      }
 
    }
 
  }
}

機端編程用的是E4A中文安卓編程軟件,簡單省力。基本功能都是齊全的。現在版本是4.7

/* 本例程通過藍牙串口發送指令給Arduino,點亮或熄滅LED,也可以通過滑塊調整LED亮度.
 
* 手機界面上的按鍵1發送 "101X",點亮LED,按鍵2發送"102X",熄滅LED.
 
* 拖動界面上的滑塊后,發送0-100之間的整數,表示亮度值,后面加一個 "X"為結束符..
 
* 接收Arduino傳回的數據,收到 "101X",滑塊到最大位置.收到"102X",滑塊的最小位置.
 
* 藍牙串口接收是異步的,必須在收到數據事件中累積收到的ASCII字符,檢測到結束符后再處理.
 
* Arduino的println()函數發出的數據后面會加上回車和換行符,可以作為結束符使用.
 
* 處理數據時或轉換格式時,要去掉回車換行符.(字符長度要減2).
 
*/
   
 
變量 返回值 為 文本型     // 定義全局變量,保存接收數據.
 
        
 
事件 主窗口.創建完畢()        
 
    返回值 = ""
 
        如果 藍牙1.是否已開啟() = 假 則     //開啟手機藍牙.
 
                藍牙1.開啟藍牙()
 
        結束 如果
 
結束 事件
   
 
事件 藍牙1.藍牙設置完畢(設置結果 為 整數型)
 
        判斷 設置結果
 
                分支 1           //藍牙已開啟.
 
                        彈出提示( "藍牙已開啟")
 
                        藍牙1.置可被發現()           //置可被發現
 
                分支 2                         '藍牙未開啟
 
                        信息框("信息","藍牙未被開啟,程序將退出!","確定")
 
                        結束程序()
 
                分支 3                       //已置可被發現
 
                        彈出提示("藍牙已設置為可被發現")
 
                分支 4                       //不可被發現
 
                        信息框("信息","藍牙未被設置為可被發現,程序將退出!","確定")
 
                        結束程序()
 
        結束 判斷
 
        藍牙1.置工作模式(1)       //置工作模式為串口通訊.
 
結束 事件
   
 
事件 按鈕10.被單擊()
 
    藍牙1.搜索設備()          //搜索設備
 
        彈出提示("正在搜索")
 
結束 事件
   
 
事件 藍牙1.發現設備(設備名稱 為 文本型,設備地址 為 文本型,是否已配對 為 邏輯型)   //發現藍牙設備.
 
        列表框1.可視 = 真            //顯示列表框.
 
        列表框1.添加項目(設備名稱 & "_" & 設備地址 & "_" & 是否已配對)   //列表框顯示搜索到的藍牙設備.
 
結束 事件
   
 
事件 列表框1.表項被單擊(項目索引 為 整數型)            //單擊列表框選擇要通訊的設備.
 
        變量 設備信息 為 文本型
 
        變量 文本數組 為 文本型()
 
        變量 設備地址 為 文本型
 
        設備信息 = 列表框1.取項目內容(項目索引)
 
        文本數組 = 分割文本(設備信息,"_")           //可以自定義分隔符,不要與設備名稱重復即可..
 
        設備地址 = 文本數組(1)
 
        彈出提示(設備地址)
 
        藍牙1.連接設備(設備地址)           //連接設備
 
        彈出提示("正在連接")        
 
結束 事件
   
 
事件 藍牙1.連接完畢(連接結果 為 邏輯型,設備名稱 為 文本型,設備地址 為 文本型,連接模式 為 整數型)
 
        如果 連接結果 = 真 則        //已連接設備,關閉列表框顯示.
 
                列表框1.可視 = 假
 
                主窗口.標題 = "已連接:" & 設備名稱
 
                彈出提示("連接成功")
 
        否則
 
                彈出提示("連接失敗")         //連接失敗,可以點擊列表框再次連接.
 
        結束 如果
 
結束 事件
   
 
事件 藍牙1.收到數據(數據 為 字節型(),設備名稱 為 文本型,設備地址 為 文本型)    //收到串口數據
 
        返回值 = 返回值 & 字節到文本(數據,"UTF8")       //累積到文本變量中.
 
        如果  取文本右邊(返回值,1) = "\n" 則                //發現結束符后開始處理數據.
 
            判斷 取文本左邊(返回值,取文本長度(返回值)-2)     //去掉回車換行符,
 
                分支 "101"                 //滑塊到最大值.
 
                        水平滑塊條1.位置 = 100
 
                分支 "102"                 //滑塊到最小值.
 
                        水平滑塊條1.位置 = 0
 
            結束 判斷
 
                返回值 = ""        //清空接收字符串,等待下一次接收.
 
        結束 如果
   
 
結束 事件
   
 
事件 按鈕1.被單擊()        
 
        藍牙1.發送數據(文本到字節("101X","UTF8"))      //按鍵1發送.
 
結束 事件
   
 
事件 按鈕11.被單擊()            //結束按鈕點擊處理.
 
        藍牙1.發送數據(文本到字節("102X","UTF8"))     //關掉LED.
 
        藍牙1.斷開連接()            //退出處理,釋放資源,結束內部處理線程
 
        結束程序()
 
結束 事件
   
   
 
事件 按鈕2.被單擊()
 
        藍牙1.發送數據(文本到字節("102X","UTF8"))   //按鍵2發送.
 
結束 事件
   
 
事件 水平滑塊條1.停止拖動()     //滑塊動作處理.
 
        變量 數值 為 文本型
 
        數值 = 整數到文本(水平滑塊條1.位置) & "X"    //添加結束符.
 
        藍牙1.發送數據(文本到字節(數值,"UTF8"))      //發送滑塊位置數據.
 
結束 事件
   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM