第3章:LoRaWAN协议栈:MAC层、Class A/B/C、ADR机制、数据包格式解析
好,咱们今天聊聊LoRaWAN协议栈。说实话,很多初学者一上来就被这个协议栈吓住了,觉得太复杂。其实你把它拆开看,核心就四个东西:MAC层怎么工作、三种设备类别怎么选、ADR怎么帮我们省电、数据包长什么样。我一个个给你讲透。
3.1 MAC层:谁说了算?
LoRaWAN的MAC层,说白了就是一套“谁先说话、谁后说话”的规矩。它不像Wi-Fi那样大家抢着说,而是终端设备主动发起,网络服务器被动响应。
我刚开始做项目时,总想着让服务器主动下发数据,结果发现根本行不通。为什么?因为LoRaWAN的设计哲学就是“终端省电优先”。终端平时都在睡觉,服务器找不到它。
MAC层定义了两种通信模式:
- 纯ALOHA:终端想发就发,不管信道忙不忙。简单,但冲突概率高。
- 带确认的ALOHA:发完等服务器回ACK,没收到就重发。可靠,但费电。
我个人习惯,在排水管网这种数据量小、实时性要求不高的场景,用纯ALOHA就够了。但如果你做的是工业控制,那必须用带确认的。
关键点:MAC层不负责路由,只负责“点到点”的通信。所有数据都经过网关转发到网络服务器,终端之间不能直接通信。
3.2 Class A/B/C:三种“作息时间”
LoRaWAN定义了三种设备类别,其实就是三种不同的“作息时间表”。
Class A:最省电,最常用
Class A是所有LoRaWAN设备必须支持的。它的工作流程很简单:
- 终端主动发一个上行数据包。
- 发完后,打开两个短暂的接收窗口(RX1和RX2)。
- 服务器如果想下发数据,只能在这两个窗口里发。
- 窗口关闭,终端继续睡觉。
我在排水管网项目里,90%的设备都用Class A。为什么?因为水位数据通常是每15分钟上报一次,中间时间设备都在休眠,一节电池能用两年。
小技巧:RX1窗口的频点和上行频点相同,RX2窗口固定使用868.1MHz(欧洲)或923.3MHz(中国)。你可以通过设置让服务器优先在RX1下发,这样延迟更低。
Class B:定时“查岗”
Class B在Class A的基础上,增加了一个定时接收窗口。终端会定期打开一个“信标窗口”,同步网络时间,然后按约定时间打开接收窗口。
嗯,这里要注意:Class B需要终端支持GPS或网络时间同步,硬件成本会高一些。我只有在需要定时采集数据的场景才用,比如每隔1小时必须上报一次。
Class C:随时待命
Class C的设备几乎不睡觉,除了发送数据时,其他时间都在监听。服务器可以随时下发数据。
你想想看,这种模式最费电,但延迟最低。我一般用在需要实时控制的场景,比如阀门控制、报警确认。但排水管网里很少用,因为电池扛不住。
| 类别 | 功耗 | 下行延迟 | 适用场景 |
|---|---|---|---|
| Class A | 极低 | 高(需等待上行) | 水位监测、环境传感 |
| Class B | 中等 | 中(定时接收) | 定时控制、数据采集 |
| Class C | 高 | 低(随时接收) | 实时控制、报警响应 |
3.3 ADR机制:自动“调音量”
ADR(Adaptive Data Rate)是LoRaWAN里一个非常聪明的功能。它就像手机自动调节屏幕亮度一样,根据信号质量自动调整发射参数。
具体来说,ADR会调整三个东西:
- 扩频因子(SF):SF越大,传输距离越远,但速率越慢。
- 带宽(BW):带宽越大,速率越快,但抗干扰能力越差。
- 发射功率(TX Power):功率越大,信号越强,但越费电。
我曾经在一条3公里长的排水管道里部署了50个节点。刚开始全部用SF12,结果网关被撑爆了,数据根本收不过来。后来开了ADR,大部分节点自动降到SF9,网关瞬间轻松了。
避坑指南:我曾经遇到过一个问题——节点在移动场景下(比如装在清淤车上),ADR反而帮倒忙。因为信号变化太快,ADR来不及调整,导致丢包率飙升。所以,固定安装的设备用ADR,移动设备建议手动固定SF。
ADR的工作流程是这样的:
- 网络服务器收到上行数据后,计算信噪比(SNR)和信号强度(RSSI)。
- 如果信号太好(比如SNR > 10dB),服务器会下发一个LinkADRReq命令,让终端降低SF或功率。
- 如果信号太差(比如SNR < -10dB),服务器会建议提高SF或功率。
- 终端收到命令后,在下一次上行时应用新参数。
说白了,ADR就是让网络服务器帮你“调音量”,你不用自己操心。
3.4 数据包格式解析:拆开看看
LoRaWAN的数据包看起来挺复杂,其实拆开就几部分。我拿一个实际抓包的数据给你看:
MHDR | DevAddr | FCtrl | FCnt | FOpts | FPort | FRMPayload | MIC
1B | 4B | 1B | 2B | 0-15B | 1B | 0-250B | 4B
咱们一个一个说:
- MHDR(1字节):消息头,告诉服务器这是上行还是下行,是确认帧还是非确认帧。
- DevAddr(4字节):设备地址,相当于设备的“身份证号”。
- FCtrl(1字节):控制字节,包含ACK标志、ADR标志、FOpts长度等。
- FCnt(2字节):帧计数器,防止重放攻击。每次上行+1。
- FOpts(0-15字节):可选字段,用来携带MAC命令,比如ADR调整命令。
- FPort(1字节):端口号,1-223是应用数据,224-255是MAC命令。
- FRMPayload(0-250字节):真正的数据内容,经过加密。
- MIC(4字节):消息完整性校验码,防止数据被篡改。
注意:FRMPayload的最大长度取决于SF和带宽。SF12时最多只能传51字节,SF7时可以传222字节。所以,如果你要传大量数据,记得选低SF。
我举个例子。假设一个水位传感器上报数据:
上行数据:0x40 0x12345678 0x80 0x0001 0x00 0x01 0x02 0x1A 0x2B 0x3C 0x4D
解析:
- MHDR = 0x40(非确认上行)
- DevAddr = 0x12345678
- FCtrl = 0x80(ADR=1,ACK=0)
- FCnt = 0x0001(第1帧)
- FOpts = 0x00(无MAC命令)
- FPort = 0x01(应用数据)
- FRMPayload = 0x02 0x1A 0x2B 0x3C(4字节水位数据)
- MIC = 0x4D(校验码)
你看,实际有用的数据只有4个字节,其他都是协议开销。这就是为什么LoRaWAN适合传小数据——你传一个温度值,可能就2个字节,但协议头占了20多个字节。
3.5 避坑指南:我踩过的三个坑
最后,分享几个我实际项目中遇到的坑,你遇到了可以少走弯路:
- ADR在信号不稳定时别开:我曾经在隧道里部署节点,信号时好时坏。开了ADR后,服务器频繁下发调整命令,结果节点一直在切换参数,数据反而丢了。后来我手动固定SF10,问题解决。
- Class B的信标同步容易失败:Class B需要终端和服务器时间同步,但排水管道里GPS信号弱,信标经常收不到。我后来改用Class A + 定时上报,效果更好。
- 数据包别塞太满:LoRaWAN一个包最多250字节,但实际传输时,SF12只能传51字节。如果你硬塞200字节,网关会直接丢弃。我建议每个包控制在50字节以内,分多次发送。
好了,这一章的内容就这些。下一章咱们聊聊如何用LoRaWAN做实际的水位监测系统设计,包括传感器选型、网关部署、数据解析这些实战内容。