1. 程式人生 > >手把手教你智慧硬體開發(四) 藍芽傳輸

手把手教你智慧硬體開發(四) 藍芽傳輸

第4節 藍芽傳輸

智慧硬體基本上都需要和手機相連,然後讓手機控制這些硬體的工作。相連的方式不外乎以下三種,

  1. 資料線有線連線,通過一根資料線把智慧硬體和手機連線起來。採用這種方式,需要一個特殊的帶USB HOST功能的擴充套件板;

  2. WIFI連線,智慧硬體和手機都連線到同一個WIFI路由器上,讓彼此通過WIFI網路傳輸資料。採用這種方式需要一個WIFI模組;

  3. 藍芽連線,智慧硬體和手機通過藍芽相連。採用這種方式需要一個藍芽模組。通常情況下智慧硬體等待其他裝置的介入,而手機端會主動尋找可以連線的藍芽裝置,主動發起連線請求;

Arduino可以通過以上三種方式的任何一種實現與手機的連線。這裡我們將選擇藍芽連線。

選擇使用藍芽連線的主要原因是,Arduino藍芽模組的價格相對便宜,實現的成本低,而且程式設計很簡單。

4.1 通訊介面

Arduino開發板會提供一個至多個用於通訊用的串列埠介面。開發板與任何通訊模組的資料交換都是通過這些串列埠來完成的。

  1. UNO的串列埠硬體位置

    USB介面和0、1引腳都是對應著串列埠-Serial

  2. MEGA的串列埠硬體位置

    MEGA有多個串列埠,
    USB介面和0、1引腳對應著串列埠-Serial
    18、19引腳對應著串列埠1-Serial1
    16、17引腳對應著串列埠2-Serial2
    14、15引腳對應著串列埠3-Serial3

每一個串列埠都由一個輸入引腳(RX)和輸出引腳(TX)組成。硬體接收和傳送資料的功能,就是通過對應的引腳實現的。

4.1.1 引腳的連線

在外接的通訊模組中,至少也要有4個引腳接入開發板:輸出TX、輸入RX、電源VC、接地GND。有的通訊模組可能還有額外的引腳作為額外的控制通道,但以上4個引腳是一定會有的。

當開發板與外接通訊模組進行連線的時候,要按照如下的方式進行,

開發板引腳 連線 外接通訊模組引腳
電源VC <—> 電源VC
接地GND <—> 接地GND
輸出TX <—> 輸入RX
輸入RX <—> 輸出TX

*注意開發板和外接通訊模組相連的時候後,是TX連著RX,一個傳送,另一個當然就是接收了;並且VC/GND不和TX/RX不能接反了,不然會燒燬藍芽模組。


電源的兩根線不能接到資料傳送的兩個的引腳上,否則會燒燬藍芽模組
電源的兩根線不能接到資料傳送的兩個的引腳上,否則會燒燬藍芽模組
電源的兩根線不能接到資料傳送的兩個的引腳上,否則會燒燬藍芽模組

如此一來,開發板和外接的通訊模組就可以通過串列埠來進行通訊了。

在實際的操作當中,我們還是會使用到擴充套件板來進行引腳的連線。

4.1.2 資料的讀寫

在進行讀寫之前,要判斷一下串列埠是否可用,

if(Serial.available())
{
    //這裡面對串列埠操作才會有意義
}

當我們想在程式碼中使用這些串列埠讀取資料的時候,可以,

  1. 讀一個位元組,

    //通過UNO或MEGA的Serial讀資料,
    //讀一個位元組
    int data = Serial.read();
    
    //通過MEGA的Serial2讀資料,
    //讀一個位元組
    int data = Serial2.read();
  2. 讀到陣列緩衝區-buffer中,

    //通過UNO或MEGA的Serial讀資料,
    //讀到的資料放在buffer的空間當中,
    //返回值nRead表示成功讀取到的位元組數
    int length = 128;
    char * buffer = new char[length];
    int nRead = Serial.readBytes(buffer, length)
    
    //通過MEGA的Serial2讀資料,
    //讀到的資料放在buffer的空間當中,
    //返回值nRead表示成功讀取到的位元組數
    int length = 128;
    char * buffer = new char(length);
    int nRead = Serial2.readBytes(buffer, length)

當我們想在程式碼中使用這些串列埠傳送資料的時候,可以,

  1. 傳送一個byte,

    //通過UNO或MEGA的Serial發資料
    Serial.write('A');
    
    //通過MEGA的Serial2發資料
    Serial2.write('A');
  2. 傳送一個緩衝區的內容,

    //通過UNO或MEGA的Serial發資料
    //result表示傳送成功的byte數
    uint8_t data[] = "hello arduino";
    int len = sizeof(data);
    int result = Serial.write(data, len);
    
    //通過MEGA的Serial2發資料
    //result表示傳送成功的byte數
    uint8_t data[] = "hello arduino";
    int len = sizeof(data);
    int result = Serial2.write(data, len);

4.2 藍芽模組

藍芽模組與Arduino開發板之間就是通過串列埠進行資料傳輸的。

