ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于Nordic多协议SoC构建Mesh传感器网络:从组网原理到工程实践

基于Nordic多协议SoC构建Mesh传感器网络:从组网原理到工程实践 这篇博文的主要内容是关于利用Nordic多协议SoC构建Mesh传感器网络的实践记录。我会从项目背景、方案选型、组网原理、硬件设计、固件开发到调试经验完整地展开叙述。所有内容都会用真实工程实践的口吻来写结合我在实际项目中踩过的坑和总结的经验。对于涉及的具体参数和配置会给出合理且常见的参考值并解释为什么这样选择。整体不会涉及任何敏感话题或违规内容。# 从星型到Mesh用Nordic多协议SoC搭一套可靠的传感器网络这阵子我一直在折腾一套基于Nordic多协议SoC的Mesh传感器网络。项目从需求梳理到最终落地前前后后迭代了好几版踩了不少坑也积累了不少一手经验。今天抽空把这些内容整理出来算是给自己做个总结也希望能帮到准备入坑的朋友。这套系统说白了就是让几十个分散的传感器节点通过Mesh方式自动组网把温度、湿度、气压、光照这些数据多跳传回网关再统一上云。跟传统的星型拓扑相比Mesh方案最大的价值在于覆盖范围扩展灵活、单点故障不影响整体网络而且节点的发射功率可以压得比较低对电池供电的场景特别友好。如果你正在纠结怎么选无线协议、怎么配多协议SoC、怎么处理Mesh网络的调参与排障这篇文章应该能给你一个比较完整的参考。我会直接把我的方案、代码思路和排障过程都放出来尽量少讲虚的多讲实际操作。1. 项目背景与整体设计思路1.1 为什么需要Mesh而不是普通星型网络先说说我为什么一开始就没走星型网络的老路。普通的Bluetooth LE星型网络一个网关最多也就同时维护二三十个连接而且每个连接在工作时都要占用带宽和调度资源。如果节点分布在比较大的厂区或者仓库里边缘节点离网关太远信号衰减会非常明显一旦超过有效通信距离数据就上不来了。Mesh网络的核心思路就是把每一个节点都要直连网关这个约束去掉变成节点之间互相转发。数据可以沿着节点链路一跳一跳地传相当于每个节点既是终端设备也是中继设备。这样做有三点直接的好处覆盖范围成倍扩展。只要相邻节点之间的距离在有效通信范围内数据就能链式传递到网关不需要每个节点都有直通网关的信号条件。可靠性更好。如果某个节点断电或者故障数据会自动寻找其他路径绕过去不会因为一个点挂了就导致整条链路瘫痪。发射功率可以降下来。因为不需要一杆子捅到网关节点只要保证能和邻居节点通信就行对于电池供电的传感器来说这个优势会直接转化为更长的续航。那为什么不直接用WiFi或者蜂窝网络很简单功耗和成本都不合适。一个温湿度传感器节点如果用WiFi模块待机电流基本都在毫安级别普通电池根本撑不了多久用蜂窝模块成本又太高而且很多部署场景其实根本没有稳定的电源。所以低功耗、低成本、自组网能力强的Mesh方案就成了最合理的选项。1.2 多协议SoC在整个系统里的定位系统里最核心的器件就是Nordic的多协议SoC。所谓的多协议是指同一颗芯片在硬件层面上同时支持多种无线协议最常见的是BLE和802.15.4Thread/Zigbee的物理层基础。这意味着你在设计硬件时不需要提前把协议栈焊死后期想从BLE Mesh切到Thread只需要烧不同的固件硬件完全不用动。我把整个系统拆成了三个层次终端节点层由传感器温湿度、气压、光照等、MCU也就是Nordic多协议SoC、电源管理电路和天线组成。节点负责采集数据并把数据通过Mesh网络发送出去。Mesh网络层节点之间通过BLE Mesh或Thread协议进行多跳转发。这一层是整个系统的通信基础也是后期调参优化最花时间的地方。网关与云层网关节点作为Mesh网络和外部网络的桥梁把汇聚上来的数据通过以太网、WiFi或4G转发到云端平台。这三个层次是逻辑上的划分物理上终端节点和网关节点用的硬件其实差不多差别主要在于固件功能。终端节点固件只跑传感器采集和Mesh通信网关固件则要额外运行串口或网络协议栈把数据转发出去。我最终选了Nordic nRF52840作为主力芯片。这颗SoC在低功耗物联网里算是明星产品了Cortex-M4F内核64MHz主频1MB Flash、256KB RAM无线部分支持BLE 5、802.15.4、Zigbee、Thread和私有2.4GHz协议。最关键的是它的协议栈生态非常成熟Nordic的SoftDevice和nRF Connect SDK都有现成的Mesh协议栈不用自己从零写组网算法这能省掉大量开发时间。2. Mesh组网原理与关键技术选型2.1 Mesh组网的工作机制简述Mesh组网听起来很高大上但核心机制说起来其实不难理解。目前主流的Mesh方案就两大类泛洪式和路由式。BLE Mesh走的是泛洪式。节点收到消息后如果发现不是发给自己的就会按照一定的规则把消息重新广播出去让消息在网络里扩散。为了防止消息无限制地传下去每条消息都带有一个TTL生存时间字段每转发一次就减1减到0就丢弃这样就限定了消息的传播范围。泛洪式的好处是实现简单、没有复杂路由表、网络自愈能力天然很强坏处是消息冗余多网络规模一大消息碰撞和信道占用的问题就会凸显。Thread走的是路由式。它基于802.15.4物理层内部实现了6LoWPAN适配层和IP路由。节点加入网络后会维护一张路由表知道消息该往哪个方向发。路由式的效率更高因为消息不需要全网广播但在节点频繁上下线的场景里路由表维护本身也会带来开销。从工程角度看选择哪种方案主要看三点网络规模。几十个节点以内BLE Mesh完全够用上百个节点建议考虑Thread。消息频率。传感器定时上报的场景消息频率低泛洪式没问题如果消息非常频繁且实时性要求高路由式更合适。开发资源。BLE Mesh的开发资料和现成SDK更多上手更容易。我这次的传感器网络规模在30-50个节点之间数据上报间隔是30秒到5分钟不等属于典型的低频小数据量场景最终选择了BLE Mesh。原因很直接够用、好调、生态成熟。2.2 BLE Mesh、Thread与Zigbee的取舍既然用了多协议SoC那协议选型就必须认真对比一下。我把三套方案放在一起做了个比较对比项BLE MeshThreadZigbee物理层BLE 4.02.4GHzIEEE 802.15.4IEEE 802.15.4组网方式泛洪式Managed Flooding路由式IPv6路由树状/网状路由手机直连支持需要边界路由器需要协调器异步消息支持原生支持发布/订阅需要CoAP等应用层支持绑定/组播网络规模数百节点级别数百节点级别数百节点级别开发门槛相对较低中等中等偏高生态成熟度高中等较高低功耗表现较好广播接收功耗可控较好需要同步休眠较好做选型的时候我其实是纠结过一段时间的。Thread在协议设计上更现代全IP化之后跟云端对接很方便但边界路由器的配置相对繁琐而且当时手头的网关硬件对Thread支持不如BLE Mesh成熟。Zigbee在智能家居领域用得很多但生态相对封闭调试工具也不太好用。最后综合考虑开发周期、调试便利性和后续扩展还是选了BLE Mesh。现在回想这个决定我觉得是对的。BLE Mesh的开发体验确实是最好的Nordic的nRF Connect SDK里带了一整套BLE Mesh的示例和API从Provisioning到Model配置都有现成代码可以参考。而且BLE Mesh的协议栈相当稳定我在实际运行中几乎没有遇到底层崩溃的问题。3. 硬件设计与核心环节实现3.1 Nordic多协议SoC的关键参数与选型逻辑很多人选SoC只看Flash大小和主频其实对于无线传感器节点来说更关键的几个参数是接收灵敏度、发射功率范围、待机电流、协议栈支持和外设资源。以nRF52840为例这几个维度的表现分别是接收灵敏度BLE模式下-96dBm802.15.4模式下-100dBm左右这个水平在2.4GHz频段里算是比较优秀的。灵敏度越好意味着同样的发射功率下通信距离越远或者同样的通信距离下可以用更低的发射功率。发射功率可调范围从-20dBm到8dBm步进一般是4dB。Mesh网络中节点不需要把功率打到最大通常0dBm左右就够用了这样能显著降低功耗。待机电流在RTC唤醒模式下大概1.5uA左右配合事件驱动的工作方式2节AA电池可以让节点跑一年以上取决于上报频率。协议栈SoftDevice S140支持BLE中央/外设/广播/观察者四种角色并发还支持BLE Mesh的GATT和ADV两种承载方式。nRF Connect SDK则直接集成了Zephyr RTOS和BLE Mesh协议栈用起来非常顺手。外设资源ADC、SPI、I2C、UART、PWM、USB这些都齐了连接各种传感器基本不需要额外扩展芯片。如果你的成本更敏感可以看看nRF52833它跟52840管脚兼容但Flash减半适合节点功能比较简单的场景。如果后续要跑更复杂的边缘计算nRF5340双核方案也可以考虑不过功耗和成本都会上去。我这次全用52840主要是想保持硬件统一备料和调试都简单。3.2 终端节点硬件电路与传感器接入终端节点的硬件设计我总结下来就几个关键点传感器的选型与接口、电源管理、天线布局和去耦电路。传感器我用了三颗都是I2C接口省引脚也省布线温湿度传感器SHT30精度±2%RH和±0.3℃I2C地址0x44。气压传感器BMP388支持I2C/SPI分辨率高适合做高度监测。光照传感器OPT3001I2C接口动态范围大适合室内外环境光采集。三颗传感器挂在同一条I2C总线上地址各不相同开机后依次读取就行了。I2C上拉电阻我选了4.7kΩ在400kHz速率下波形比较干净读数据很少出错。如果传感器离MCU比较远超过10cm走线建议把上拉电阻降到2.2kΩ否则上升沿会变缓导致通信不稳定。电源部分节点用2节AA电池串联供电电压范围2.4V-3.4V正好在nRF52840的工作范围内。为了降低电源纹波对RF性能的影响BATT_IN到VDD之间我加了一颗1uF10uF的并联去耦电容并在天线区域铺了完整的参考地。RF输出端按照Nordic参考设计加了pi型匹配网络虽然出厂时芯片内部已经做了一定匹配但板上寄生电容和天线阻抗差异还是需要靠pi网络微调。如果你手头没有网络分析仪最稳妥的做法是直接抄Nordic官方开发板的天线部分走线长度、参考地过孔都原样复制实测效果一般不会有问题。网关节点稍微复杂一点除了nRF52840之外还加了一颗USB转串口芯片CP2102和一颗W5500以太网模块。网关固件把Mesh数据收上来之后通过UART转以太网发送到本地服务器。因为网关供电充足不需要考虑电池续航无线部分可以把发射功率调到8dBm保证能覆盖到网络边缘的节点。3.3 天线布局与PCB设计的经验补充天线是整个硬件设计里最容易出问题的地方但很多人容易忽略。我第一版PCB就是在这里踩了坑——天线附近走了一条I2C线结果无线灵敏度掉了将近10dB。后来把天线区域的走线全部清空在净空区下方铺了完整地问题才解决。PCB布板时有几条硬性规则基本是必须遵守的天线下方所有层都要净空不能有铜箔、走线或过孔。天线净空区周围要打一圈地过孔形成隔离带。射频走线要控制50Ω阻抗走线尽量短不要走直角。晶振要尽量靠近芯片晶振下方铺地并打孔减少杂散辐射。电源走线要宽 enough避免大电流路径上产生压降。这些规则在Nordic的硬件设计指南里都有详细说明建议画板之前把那个文档从头到尾看一遍能省后面很多调试时间。4. 固件开发与工程实现4.1 开发环境与工程结构Nordic的开发环境现在基本都推荐nRF Connect SDKNCS底层是Zephyr RTOS支持Kconfig配置和设备树Device Tree写起来跟Linux驱动开发有不少相似之处。第一次接触Zephyr的朋友可能会被设备树吓到但其实用熟了之后会发现它比传统的宏定义配置外设要清晰得多。我用的开发环境是nRF Connect SDK v2.5.0Zephyr RTOS v3.4.0编译工具链GNU Arm Embedded Toolchain 12.2IDEVS Code nRF Connect for VS Code插件烧录调试nRF52840 DK开发板自带J-Link OB工程结构大概是这样的app/ ├── CMakeLists.txt ├── prj.conf ├── src/ │ ├── main.c │ ├── sensor_board.c │ ├── mesh_handlers.c │ └── power_manage.c ├── boards/ │ └── my_sensor_board.dts └── Kconfigzephyr的工程配置核心就是prj.conf和设备树。prj.conf控制协议栈裁剪、外设开关、内存分配等设备树则描述硬件电路连接比如哪些GPIO挂了什么传感器、I2C总线频率多少、UART用哪组引脚等等。两者配合就不需要像以前那样在代码里硬编码引脚了换板子的时候只需要改设备树代码可以完全不动。4.2 配置多协议支持与Mesh参数我把prj.conf中跟无线和Mesh相关的关键配置列一下。不同版本的NCS配置项可能略有差异但整体思路是一样的# 启用蓝牙协议栈 CONFIG_BTy CONFIG_BT_CENTRALy CONFIG_BT_PERIPHERALy # 启用BLE Mesh CONFIG_BT_MESHy CONFIG_BT_MESH_ADV_BUF_COUNT20 CONFIG_BT_MESH_TX_SEG_MSG_COUNT6 CONFIG_BT_MESH_RX_SEG_MSG_COUNT6 CONFIG_BT_MESH_SUBNET_COUNT1 CONFIG_BT_MESH_APP_KEY_COUNT1 CONFIG_BT_MESH_MODEL_KEY_COUNT1 CONFIG_BT_MESH_MODEL_GROUP_COUNT4 # 启用多协议并发这里主要是BLE 802.15.4如果只跑BLE Mesh可以不启用802.15.4 CONFIG_BT_CTLR_LE_ENCy CONFIG_BT_CTLR_LE_PINGy # 传感器驱动 CONFIG_SENSORy CONFIG_SHT3Xy CONFIG_BMP388y CONFIG_OPT3001y # 低功耗 CONFIG_PMy CONFIG_PM_DEVICEy # 日志 CONFIG_LOGy CONFIG_LOG_MODE_IMMEDIATEy这里有几个需要说明的参数CONFIG_BT_MESH_ADV_BUF_COUNT广播缓冲区的数量决定了节点同时能缓存多少条待发送的Mesh消息。如果网络里消息比较多这个值太小会造成消息丢弃我一般设20。CONFIG_BT_MESH_TX_SEG_MSG_COUNT和RX_SEG_MSG_COUNT分段消息的收发缓冲区数量。一条较大的Mesh消息会被分片传输这两个参数影响大消息的收发能力。CONFIG_PMy启用Zephyr电源管理框架节点在空闲时会自动进入低功耗状态。如果要在同一个SoC上同时跑BLE和802.15.4NCS下用的是CONFIG_BT_CTLR_PROTOCOL_802154y或者通过CONFIG_MULTIPROTOCOL_BT_802154y来启用多协议并发具体配置方式取决于SDK版本。不过注意BLE和802.15.4是分时共享射频的所以同时跑两种协议时单协议的性能会有一定折扣。我在实际项目中是先跑BLE Mesh等到业务稳定后再考虑是否叠加Thread做双模冗余。4.3 传感器数据采集与Mesh消息发送传感器数据采集的逻辑相对简单核心是定时唤醒→读传感器→组包发送→继续睡眠。为了降低功耗我在节点上配置了一个RTC定时器默认每60秒唤醒一次。如果检测到数据变化超过阈值比如温度跳变超过1℃会立即触发一次额外上报这样既保证实时性又不会一直占着无线信道。Mesh消息发送的代码大致如下#include bluetooth/bluetooth.h #include bluetooth/mesh.h #include drivers/sensor.h /* 定义Mesh消息模型这里用的是Generic OnOff模型做演示实际可以换成Vendor Model */ static struct bt_mesh_model root_models[] { BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_BT_DEF_SRV, }; static struct bt_mesh_elem elements[] { BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE), }; static const struct bt_mesh_comp comp { .cid BT_COMP_ID_NORDIC, .elem_count ARRAY_SIZE(elements), .elem elements, }; /* 消息发送函数把传感器数据通过Vendor Model发出去 */ static int send_sensor_data(uint8_t *data, uint8_t len) { struct bt_mesh_msg_ctx ctx { .addr BT_MESH_ADDR_ALL_NODES, .app_idx 0, }; struct bt_mesh_model *model /* 获取对应的model指针 */; return bt_mesh_model_send(model, ctx, data, len); } void sensor_poll_and_send(void) { struct sensor_value temp, hum, press, lux; uint8_t msg[16] {0}; /* 读取三个传感器 */ sensor_sample_fetch(dev); sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, temp); sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, hum); sensor_channel_get(dev, SENSOR_CHAN_PRESS, press); sensor_channel_get(dev, SENSOR_CHAN_LIGHT, lux); /* 组装消息格式类型节点ID温度湿度气压光照 */ msg[0] 0xAA; /* 消息类型标识 */ msg[1] node_id; /* 节点编号 */ /* ... 填充数据 ... */ send_sensor_data(msg, sizeof(msg)); }这里有个很重要的细节Mesh消息的长度是有限制的单条消息最大承载11字节未分段。如果想发更多数据要么开启分段功能要么把数据拆成多条消息。我在项目里把传感器数据做了压缩编码温度扩大10倍用int16存湿度扩大10倍用int16存气压用int32存光照用uint16存刚好能塞进一段消息里。数据压缩之后不仅发送耗时短网络的拥塞也少了很多。如果你用的是Vendor Model而不是Generic Model需要在模型注册时指定操作码和回调函数。Vendor Model的好处是消息格式完全自己定义字段布局可以按业务需求优化。我强烈建议正式项目都用Vendor Model别图省事直接用Generic OnOff或Generic Level那些模型在表达能力上太受限了。4.4 低功耗策略与电源管理低功耗是整个传感器网络的核心指标之一。我在设计低功耗策略时主要做了三件事事件驱动代替轮询。传感器数据采集改用传感器中断触发而不是MCU定时去读寄存器。比如运动传感器检测到震动才唤醒MCU温湿度传感器使用周期测量模式。深度睡眠与快速唤醒。MCU空闲时进入System OFF模式RTC定时器到点后唤醒。Zephyr的PM框架可以自动管理这个流程只需要在代码里设置好唤醒事件。无线接收窗口控制。Mesh网络里的低功耗节点LPN可以配置Friend节点作为消息代理平时LPN关闭接收机按固定周期唤醒问Friend要数据。这个机制能大幅降低功耗但会引入额外的消息延迟需要根据业务容忍度来折中。实测下来60秒上报一次的情况下节点平均电流大约在15-25uA之间取决于传感器功耗和发射功率用一节CR2032纽扣电池或者两节AA电池续航可以达到一年以上。如果上报频率降到5分钟一次平均电流可以压到10uA以下。4.5 OTA升级与远程维护传感器节点一旦部署多了如果还要物理接触来升级固件运维成本会非常夸张。所以我在项目里专门加了MCUboot和BLE Mesh OTA升级通道。NCS自带MCUboot支持基于BLE的DFUDevice Firmware Upgrade。整个流程大致是网关通过Mesh网络向目标节点发送升级命令→目标节点进入DFU模式→通过Mesh消息分片传输固件→校验签名→重启并跳转到新固件。不过注意Mesh OTA的传输速度受限于Mesh消息吞吐量一个大固件可能要传很久。我在实测中发现48KB的固件在Mesh上全速传输大概需要5-10分钟期间不能有节点掉线否则要重传。所以在实际部署中我会建议错峰升级一次只升几个节点避免整个网络同时瘫痪。5. 常见问题与排查技巧实录5.1 节点掉线、重连与数据丢失Mesh网络最让人头疼的问题就是节点掉线。我这套系统刚跑起来的时候每天都有好几个节点失联日志里全是重试失败记录。排查了一圈发现主要原因有三个供电电压过低。电池快没电的时候电压掉到2.4V以下射频发射功率会明显下降节点之间通信距离大幅缩短导致数据发不出去。这个没什么好办法只能靠低电量告警功能提前通知运维换电池。消息缓存被占满。如果某个节点周围拓扑变化比较剧烈比如某台叉车挡了信号消息发送会一直重试把发送缓冲区占满后续消息全部丢弃。解决方法是增加CONFIG_BT_MESH_ADV_BUF_COUNT同时在应用层做消息去重和合并。Provisioner配置丢失。节点重新上电后如果Flash里存储的Provisioning信息丢失节点就无法加入Mesh网络表现为永远连不上。我在固件里加了配置持久化逻辑每次Provisioning成功后立即写入Flash上电时先从Flash恢复。另外BLE Mesh默认的重发机制是缓存一定时间内收到的消息重复的消息直接丢弃。如果你的业务需要更高可靠性可以在应用层加ACK机制发送方在消息里带上消息序号接收方处理完后回复ACK发送方超时未收到ACK就重发。当然这会增加消息量和网络负载需要在可靠性和带宽之间做取舍。5.2 2.4GHz频段干扰的真实困扰2.4GHz频段是个大熔炉WiFi、蓝牙、Zigbee、私有协议全挤在一起。在厂房里实测WiFi信道62.437GHz和信道112.462GHz附近干扰特别严重Mesh数据包重传率能达到30%以上。排查干扰的方法很简单用频谱仪或者带频谱显示功能的手机App在部署现场扫一遍信道占用情况找一个相对空闲的频段。Nordic的SoC支持频偏校准和信道调整BLE Mesh的广播信道默认是37/38/39三个信道这三个信道恰好避开了WiFi常用的信道1、6、11的中心频率所以BLE Mesh的抗干扰能力其实还行。但如果你用的是802.15.4Thread/Zigbee信道选择就更讲究了。Zigbee在2.4GHz频段有16个信道11-26信道宽度5MHz跟WiFi信道有部分重叠。我的建议是尽量选WiFi信道之间的空隙比如Zigbee的15、20、25信道。实际部署时如果发现某种WiFi信号占主导可以微调偏移量利用Zigbee的频偏功能把中心频率稍微挪开。5.3 功耗远高于预期的排查思路明明代码里已经做了深度睡眠结果实测功耗还是居高不下这是很多人的疑惑。我在项目里也遇到过类似的情况当时把节点放到电流表上发现睡眠电流有3mA比预期高了几个数量级。最后定位到问题根本不在MCU上而是传感器的I2C上拉电阻在漏电。排查功耗的思路我总结成一套流程先测整板睡眠电流如果高于100uA说明有外设没有关掉。逐个外设断电测试用万用表串联在电源线上观察电流变化。重点检查GPIO悬空引脚。悬空引脚会形成半导通状态导致漏电。所有不用的GPIO要么配置为输入下拉要么配置为输出低电平。检查传感器是否进入低功耗模式。很多传感器默认是连续采样模式需要显式调用低功耗API。检查I2C上拉电阻的供电。如果上拉电阻一路接VDD一路接传感器VDDIO传感器掉电时上拉电阻会通过I2C线倒灌电流进MCU的GPIO保护二极管。还有一个容易忽略的地方是稳压器的静态电流。如果用了LDO静态电流通常在1-5uA如果用了DC-DC静态电流更低但开关频率可能引入额外的纹波。对于电池供电的设备我建议直接用Nordic芯片内置的DC-DC模式效率比LDO高10-20%而且静态电流很低。启用DC-DC的代码很简单pm_dcdc_enable();这一行能省下来的功耗是实打实的。5.4 调试器连接与固件烧录的坑用J-Link调试nRF52840的时候有一类很常见的问题是程序跑飞之后调试器连接不上目标芯片日志提示类似disconnected from the target vm。这个问题背后往往是由于固件把芯片的SWD调试引脚复用掉了或者芯片因为看门狗复位一直在重启。解决办法是进Bootloader模式按住开发板上的RESET键同时点击烧录按钮让芯片在复位后的一小段窗口期内进入DFU模式此时可以重新烧录固件。另外在固件里不要把SWD引脚P0.18/P0.20等随意配置成GPIO除非你很清楚自己在做什么。还有一次我遇到更隐蔽的问题芯片能烧录但复位后跑不起来。查了半天发现是时钟配置不对。nRF52840外部晶振如果焊接不良或者电容匹配不当HFCLK无法起振芯片会一直卡在启动阶段。看门狗没跑起来的话芯片就像死了一样。这时候用示波器看晶振引脚波形就能发现异常——正常应该看到12MHz或32.768kHz的稳定振荡波形看到的是直流电平就说明晶振没工作。5.5 数据丢包与消息风暴数据丢包的原因多种多样我在项目里遇到最诡异的一种是消息风暴导致的网络瘫痪。当时场景是这样的某个节点上报的数据让网关误判为需要立刻下发电网指令于是网关连续回发几十条指令结果指令在Mesh网络里泛洪占满了所有广播信道其他节点都发不出数据了。这个问题的根因是应用层的消息没有做限速和优先级控制。解决方法也很直接限制网关下发指令的最高频率比如每分钟不超过10条。给不同类型的消息分配不同的优先级。BLE Mesh的模型消息可以配置Priority字段紧急指令走High Priority普通数据走Normal Priority。启用消息去重与聚合。多个传感器数据可以在网关侧聚合成一条上行消息减少Mesh网络里的总消息数。消息风暴在节点数量多的网络里尤其容易发生建议在设计协议的时候就把流控机制考虑进去别等到线上出了问题再补。6. 项目落地效果与后续扩展方向6.1 实测数据与网络表现我最终在约2000平米的仓库里部署了32个传感器节点1个网关节点。节点布置在货架、门口、空调出风口等位置覆盖了仓库的主要环境区域。实测下来的数据如下指标实测结果网络节点数32个终端节点 1个网关最大跳数5跳最远节点到网关数据上报周期30秒关键节点~ 5分钟普通节点端到端送达率99.2%排除网关宕机时段平均时延200ms以内2跳500ms左右5跳节点平均功耗约20uA 3V60秒上报周期网关到云端时延1s局域网内部这个送达率说实话已经比较理想了。最开始调试阶段送达率只有95%左右后来通过调整重发参数、优化信道选择和增加缓存容量才慢慢提升到99%以上。6.2 从BLE Mesh到多协议融合的演进方向最后的最后可以聊聊这套系统的扩展空间。如果你也想用Nordic多协议SoC做类似的项目有几件事我建议提前考虑考虑双模设计。如果你对网络实时性要求更高并且节点数量会扩张到上百个可以在硬件不变的前提下评估切换到Thread或Zigbee协议。nRF52840同时支持这些协议换协议只是换固件的事。数据格式要预留扩展字段。我的消息格式头部预留了2个字节的扩展位后续如果增加气体传感器、PM2.5传感器不需要改动消息结构直接填充扩展字段就行。网关层可以多做点事情。目前网关只做数据转发后续可以加入本地规则引擎比如温度超标自动报警、湿度变化触发排风设备等。这样即使云端不可用现场系统也能独立运转。OTA升级通道越早设计越好。等节点部署到几百个的时候再回头补OTA功能会非常痛苦。建议从第一个版本开始就预留DFU升级通道。这次项目的整体收益是很明显的维护成本降下来了数据上报的实时性在可接受范围内节点的电池续航也远远超出了预期。对于一个中大规模的传感器网络来说这个方案在成本、功耗、可靠性和开发效率之间取得了比较好的平衡。后面如果有什么新的优化进展我再回来更新。
返回列表