Adaptive Data Rate (ADR) is a mechanism for optimizing data rates, airtime and energy consumption in the network.
This reference documents how ADR is implemented in The Things Stack.
How ADR Works
The ADR mechanism controls the following transmission parameters of an end device:
- Spreading factor
- Bandwidth
- Transmission power
See The Things Network LoRaWAN documentation for a general description of ADR. See the Spreading Factors section to learn how spreading factor influences data rate, range and battery life.
The Things Stack ADR Algorithm
This section describes The Things Stack ADR implementation in plain english, with links to the relevant lines of source code in our open source LoRaWAN Stack Repository.
The Things Stack ADR implementation looks at the signal-to-noise ratio (SNR) to determine the Data Rate and Tx Power, and looks at frame counters to determine packet loss, and set the number of re-transmissions accordingly.
The implementation is based on Semtech’s recommended algorithm described in this document:
- Determine the maximum SNR over recent transmissions
- Determine the minimum SNR to demodulate an uplink given the current parameters
- Calculate the margin to further optimize the data rate
- Part of this is configurable per device (if you use the CLI)
- If less measurements (uplinks) are available than necessary, include a safety margin
- Increase the data rate as long as there’s enough margin
- If there’s still margin after reaching the maximum data rate, decrease the transmit power
- Depending on packet loss, increase the number of retransmissions
Custom ADR Algorithm
Besides The Things Stack ADR mechanism described above, The Things Stack also supports using a custom ADR, meaning ADR parameters (data rate, Tx power, number of transmissions per uplink frame) can be controlled manually.
Note:
We recommend to test the process described below on test devices before implementing it in production.Before setting ADR parameters to desired values, you first need to turn off the default, The Things Stack ADR mechanism. To turn of The Things Stack ADR using the CLI:
ttn-lw-cli end-devices set --application-id <app-id> --device-id <dev-id> --mac-settings.use-adr=false
After The Things Stack ADR mechanism is disabled, the Network Server will no longer try to optimize ADR parameters.
Now you can manually set ADR parameters to desired values using the CLI:
ttn-lw-cli end-devices set --application-id <app-id> --device-id <dev-id> --mac-state.desired-parameters.adr-data-rate-index <data_rate> --mac-state.desired-parameters.adr-tx-power-index <power_index> --mac-state.desired-parameters.adr-nb-trans <nb_trans>
Desired values that you set for ADR parameters need to be supported by the end device based on its MAC and PHY versions, and its frequency plan. Upon receiving a next uplink message, the Network Server schedules a LinkADRReq
message with new ADR parameters included.
If the end device accepts all three parameters specified, then it will use them and answer with a LinkADRAns
uplink message. We recommend setting all three parameters explicitly to avoid a possible rejection.
Keep in mind that changes to mac-state.desired-parameters.<parameter>
are not persistent and will be lost on a device reset/rejoin. Read the MAC Settings section for detailed info.
Configuring ADR Margin
The Things Stack Network Server calculates the ADR margin to optimize the data rate and Tx power.
Margin is the difference between the gateway’s maximum measured SNR and the minimal SNR required to demodulate a message on a given data rate. Margin is used to determine how much data rate can be increased, or how much transmit power can be lowered. Increasing the ADR margin reduces the data rate, leading to a reduced overall network capacity, but also to a lower packet loss rate in lightly loaded networks. Decreasing the ADR margin leads to a data rate increase, network capacity enhancement, but also causes higher packet loss rate.
Note:
We recommend to test the process described below on test devices before implementing it in production. It is also recommended to use different test scenarios to identify which margin best fits your environment.The Network Server uses the ADR margin of 15, but this value can be configured per device using the CLI:
ttn-lw-cli end-devices set --application-id <app-id> --device-id <device-id> --mac-settings.adr-margin <float32>
Keep in mind that changes to mac-settings.<parameter>
are persistent and will be present even after a device reset/rejoin. Read the MAC Settings section for detailed info.
Examples
Consider a device whose SNR values in the last 20 uplink messages were in range from 0 to 7. The data rate of the last received frame from the end device is DR3. Three cases presented below demonstrate how choosing a different ADR margin leads to different outcomes in terms of changing the data rate and Tx power.
In practice, the ADR margin value should be tuned until the optimization target is reached. The optimization target can be different (like battery duration, low packet loss, etc.) in different environments, so a user needs to decide on which margin value to adopt.
Case 1: ADR margin set to default
The default ADR margin value in The Things Stack is 15, while the minimum SNR required to demodulate a message for DR3 is 12.5.
First, the maximum SNR is computed for recent uplinks. In this example, the SNRmax
is 7.
Then the SNR margin is calculated as follows:
SNRmargin = SNRmax - SNRDR3 - margindB = 7-(-12.5)-15 = 4.5
The final step is to calculate the NStep
value to decide whether a data rate can be optimized:
NStep=int(SNRmargin/2.5) = int (4.5/2.5) = 1
Considering the diagram for acting on an NStep calculation depicted here, the conclusion for this example is that the Network Server should increase the data rate to DR4.
Case 2: ADR margin set to 18
The SNR margin would be:
SNRmargin = SNRmax - SNRDR3 - margindB = 7-(-12.5)-18 = 1.5
The NStep
value would be:
NStep=int(SNRmargin/2.5) = int (1.5/2.5) = 0
In this case, according to the previously mentioned diagram, the Network Server should not take any action to further optimize the data rate.
Case 3: ADR margin set to 25
The SNR margin would be:
SNRmargin = SNRmax - SNRDR3 - margindB = 7-(-12.5)-25 = -5.5
The NStep
value would be:
NStep=int(SNRmargin/2.5) = int (-5.5/2.5) = -1
In this case, according to the previously mentioned diagram, if Tx power is lower than its maximum, the Network Server should increase it once by 3dB, while the data rate should not be changed.