当我们利用ESP32作为蓝牙mesh网关时,我们为了确保设备在不在线,需要检测设备的心跳来实现这一功能。因此设备心跳是我们不能错过的一个功能模块。

但是,ESP32的蓝牙mesh方案中对心跳的提及很少,demo中也没有,因此我们作为小白在摸索时还是比较费劲的,为了帮助各位少走弯路,特此留下此篇文章,愿诸君共享之。

收不到设备心跳时,我们不要慌张,需要一步一步排查,以下就是我找到的方法:

首先到配置文件里打开心跳接收配置

idf.py menuconfig

在代码中对应的宏定义是:

CONFIG_BLE_MESH_PROVISIONER_RECV_HB

此时,根据蓝牙mesh的demo我们可以正常追溯到

trans_heartbeat

函数,但是在该函数内调用的函数

bt_mesh_pvnr_heartbeat_recv

会被函数入口处的判断堵住

由此我们知道是因为没有注册回调函数

所以需要回到应用层蓝牙mesh回调函数注册位置注册回调函数

因为我们不知道该回调函数接口是什么,也没见demo中有过使用

所以我们需要先找到回调函数注册接口,具体寻找方法为:既然有CONFIG_BLE_MESH_PROVISIONER_RECV_HB,我们直接全局搜索,看该宏定义内是否存在带register的函数,

经过查找,我们找到了函数

bt_mesh_pvnr_register_hb_recv_cb

这里还是特别感谢乐鑫的代码规范性做得很好

找到注册函数就简单了,我们需要定义一个回调函数,根据注册函数原型

int bt_mesh_pvnr_register_hb_recv_cb(bt_mesh_pvnr_hb_recv_cb_t cb)

我们可以找到回调函数的样式

typedef void (* bt_mesh_pvnr_hb_recv_cb_t)(uint16_t hb_src, uint16_t hb_dst,
                                           uint8_t init_ttl, uint8_t rx_ttl,
                                           uint8_t hops, uint16_t feat, int8_t rssi);

由此我们只需要在应用层定义一个回调函数

void cyy_heartbeat_recv_online(uint16_t hb_src, uint16_t hb_dst,
                               uint8_t init_ttl, uint8_t rx_ttl,
                               uint8_t hops, uint16_t feat, int8_t rssi)
{
    // 在这里实现您的心跳接收处理逻辑
    // 例如:
     printf("Heartbeat received from 0x%04x to 0x%04x\n", hb_src, hb_dst);
    // 其他处理代码...
}

再在初始化mesh时注册该回调函数

bt_mesh_pvnr_register_hb_recv_cb(cyy_heartbeat_recv_online);//注册心跳包接收回调函数

此时每当设备发送心跳给网关,网关就能在应用层拿到相关信息,剩下的就是简单的数据处理工作

如果你根据我的流程没收到设备心跳,一般就是设置心跳给子设备没成功,你可以利用nrf mesh将心跳设置之后再来此验证。如果说你对心跳设置也存在疑问,也可以下方留言或者私信,需要的人多我就再写一篇关于设置心跳的文章。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