NRF52840开发笔记:定向直连

记录在 NRF52840 项目中使用定向直连广播模式实现设备定向连接的思路与代码。

一、需求

毕设项目里面需要实现在每个设备成功交换信息之后,从机需要选择一个综合指标最好的设备进行连接,一开始想的是在主机端进行处理,但大规模的设备组网对从机和主机的负担都很大。最简单最好的办法是从机使用定向直连的广播模式与目标主机设备进行连接。

二、代码实现

1. 广播初始化

SDK中的广播方式是递进的,顺序为 Direct High Duty -> Direct -> Fast -> Slow -> Idle。如果开启广播时选择 Direct 模式,即代码 ble_advertising_start(&m_advertising, BLE_ADV_MODE_DIRECTED),但是未在初始化时设置 Direct 模式的相关参数,那么它就会尝试 Fast 模式,如果初始化时 Fast 模式的相关信息也没设置,就会再尝试 Slow 模式,如果初始化时 Slow 模式相关信息也没设置最后就直接进入到 Idle 模式了。在我的广播初始化中,我只初始化了 Direct 和 Fast 两个模式的参数。

2. 广播回调函数

在程序的 while(1) 开始前,我调用 ble_advertising_start(&m_advertising, BLE_ADV_MODE_DIRECTED) 开启广播,在广播回调函数中会抛出 BLE_ADV_EVT_PEER_ADDR_REQUEST 的请求。然而在开始时,还没有获得需要连接的设备的对等地址,所以全局变量 direct_peer_adr 还未赋值,则不会执行 ble_advertising_peer_addr_reply(&m_advertising, &direct_peer_adr)。此时会跳过 Direct 模式的广播,直接进入 Fast 广播模式。

下面是系统程序开始时,从机端输出的 RTT 日志信息:

从机端 RTT 日志

3. 扫描回调函数

对于从机而言,扫描到可连接的广播数据后,判断广播数据的对等设备是否是自己需要连接的,为了测试,我这里使用了简单的判断 if(p_adv->peer_addr.addr[0] < DEVICE_ID),如果满足条件,就把变量 direct_peer_adr 赋值为需要连接设备的对等地址。关闭后又打开广播是因为让广播从定向广播模式开始,在对等地址请求时会成功执行 ble_advertising_peer_addr_reply(&m_advertising, &direct_peer_adr) 而进入直连广播模式。

对于需要被连接的主机而言,从机发送定向广播后,会收到 directed 定向广播数据。需要注意的是,如果开启了扫描过滤,定向数据是不会出现在 NRF_BLE_SCAN_EVT_FILTER_MATCH 里的,而是出现在 NRF_BLE_SCAN_EVT_NOT_FOUND 里,这里我卡了很久!最后调用连接函数连接即可。此外,直连模式的广播是无法被 Sniffer 捕捉到的,因此我在没有收到直连数据时尝试过这个方法,后来才发现是在 NRF_BLE_SCAN_EVT_NOT_FOUND 里。

下面是直连时,主机和从机输出的 RTT 日志信息,从机通过判断条件设置了需要连接的对等地址,并重新开始广播使得定向广播成功开启。主机在扫描回调函数中,匹配项里发现了可连接非定向的数据,未匹配项里发现了定向数据,选择连接,并发现了自定义的 sns 服务。

主机输出:

主机输出 RTT 日志

从机输出:

从机输出 RTT 日志

评论区

评论加载中...