3. ADR工作机制:网络侧与终端侧的区别

好,咱们今天来聊聊ADR的工作机制。说实话,这个知识点是LoRaWAN里最容易让人混淆的地方之一。我见过不少开发者,一上来就问“ADR是不是终端自己调的?”——其实没那么简单。

ADR分为两个角色:网络侧ADR终端侧ADR。它们各自负责不同的任务,配合起来才能达到最优效果。

3.1 网络侧ADR vs 终端侧ADR

先说说最核心的区别:

对比项 网络侧ADR 终端侧ADR
谁在控制 网络服务器 终端设备本身
主要职责 根据上行信号质量,计算最优速率和发射功率 检测下行链路,判断是否需要请求ADR调整
触发方式 收到上行数据后被动计算 主动监测下行链路质量,超时后发起请求
典型场景 网关覆盖良好、终端固定部署 终端移动、信道变化剧烈

我个人习惯把网络侧ADR比作“教练”,终端侧ADR比作“运动员”。教练根据比赛数据制定战术,运动员在场上感觉不对劲时可以主动喊暂停。嗯,这个比喻你想想看,是不是挺贴切的?

重要提醒:大多数LoRaWAN网络默认启用网络侧ADR。终端侧ADR通常作为备选方案,在终端无法收到网络响应时发挥作用。

3.2 ADR控制流程

ADR的控制流程分为两大块:上行链路测量下行链路命令。我当年在做一个智慧农业项目时,就踩过这里的坑——终端上报数据正常,但网络就是不调整速率,后来才发现是上行测量参数没配对。

3.2.1 上行链路测量

终端每次发送上行数据时,网络服务器会记录以下信息:

  • RSSI(接收信号强度指示):信号有多强
  • SNR(信噪比):信号有多干净
  • 网关数量:多少个网关收到了这个包
  • 数据速率:当前使用的DR值

网络服务器会维护一个滑动窗口,通常保存最近20个上行包的测量数据。为什么是20个?因为太少不够统计意义,太多又反应太慢。我在项目中试过10个和30个,最后还是觉得20个最稳。

网络侧ADR的决策逻辑大致如下:

// 伪代码示意
if (最近20个包的SNR平均值 > SNR阈值) {
    // 信号质量好,尝试提高速率
    尝试增加DR值;
    同时降低发射功率;
} else if (最近20个包的SNR平均值 < SNR阈值 - 余量) {
    // 信号质量差,降低速率
    降低DR值;
    同时增加发射功率;
} else {
    // 保持当前配置
    不做调整;
}

我的经验:SNR阈值不要设得太死。比如SF12到SF11的切换,我一般留3dB的余量,避免频繁震荡。曾经有个项目,余量设了1dB,结果终端在SF11和SF12之间来回跳,功耗直接翻倍。

3.2.2 下行链路命令

网络服务器计算好新的参数后,通过下行链路命令告诉终端。这个命令叫做LinkADRReq,它包含:

  • 数据速率(DR):新的速率值
  • 发射功率(TX Power):新的功率值
  • 通道掩码(ChMask):可用的通道列表
  • 重试次数(NbTrans):每个包重复发送的次数

终端收到LinkADRReq后,必须回复LinkADRAns,告诉网络服务器“我收到了,并且应用了”。如果终端发现命令参数有问题(比如通道掩码不合法),会在应答中设置对应的错误位。

注意:下行链路命令不是实时生效的。终端可能在收到命令后,等到下一个上行机会才应用新参数。我曾经遇到过终端在发送上行数据前就应用了新参数,结果导致上行数据丢失——因为新参数对应的通道刚好不可用。

3.3 ADR_ACK_LIMIT与ADR_ACK_DELAY参数

这两个参数是终端侧ADR的核心。说白了,它们决定了终端在“失联”多久后,会主动发起ADR请求。

参数 默认值 含义
ADR_ACK_LIMIT 64 连续发送多少个上行包后,如果没有收到下行确认,就进入ADR请求模式
ADR_ACK_DELAY 32 进入请求模式后,再发送多少个上行包,如果还没收到响应,就降低速率

你想想看,这两个参数配合起来是什么效果?

假设终端启用了ADR,并且连续发送了64个上行包,但一个下行响应都没收到。这时候终端会认为“网络可能收不到我,或者我收不到网络”。于是它开始在每个上行包中设置ADRACKReq位,告诉网络“我需要确认”。

如果又过了32个包(总共96个包),还是没有收到任何响应,终端就会主动降低一个速率等级(比如从DR5降到DR4),同时增加发射功率。这就是终端侧ADR的“自救”机制。

关键点:ADR_ACK_LIMIT和ADR_ACK_DELAY的单位是“上行包数量”,不是时间。所以如果终端发送频率很高(比如每10秒一个包),那么64个包只需要640秒;如果发送频率很低(比如每小时一个包),那就需要64小时。这一点在低功耗场景下特别重要。

我曾经在一个水表项目中,终端每小时上报一次数据。默认的64和32意味着终端要等4天后才会发现网络失联。客户反馈说“水表数据丢了4天才发现”,我一看,就是这两个参数没调。后来我把ADR_ACK_LIMIT改成16,ADR_ACK_DELAY改成8,这样最多24小时就能发现问题。

调参建议:

  • 对于高频上报(分钟级):保持默认值64/32即可
  • 对于低频上报(小时级):建议缩小到16/8或更小
  • 对于关键数据(如报警):可以考虑关闭终端侧ADR,完全依赖网络侧

嗯,到这里ADR的工作机制就讲得差不多了。总结一下:网络侧ADR负责“算”,终端侧ADR负责“保底”。两个参数ADR_ACK_LIMIT和ADR_ACK_DELAY,就是终端侧ADR的“耐心值”——耐心太大,反应慢;耐心太小,容易误判。具体怎么调,得看你的业务场景。