ADR Algorithm and Sensor Data Rate(DR) Settings and Working

Hi All,

I am having a trouble with sensor going into DR0 even though it has good signal strength and SNR. So I am just trying to understand the default ADR algorithm, but I am not getting much inputs. I just want to understand why the sensors are set to DR0 and also I would like to understand how the default ADR requests the sensors to change the DR. I am using sensors in US915 sub band 1. Below is the downlink sent from Chirpstack network server. Currently I am using Chirpstack v3. Can someone please help me with the explanation of below payload and also the ADR algorithm working. In an earlier thread I saw the minimum data rate is not of much use, because it is not considered by default ADR. Is this still the same or it has been updated. { "txInfo": { "frequency": 926900000, "power": 20, "modulation": "LORA", "loRaModulationInfo": { "bandwidth": 500, "spreadingFactor": 9, "codeRate": "4/5", "polarizationInversion": true }, "board": 0, "antenna": 0, "timing": "DELAY", "delayTimingInfo": { "delay": "1s" }, "context": "VeMTnA==" }, "phyPayload": { "mhdr": { "mType": "UnconfirmedDataDown", "major": "LoRaWANR1" }, "macPayload": { "fhdr": { "devAddr": "001b8c01", "fCtrl": { "adr": true, "adrAckReq": false, "ack": false, "fPending": false, "classB": false }, "fCnt": 534, "fOpts": [ { "cid": "LinkADRReq", "payload": { "dataRate": 0, "txPower": 0, "chMask": [ true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false ], "redundancy": { "chMaskCntl": 7, "nbRep": 0 } } }, { "cid": "LinkADRReq", "payload": { "dataRate": 5, "txPower": 0, "chMask": [ true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false ], "redundancy": { "chMaskCntl": 0, "nbRep": 3 } } }, { "cid": "DevStatusReq", "payload": null } ] }, "fPort": null, "frmPayload": null }, "mic": "8590fb88" } }

Also the Chirpstack Network Server is not sending any LinkADRReq to the sensor even though the ADR is set to true. Can someone please help me with this, why and when this happens.

Can someone please help me with the queries, any inputs would help me. Also I could see the server sending downlink to the least rssi and snr gateway. Can anyone please let me know why chirpstack network server is not selecting the gateway with best rssi and snr? Please help me with this problem. @brocaar

Chirpstack, like with many other common LNS, has a default ADR algorithm that is loosely based on the reference algorithm from Semtech. I couldn’t find where Semtech hosted this document, but TheThingsNetwork has a copy: https://www.thethingsnetwork.org/forum/uploads/default/original/2X/7/7480e044aa93a54a910dab8ef0adfb5f515d14a1.pdf

ADR has the following objectives:

  • To select the best datarate. Better use of bandwidth, less time on air.
  • To select the lowest transmission power. Aside from saving power, it can pull the node out of range of gateways that are far away and not meant to serve this.
  • There are variants of this, but the strategy for compensating for packet losses via RF attenuation is by adjusting the repetition factor.
  • Informing nodes which channel(s) to not use.

I’m not sure I understand your question. It seems like you have ADR working in your first post, but the question is about why the node drops back to using DR0? This depends on the node’s logic, but it is indeed the node’s responsibility to roll back the steps of ADR if it hasn’t been able to get downlinks from the LNS.

ADR will increase datarate until the maximum, and then lower transmission power. The steps taken by the node are the reverse.

Every time there is an uplink, ADR will determine whether it can make any adjustments (datarate, transmission power and repetition count). Adjustments to the transmission power and repetition count are only done if Chirpstack has at least seen 20 uplinks. The number of steps is determined with the following formula:
steps = (SNR - demodulation floor - margin) / 3

Where SNR is the SNR of the most-recent uplink, demodulation floor is the minimum SNR level for demodulating a frame for the current datarate (according to the SX1276/77/78 datasheet). The margin is for compensating for RF environmental issues in dB, and defaults to 10.


Downlink gateway selection: there is an algorithm for selecting the downlink gateway. It’s not purely about selecting the gateway with the best RSSI/SNR performance.

Chirpstack will first determine a list of candidate gateways, with a formula like this:
SNR - demodulation floor - downlink gateway margin > 0

The downlink gateway margin is different from the ADR margin. It defaults to 10dB.

After that, it’ll randomly select one.

If there are no matches (may happen if the SNR is too low), then it’ll pick the gateway with the best SNR, followed by RSSI.

In the first post the downlink contains two linkADRreq commands. The first is to set the 500khz channels and disables all 125khz channels, chMaskCtrl:7, the dr and power are ignored.

The second command sets the desired 8 - 125 kHz channels, chMaskCtrl: 0, and device to use DR5.

LinkADRReq is sent periodically, it is not sent on every downlink when ADR bit is set. The ADR bit tells the LNS that the device will accept requests to change DR and PWR.

ADRACKReq bit is used to request a LinkADRReq feom the server, if not received after ADR_DELAY packets the ADR algo will lower the datarate.

If the device is still using DR0 after receiving these commands it is a device issue.

For the gateway selection using lowest rssi/snr, can you provide the up/down packet info showing this?

Thank you for the inputs. If LinkADRReq is periodically, I am not able to understanda why it is sending LinkADRReq in all uplink packets for one sensor and not sending at all for other sensors.

The live frames for one of the sensor with one uplink and one downlink are attached. I could not share the json, so I have attached screenshots. Kindly let me know if this helps.







What leads you to believe that LinkAdrReq is sent? I don’t see it in your screenshots. All I see is that ADR is enabled (true), not that a LinkAdrReq is sent.

On first screenshot is a DevStatusReq - device status request, not ADR Request. Other screenshost are normal.

You can disable DevStatusReq if you want from chirpstack.

Since ADR true, it should have been sent. As I am new to chirpstack, I am trying to understand why it is not sending. In earlier comments its mentioned it sends periodically as well, but I am not able to see any LinkADRReq sent periodically also. The only way I could fix this was by resetting the sensor, but I am still not clear why network server was not sending LinkADRReq even though ADR flag was set to true from sensor.

Thank you for the detailed explanation. But ideally the gateway with best signal strength should be selected right? Because the problem what is happening is, on our end there is a graph showing signal strength over time, this value is fluctuating each time with once it being high and another time it being low. In my application server, I am using the gateways signal strength sent in the json of http request integration. Could you please let me know if I can do anything better to solve this.

RF can be unpredictable. If you can remove or mitigate the sources of attenuation, there would be less interference. But it could still be observed, as LoRaWAN operates in the ISM band. Where anyone is free to do anything, within your laws. It is possible for LoRaWAN transmissions to overlap other transmissions.

Downlink gateway selection does not always end up with the best-performing gateway being selected. Instead, Chirpstack will make a list of candidates and randomly choose one, based on the last uplink message’s reception performance. This allows for some load-balancing over the best gateways and to mitigate against the case the best-performing gateway during the last uplink is actually the wrong choice.

If it is too lax with selecting gateways, you can reduce the margin. If no gateways end up as candidates, then the gateway with the best SNR and RSSI will be selected.

1 Like