我們經常見到的藍芽模組有HC-05 HC-06HC-06擁有4個引腳,輸出TX、輸入RX、電源VC、接地GND。還有一種形式的藍芽模組,它就遠不止4個引腳了。

我們安豆雜貨鋪提供的藍芽模組,就是功能最為簡單的HC-06藍芽模組,它只能夠被動的接收其它藍芽模組發起的連線請求,連線時的配對密碼預設是1234

4.2.1 藍芽模組的硬體連線

這些藍芽模組的連線非常簡單。這裡我們選擇的器件有,

  • 1個MEGA開發板;
  • 1個HC藍芽模組;
  • 4根連線線;

根據之前串列埠連線的原則,我們將藍芽模組與Arduino開發板用插線連線起來。我們選擇將藍芽模組的RX TX連線到MEGA開發板的0和1引腳--使用Serial這個串列埠。

或者使用擴充套件板來連線藍芽模組,這裡我們使用HC-06舉例,將HC-06連線到MEGA擴充套件板的Serial介面上,

擴充套件板引腳 連線 藍芽模組引腳
0組V(電源VC) <—> 電源VC
0組G(接地GND) <—> 接地GND
1組S(TX) <—> 輸入RX
0組S(RX) <—> 輸出TX

當開發板通電(USB資料線連線上電腦)以後,藍芽模組的指示燈就亮了。此時它就進入了工作狀態:其他藍芽裝置就可以查詢並連線這個外接的藍芽模組了。

*注意:假如你使用的是UNO開發板,也可以按照上面的引腳進行連線,不過當D0 D1引腳被藍芽裝置佔用的時候,是不能向UNO開發板部署程式碼的。因此每當你要部署程式碼的時候,需要將D0 D1引腳斷開,部署完成後再重新連上。如果使用MEGA開發板,你就可以將藍芽接到其它的串列埠上(MEGA有多個串列埠,而UNO只有一個),避免每次刷機都要重新連線硬體。所以我們建議你最好還是採用MEGA開發板。

4.2.2 藍芽通訊的實現

接下來,我們做個簡單的程式:讓藍芽模組接受其他藍芽裝置傳送過來的資料,每次收到該資料後,又把資料原封不動的回傳給傳送裝置,

  1. setup()中,初始化好藍芽裝置的波特率,為9600,因為我們硬體連線的是Serial,所以就要初始化Serial

    void setup()
    {
        Serial.begin(9600);
    }
  2. loop()中,不停的嘗試讀取串列埠(藍芽裝置)收到的訊息,一旦收到,就通過串列埠(藍芽裝置)把收到的內容原封不動的傳送出去,

    void loop()
    {
        //如果可以讀取資料
        if (Serial.available())
        {
            //建立讀取資料用的快取
            int length = 128;
            char * buffer = new char[length];
    
            //讀取資料到buffer中
            int nReadSize = Serial.readBytes(buffer, length);
    
            //如果成功讀取到資料,就原封不動的發回去
            if(nReadSize > 0)
            {
                Serial.write(buffer, nReadSize);
            }
    
            //刪除分配的空間,避免記憶體洩漏
            delete buffer;
        } 
    }

4.2.3 結果驗證

最後我們需要一個藍芽裝置上的應用程式,來連線這個正在工作的藍芽模組,並向它傳送資料。該應用收到藍芽模組回傳的訊息後,能夠向開發者展現出來。

這裡可以使用我們另一篇文件《手把手教你做藍芽聊天應用》開發的AnddleChat來連線裝置、傳送資料、顯示接收的內容。

大家可以,

  1. 下載該部分對應的原始碼,編譯後獲取可執行的程式;

  2. 也可以使用編譯好的APK檔案,直接安裝測試。

安裝完成後,啟動應用,根據提示開啟藍芽功能,搜尋要連線的Arduino藍芽模組,選擇連線。這裡選擇搜尋到的HC-06裝置,

在文字輸入框輸入內容123456789,獲取對方接收到後到迴應,

可以看到,我們返回的資料分成了兩條:1 23456789。說明Arduino開發板在讀取藍芽串列埠的資料時,Serial.readBytes()並沒有一次把所有資料讀完,而是分兩次接收到的。

//讀取資料到buffer中時,並沒有一次將對方傳送來的資料全部讀完
int nReadSize = Serial.readBytes(buffer, length);

所以,假如Arduino開發板希望將對方傳送來的資料接收完全之後,在整個傳送回去,需要將每次讀到的資料儲存下來,直到沒有新的資料接收,然後再統一一次性的全部發送返回。

至此,Arduino通過外接藍芽模組接收和傳送資料的功能就完整的實現了。

/*******************************************************************/

本系列課程使用到的Arduino開發板、擴充套件板以及其他相關的感測器,各位可以根據我們文章中介紹的硬體在淘寶網選購。
您也可以在我們的網店跟我學Arduino程式設計中購買,這些相關硬體都由我們為您把關購買,為大家節省選擇的精力與時間。同時也感謝大家對我們這些碼農的支援。

最後再次感謝各位讀者對安豆的支援,謝謝:)

/*******************************************************************/