打开主菜单

谷雨文档中心 β

更改

NRF52832DK协议栈实验

添加8,890字节2019年7月10日 (三) 12:00
实验简介
==== 实验简介 ====
经过通用扫描实验的学习,大家应该对于蓝牙的扫描和广播有一定的了解了。那么在我们实际的项目使用中,由于我们的附近可能存在的BLE设备太多,导致我们去扫描的时候,没法在第一时间找到我们想要的设备,那么这个时候,我们有没有好的处理方法呢。经过通用扫描实验的学习,大家应该对于蓝牙的扫描和广播有一定的了解了。那么在我们实际的项目使用中,可能会出现由于我们的附近可能存在的BLE设备太多,导致我们去扫描的时候,没法在第一时间找到我们想要的设备的情况,那么这个时候,我们有没有好的处理方法呢。
上面的疑问答案是肯定的,因为我们在扫描的时候,可以先判断一下扫描到的广播数据或者扫描回调数据,这样就可以找到我们的设备。nordic对这部分处理的很细心,上面的疑问答案是肯定的,因为我们在扫描的时候,可以先判断一下扫描到的广播数据或者扫描回调数据,仅返回我们需要的设备(也就是做一些数据的判断和限制),这样就可以快速的找到我们的设备。nordic对这部分处理的很细心,在BLE协议的扫描和广播中,都给我们开发者留好了限制的数据属性,我们以scan为例,可以看到限制的广播数据如下几种:名称,简称,地址,UUID以及容貌。 {{Note|text=typedef enum{ SCAN_NAME_FILTER, /**< Filter for names. */ SCAN_SHORT_NAME_FILTER, /**< Filter for short names. */ SCAN_ADDR_FILTER, /**< Filter for addresses. */ SCAN_UUID_FILTER, /**< Filter for UUIDs. */ SCAN_APPEARANCE_FILTER, /**< Filter for appearances. */} nrf_ble_scan_filter_type_t;|type=info}}
==== 实验现象 ====
主机部分,可以看到上电先打印'''1.3_ble_central_scan_filter'''字样,然后会周期打印扫描到的2.3例程的从机设备信息(MAC、扫描回调数据、RSSI)。
 
在扫描回调的数据的末尾,我们可以看到03030100的字样,这个就是我们实验限制扫描的UUID。
{{Note|text=03,// UUID数据长度
 
03,// 16bit UUID数据类型
 
01,00 // UUID 0x0001,这边是低位在前|type=info}}
[[文件:Nrf rtt 13.png|边框|居中|无框|656x656像素]]
从机部分,可以看到上电先打印'''2.3_ble_peripheral_adv_filter'''字样。
[[文件:Nrf rtt 23.png|边框|居中|无框|656x656像素]]
==== 工程及源码讲解 ====
 
===== 主机工程 =====
 
====== 工程说明 ======
本工程相对于上一章节的通用扫描实现,改动较小,只是对扫描返回的设备做出限制,不再像之前那样返回所有扫描到的设备。
 
所以我们的修改内容集中在scan_init()函数以及scan_evt_handler()回调函数当中。
 
====== scan_init()函数 ======
相对于通用扫描的主机程序,我们在限制扫描的初始化函数当中,新增了nrf_ble_scan_filter_set()函数用于限制扫描的设备,在这个例程中,我们给大家展示的是限制UUID扫描,大家也可以根据其他信息去进行限制。
 
我们限制了扫描的UUID是16bit的0x0001,并且调用nrf_ble_scan_filters_enable()使能了这个限制。<syntaxhighlight lang="c" line="1" start="65">
// 定义扫描限制的UUID
static ble_uuid_t const m_nus_uuid = {BLE_UUID_NUS_SERVICE, BLE_UUID_TYPE_BLE};
</syntaxhighlight><syntaxhighlight lang="c" line="1" start="162">
//******************************************************************
// fn : scan_init
//
// brief : 初始化扫描(未设置扫描数据限制)
//
// param : none
//
// return : none
static void scan_init(void)
{
ret_code_t err_code;
nrf_ble_scan_init_t init_scan;
 
// 清空扫描结构体参数
memset(&init_scan, 0, sizeof(init_scan));
// 配置扫描的参数
init_scan.p_scan_param = &m_scan_params;
 
// 初始化扫描
err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
APP_ERROR_CHECK(err_code);
// 设置扫描的UUID限制
err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_UUID_FILTER, &m_nus_uuid);
APP_ERROR_CHECK(err_code);
 
// 使能扫描的UUID限制
err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_UUID_FILTER, false);
APP_ERROR_CHECK(err_code);
}
</syntaxhighlight>
 
====== scan_evt_handler()回调函数 ======
大家可以看到,我们对于扫描回调的事件ID判断进行了更改,上一章的通用扫描我们的判断的是NRF_BLE_SCAN_EVT_NOT_FOUND,这一章的限制扫描我们判断的是NRF_BLE_SCAN_EVT_FILTER_MATCH。
 
由于上面的一系列对于扫描UUID的限制操作,所以我们的1.3主机实验的现象,才会仅扫描并返回给我们的2.3实验的从机设备。
 
