第09節-使用BTStack編寫藍牙程序


Bluetooth LE Exploer(微軟提供的)可以讀取BLE藍牙設備,可以讀寫它的值。本篇博客將使用BTStack寫出一個精簡版的Bluetooth LE Exploer。

涉及文件:

btstack-master\example\le_data_channel_client.c

btstack-master\example\Makefile.inc

注意:在PC上使用軟件Bluetooth LE Exploer來操作藍牙模塊時,使用系統自帶的驅動;

      使用btstack來操作藍牙模塊時,使用winusb驅動(使用zadig-2.4.exe安裝此驅動)

在手機上使用藍牙時,過程如下:

1. 掃描周邊的藍牙設備

2. 選擇某個設備,連接它

3. 使用該設備

一、程序效果:

我們寫的藍牙程序也包含這3個過程,我設計出4個菜單:

1.主菜單:

********* Main Menu *********

[s] show scan menu

[c] show connect menu

[t] show test menu

可以在主菜單中:

輸入s進入“Scan Menu”,

輸入c進入“Connect Menu”,

輸入t進入“Test Menu”。

2. 掃描菜單:

********* Scan Menu *********

[s] scan ble devices

[t] stop scan ble devices

[l] list ble devices

[q] Back to main menu

可以在掃描菜單中:

輸入s開始掃描周邊設備,掃描結果會打印出來,並在程序中保存起來;

輸入t停止掃描;

輸入l列出掃描到的設備;

輸入q退回到主菜單。

3. 連接菜單:

********* Connect Menu *********

List devices have beenn scanned

[0] 100ASK

[1] Mi Band 2

[?] Enter the device's number to connect

[d] Disconnet

[q] Back to main menu

在連接菜單的前面,會首先列出之前掃描到的設備。

在連接菜單中,

輸入所列設備的序號,就會連接它;

輸入d則斷開連接;

輸入q退回到主菜單。

4. 測試菜單:

********* Test Menu *********

[r] read att handle 42

[w] write att handle 42

[q] back to main menu

在測試菜單中,

輸入r則會讀取handle等於42的屬性的值;

輸入w則寫handle等於42的屬性的值;

輸入q退回到主菜單。

注意

之所以固定讀寫handle 42是為了簡化程序,

42這個值是事先使用軟件Bluetooth LE Explorer連接設備后確定的,你的設備可能有所不同。

二、程序演示:

啟動MSYS2 MinGW 64-bit,進入btstack-master/port/windows-winusb目錄:

1. 執行 make 命令編譯程序

2. 執行以下命令啟動程序:

winpty  ./le_data_channel_client.exe

注意:在MSYS2下Windows的stdin無法使用,必須通過winpty來啟動程序。

3. 在主菜單中:輸入s進入掃描菜單

4. 在掃描菜單中:輸入s開始掃描設備

在手機上,啟動“Bluetooth LE Peripheral”,選擇“100ASK”,點擊“START”按鈕。

這時在MSYS2中可以看到不斷打印如下信息(這表示不斷收到手機發來的廣播信號):

advertisement_report_gets_name get 100ASK

 

5. 在掃描菜單中:輸入t停止掃描設備

6. 在掃描菜單中:輸入q退回到主菜單

7. 在主菜單中:輸入c進入連接菜單

8. 在連接菜單中:輸入0表示連接第掃描到的第0個設備

9. 在連接菜單中:輸入q退回到主菜單

10. 在主菜單中:輸入t進入測試菜單

11. 在測試菜單中:輸入w寫數值

觀察手機上“Bluetooth LE Peripheral”的Service-1中收到的值。

不斷輸入w,可以觀察到手機上收到的值不斷加1。

12. 在測試菜單中:輸入r讀取數值

13. 在測試菜單中:輸入q退回到主菜單

14. 在主菜單中:輸入c進入連接菜單

15. 在連接菜單中:輸入d斷開連接

三、主要函數:

本程序主要源文件是btstack-master\example\le_data_channel_client.c,我在上面做了大量的修改。

1.要用鍵盤來控制程序,需要給程序增加一個“數據源”,即btstack_data_source_t結構體。

這個數據源從stdin獲得數據,根據這些數據進行菜單操作。

使用如下代碼增加數據源:

btstack_stdin_setup(stdin_process);

stdin_process是我們編寫的處理函數。

2. 啟動掃描:

printf("Start scanning!\n");

state = TC_W4_SCAN_RESULT;

gap_set_scan_parameters(0,0x0030, 0x0030);

gap_start_scan();

3. 記錄打描結果:

掃描到的設備會上報3種信息:MAC地址、地址類型、名。我們要從上報的信息中取出這些信息,記錄起來。

使用函數gap_event_advertising_report_get_address獲得地址;

使用函數gap_event_advertising_report_get_address_type獲得地址類型;

使用函數advertisement_report_gets_name獲得名字(這函數是我從advertisement_report_contains_name改出來的)。

這3個信息會保存在ble_devs結構體數組中。

4. 連接設備:

gap_connect(ble_devs[i].le_data_channel_addr, ble_devs[i].le_data_channel_addr_type);

gap_connect函數只需要2個參數:MAC地址、地址類型。

連接成功后會返回一個hci_con_handle_t,也就是一個16位的整數。

一個中央設備可以連接多個外設,每一個連接都用一個hci_con_handle_t來分辨。

5. 斷開連接:

gap_disconnect(connection_handle);

6. 寫數據:

gatt_client_write_value_of_characteristic_without_response(connection_handle, 42, 1, &g_value);

第1個參數表示要寫哪一個設備,用connection_handle 來表示(哪一個連接對應的設備);

第2個參數表示要寫哪一個屬性,每一個屬性也都有一個標號即handle;

第3個參數表示要寫多少字節的數據;

第4個參數表示數據的buffer。

7. 讀數據:

gatt_client_read_value_of_characteristic_using_value_handle(handle_gatt_client_event,connection_handle, 42);

第2個參數表示要寫哪一個設備,用connection_handle 來表示(哪一個連接對應的設備);

第3個參數表示要寫哪一個屬性,每一個屬性也都有一個標號即handle;

第1個參數比較特殊:讀數據時,要先向外設備發出無線信號,過一會收到對方發回到信號后,才可以解析出數據。所以讀函數不可能立刻返回結果,我們需要提供一個回調函數。第1個參數就是一個回調函數。

在回調函數中,我們去解析數據,從中取出我們關注的數值。

回調函數handle_gatt_client_event源自btstack-master\test\pts\Ble_central_test.c,我做了一些精簡。


免責聲明!

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



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