第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设备必须支持的。它的工作流程很简单:

  1. 终端主动发一个上行数据包。
  2. 发完后,打开两个短暂的接收窗口(RX1和RX2)。
  3. 服务器如果想下发数据,只能在这两个窗口里发。
  4. 窗口关闭,终端继续睡觉。

我在排水管网项目里,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的工作流程是这样的:

  1. 网络服务器收到上行数据后,计算信噪比(SNR)和信号强度(RSSI)。
  2. 如果信号太好(比如SNR > 10dB),服务器会下发一个LinkADRReq命令,让终端降低SF或功率。
  3. 如果信号太差(比如SNR < -10dB),服务器会建议提高SF或功率。
  4. 终端收到命令后,在下一次上行时应用新参数。

说白了,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 避坑指南:我踩过的三个坑

最后,分享几个我实际项目中遇到的坑,你遇到了可以少走弯路:

  1. ADR在信号不稳定时别开:我曾经在隧道里部署节点,信号时好时坏。开了ADR后,服务器频繁下发调整命令,结果节点一直在切换参数,数据反而丢了。后来我手动固定SF10,问题解决。
  2. Class B的信标同步容易失败:Class B需要终端和服务器时间同步,但排水管道里GPS信号弱,信标经常收不到。我后来改用Class A + 定时上报,效果更好。
  3. 数据包别塞太满:LoRaWAN一个包最多250字节,但实际传输时,SF12只能传51字节。如果你硬塞200字节,网关会直接丢弃。我建议每个包控制在50字节以内,分多次发送。

好了,这一章的内容就这些。下一章咱们聊聊如何用LoRaWAN做实际的水位监测系统设计,包括传感器选型、网关部署、数据解析这些实战内容。