为了给大家更直观的找到限制的UUID,我们这边临时注视掉了广播数据的打印,只保留了包含了UUID的扫描回调数据打印。<syntaxhighlight lang="c" line="1" start="102">
//******************************************************************
// fn : scan_evt_handler
//
// brief : 处理扫描回调事件
//
// param : scan_evt_t 扫描事件结构体
//
// return : none
static void scan_evt_handler(scan_evt_t const * p_scan_evt)
{
switch(p_scan_evt->scan_evt_id)
{
// 匹配的扫描数据(也就是过滤之后的)
case NRF_BLE_SCAN_EVT_FILTER_MATCH:
{
// 下面这一段我们只保留了扫描回调数据获取的部分,因为从机筛选广播的UUID在扫描回调数据
// 判断是否为扫描回调数据
if(p_scan_evt->params.filter_match.p_adv_report->type.scan_response)
{
NRF_LOG_INFO("Device MAC: %s",
Util_convertBdAddr2Str((uint8_t*)p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr));
if(p_scan_evt->params.filter_match.p_adv_report->data.len) // 存在扫描回调数据
{
NRF_LOG_INFO("scan data: %s",
Util_convertHex2Str(
p_scan_evt->params.filter_match.p_adv_report->data.p_data,
p_scan_evt->params.filter_match.p_adv_report->data.len));
}
else
{
NRF_LOG_INFO("scan data: %s","NONE");
}
NRF_LOG_INFO("rssi: %ddBm",p_scan_evt->params.filter_match.p_adv_report->rssi);
}
// else // 否则为广播数据
// {
// // 打印扫描的设备MAC
// NRF_LOG_INFO("Device MAC: %s",
// Util_convertBdAddr2Str((uint8_t*)p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr));
//
// if(p_scan_evt->params.filter_match.p_adv_report->data.len) // 存在广播数据
// {
// NRF_LOG_INFO("adv data: %s",
// Util_convertHex2Str(
// p_scan_evt->params.filter_match.p_adv_report->data.p_data,
// p_scan_evt->params.filter_match.p_adv_report->data.len));
// }
// else
// {
// NRF_LOG_INFO("adv data: %s","NONE");
// }
// }
} break;
 
default:
break;
}
}
</syntaxhighlight>
 
===== 从机部分 =====
 
====== 工程说明 ======
从机部分相对于通用广播的从机,我们也仅仅增加了UUID的广播数据。所以这边我们查看一下广播数据初始化的函数advertising_init()。
 
====== advertising_init() ======
大家可以看到,在广播数据初始化函数中,我们在init.srdata中增加了uuids_complete的定义,这样我们的广播数据中就会携带16bit的UUID 0x0001数据(这个数据在m_adv_uuids中被定义)。<syntaxhighlight lang="c" line="1" start="53">
// 定义广播的UUID
static ble_uuid_t m_adv_uuids[] = {{BLE_UUID_NUS_SERVICE, BLE_UUID_TYPE_BLE}};
</syntaxhighlight><syntaxhighlight lang="c" line="1" start="87">
//******************************************************************
// fn : advertising_init
//
// brief : 用于初始化广播
//
// param : none
//
// return : none
static void advertising_init(void)
{
uint32_t err_code;
ble_advertising_init_t init;
 
memset(&init, 0, sizeof(init));
 
// 广播数据包含所有设备名称(FULL NAME)
init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
// // 广播数据只包含部分设备名称(SHORT NAME,长度为6)
// init.advdata.name_type = BLE_ADVDATA_SHORT_NAME;
// init.advdata.short_name_len = 6;
// 扫描回调数据中包含16bit UUID:0x0001
init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
init.srdata.uuids_complete.p_uuids = m_adv_uuids;
// 扫描回调数据中包含设备MAC地址
init.srdata.include_ble_device_addr = true;
// 配置广播周期,先快速广播18s(周期40ms),再慢速广播18s(周期100ms),最后停止广播
init.config.ble_adv_fast_enabled = true;
init.config.ble_adv_fast_interval = 64; // 64*0.625 = 40ms
init.config.ble_adv_fast_timeout = 1800; // 1800*10ms = 18s
init.config.ble_adv_slow_enabled = true;
init.config.ble_adv_slow_interval = 160; // 160*0.625 = 100ms
init.config.ble_adv_slow_timeout = 18000; // 18000*10ms = 180s
err_code = ble_advertising_init(&m_advertising, &init);
APP_ERROR_CHECK(err_code);
 
ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}
</syntaxhighlight>
==== 实验总结 ====
经过这个扫描限制实验的学习,大家需要掌握的要点。
 
主机部分:
 
1.如何添加一个扫描的限制并使能
 
2.限制扫描的回调事件ID是NRF_BLE_SCAN_EVT_FILTER_MATCH
 
3.自行编程,完成通过名称、地址等其他限制的扫描
 
从机部分:
 
1.如何添加个人的广播数据,例如本章节的UUID(本质上还是广播数据的配置)
=== 白名单扫描实验 ===
510
个编辑