1. 簡介
BLE Scanner是一個常見的BLE Central應用。本文介紹了如何使用YoC藍牙協定棧和CH6121開發闆進行BLE Scanner應用開發的過程。
2. 應用開發
BLE Scanner應用主要實作了藍牙裝置的發現、連接配接、BLE Profile的發現以及操作。示例程式中通過掃描HRS裝置,并與之建立連接配接通信,展示了BLE Central應用的主要工作流程。BLE Scanner應用的主要工作流程分為:
- 應用初始化
- 藍牙協定棧事件處理
- HRS服務及特征發現
- 特征操作
2.1. 應用初始化
應用入口函數app_main(),主要實作如下功能:
- 藍牙協定棧的初始化,配置MAC位址及類型
- 注冊藍牙協定棧事件回調處理函數
- 開啟掃描
代碼分析:
int app_main(int argc, char *argv[])
{
/* 定義裝置MAC位址以及位址類型 */
dev_addr_t addr = {DEV_ADDR_LE_RANDOM, DEVICE_ADDR};
/* 藍牙協定棧初始化參數設定 */
init_param_t init = {
.dev_name = DEVICE_NAME,
.dev_addr = &addr,
.conn_num_max = 1,
};
/* 闆級初始化,各業務子產品初始化 */
board_yoc_init();
......
/* 藍牙協定棧初始化 */
ble_stack_init(&init);
/* 注冊藍牙協定棧事件回調函數 */
ble_stack_event_register(&ble_cb);
/* 開始掃描 */
scan_work(NULL);
while (1) {
aos_sem_wait(&sync_sem, 2000);
if (g_mtu_exchanged) {
/* MTU協商成功後,開始HRS服務發現*/
ble_stack_gatt_discovery_primary(g_conn_handle, UUID_HRS, 0x0001, 0xFFFF);
g_mtu_exchanged = 0;
}
/* 連接配接失敗則2秒後重新開始掃描 */
if (g_conn_handle == -1) {
scan_work(NULL);
}
}
return 0;
}
2.2. 藍牙協定棧事件處理
藍牙協定棧的事件是通過event_callback()回調函數上報,應用程式需要對這些事件進行相應的處理:
- 藍牙裝置發現事件
- 連接配接成功或失敗事件
- MTU協商請求事件
- 服務及特征發現事件
- GATT Read、Write回調事件
- GATT Notify事件
static int event_callback(ble_event_en event, void *event_data)
{
switch (event) {
/* 裝置發現事件,使用者可決定是否發起連接配接請求 */
case EVENT_GAP_DEV_FIND:
device_find(event, event_data);
break;
/* 連接配接成功或失敗事件 */
case EVENT_GAP_CONN_CHANGE:
conn_change(event, event_data);
break;
/* MTU協商事件 */
case EVENT_GATT_MTU_EXCHANGE:
mtu_exchange(event, event_data);
break;
/* 服務發現事件 */
case EVENT_GATT_DISCOVERY_SVC:
case EVENT_GATT_DISCOVERY_CHAR:
case EVENT_GATT_DISCOVERY_CHAR_DES:
case EVENT_GATT_DISCOVERY_COMPLETE:
service_discovery(event, event_data);
break;
/* 屬性寫操作事件 */
case EVENT_GATT_CHAR_WRITE_CB: {
evt_data_gatt_write_cb_t *e = event_data;
LOGI(TAG, "GATT write %s", e->err ? "FAIL" : "SUCCESS");
break;
}
/* 屬性讀操作事件 */
case EVENT_GATT_CHAR_READ_CB: {
evt_data_gatt_read_cb_t *e = event_data;
char val_str[10] = {0};
hex_to_str((uint8_t *)val_str, (uint8_t *)e->data, e->len);
LOGI(TAG, "GATT read %s", val_str);
break;
}
/* GATT通知事件 */
case EVENT_GATT_NOTIFY: {
evt_data_gatt_notify_t *e = event_data;
char val_str[10] = {0};
hex_to_str((uint8_t *)val_str, (uint8_t *)e->data, e->len);
LOGI(TAG, "GATT notify %s", val_str);
break;
}
default:
LOGW(TAG, "Unhandle event %x\n", event);
break;
}
return 0;
}
2.2.1. 裝置發現事件
發現藍牙裝置後,發起連接配接請求前,需要先停止廣播,處理流程如下圖:

