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地址及类型
- 注册蓝牙协议栈事件回调处理函数
- 开启扫描
- HRS服务及特征发现
代码分析:
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,扫描下方训练营班群二维码👇,参与今日课程直播或观看直播回放,群内不定时配备讲师答疑~
学习完课程视频后,我们今天的学习才算正式结束哦~