2.2.2. 服務發現事件
HRS服務發現處理流程如下圖:
- 發現HRS服務的Primary Service,藍牙協定棧将傳回查詢結果。成功發現Primary Service後,需要記錄HRS服務的開始和結束句柄。
- 發現HRS服務的所有特征,藍牙協定棧将周遊所有的特征,并一一傳回查詢結果。全部特征查詢完畢後,将傳回EVENT_GATT_DISCOVERY_COMPLETE事件。
- 發現HRS服務的所有特征描述符,藍牙協定棧将周遊所有的特征描述符,并一一傳回查詢結果。全部特征描述符查詢完畢後,也是傳回EVENT_GATT_DISCOVERY_COMPLETE事件。
- 開始進行GATT Read、Write操作。
2.2.3. 心率值更新事件
HRS服務及特征成功發現後,設定HRS服務中的Measurement特征屬性為Notify,允許HRS裝置主動上報Measurement特性,這時可以開始接收HRS裝置的心率資料更新了。
處理流程如下圖:
- 執行GATT Read操作,讀取HRS裝置的心率資料
- 藍牙協定棧上報GATT Notify操作,應用程式接收HRS裝置發送的心率資料
3. 例程運作
以CH6121開發闆為例,BLE Scanner示例程式的運作步驟為:
- 連接配接序列槽調試工具, 配置為 波特率: 115200, 資料位: 8, 校驗位: None, 停止位: 1, 流控: None
- 開發闆撥碼開關撥至GND
- 按RESET按鍵,複位開發闆
- BLE Scanner開始掃描後,将在序列槽上輸出'scan start'資訊
boot_v1.4
[ 0.004000][I][INIT ]Build:Aug 2 2019,20:18:49
[ 0.023000][D][MTB ]mtb find 0x11005000
[ 0.042000][I][INIT ]find 9 partitions
[ 0.779000][I][DEMO ]Bluetooth scanner demo!
[ 1.558000][W][AOSBT ]bt_pub_key_gen:ECC HCI commands not available
[ 2.182000][I][DEMO ]scan start!
- BLE Scanner發現'YoC HRS'裝置并成功連接配接
[ 3.487000][I][DEMO ]find device YoC HRS
[ 3.512000][I][DEMO ]find device c0:bf:88:e3:3b:cc|(type 1),ADV_CONNECTABLE,02010603030d180809596f4320485253
[ 3.559000][I][DEMO ]Connected, conn handle 0
- BLE Scanner成功發現HRS服務及特征
[ 3.814000][I][DEMO ]find service HRS, start handle c, end handle 13
[ 4.015000][I][DEMO ]HRS CHAR handle d, val handle e
[ 4.116000][I][DEMO ]HRS DES handle f, UUID 0229
[ 4.217000][I][DEMO ]HRS service discovery complete
- BLE Scanner列印'GATT notify'表示收到來自HRS裝置的心率資料
[ 4.418000][I][DEMO ]GATT write SUCCESS
[ 4.520000][I][DEMO ]GATT notify 008a
[ 16.947000][I][DEMO ]GATT notify 003e
[ 17.952000][I][DEMO ]GATT notify 003f
- 另一塊CH6121開發闆運作HRS裝置示例程式,發送廣播包,裝置名為'YoC HRS'
- HRS裝置列印'data'顯示間隔1秒重新整理一次心率資料
[ 0.777000][I][DEMO ]Bluetooth HRS demo!
[ 1.133000][I][DEMO ]DEV_NAME:YoC HRS
[ 2.534000][I][DEMO ]hrs adv start!
[ 2.730000][I][DEMO ]Connected
[ 2.784000][I][DEMO ]mtu exchange, MTU 247
[ 3.565000][D][HRS ]data:3e
[ 4.580000][D][HRS ]data:3f
HRS裝置應用的示例代碼請見下回分曉~
原文作者:qinghuan
點選檢視原文添加班級群
閱讀完今日份的文章分享後,别忘了打開釘釘APP,掃描下方訓練營班群二維碼👇,參與今日課程直播或觀看直播回放,群内不定時配備講師答疑~
學習完課程視訊後,我們今天的學習才算正式結束哦~