The Best LoRa Settings for Range and Reliability

Why won’t my two LoRa (Long Range) radios talk to each other? A common refrain when you’re developing LoRa applications.

Start by examining how LoRa settings theoretically affect range and reliability.

LoRa Settings and Effect

The first requirement is to realize there are country (US v EU) restrictions. These include allowed frequencies, maximum power, and maximum packet sizes. These are well summarized here.

Next, Semtech has a very cool application you can download to get a feel for performance.

Semtech’s LoRa Calculator

Spreading Factor

LoRa sends chirp signals, that is the signal frequency moves up or down, and the speed moved is roughly 2**spreading factor. Each step up in spreading factor doubles the time on air to transmit the same amount of data. Higher spreading factors are more resistant to local noise effects and will be read more reliably at the cost of lower data rate and more congestion. Each unit increase in SF correlates to about 2.5dB extra link budget.

Bandwidth

The chirp will cover this bandwidth. If you examine the 4 images below, they were clearly done with a 31KHz bandwidth. Higher bandwidth has higher data rates but more congestion. Each doubling of the bandwidth correlates to almost 3dB less link budget.

Outputs from the Semtech Calculator

A number of really interesting things pop out of the calculator.

Link Budget: This is how many dBs you can lose between the transmit PA and the receiver IF. Higher link budgets directly translate to longer distances (6dB = twice distance).

Max Crystal Offset: A way to view the necessary crystal accuracy.

Let’s continue with real life analysis of some radios.

Miscommunication & Frequency Stability

After building two radios that worked fine together I built two more. One of them would talk to everyone, one of them would only talk to the other new one. I got persistent CRC errors on receive and didn’t know why.

Four Radio Spectra

Looking at the above spectral charts you can see that although they look similar, they’re at different frequency ranges. This is no doubt caused by alignment of the 32MHz base crystal oscillator.

The four graphs differ by about 10KHz from first to last. This is equivalent to an error of 11ppM (0.011%). That’s pretty high for a crystal-based oscillator circuit. Worse yet, frequency errors also affect the symbol rates.

Allowed Frequency Variation

So, what frequency variation will work? Semtech provides a really good application note. Extracted from it (where PER = packet error rate):

Semtech Error Rate Graph at 125KHz

As you can see in this graph, 125KHz works up to about 30KHz error and then starts dramatically failing.

From Semtech: “The figure indicates that frequency tolerances of typically ±25% of the LoRa® modulation bandwidth can be withstood and still maintain a 10% PER link.”.

So, at 31KHz that implies an error > 7KHz would start causing failures. Exactly what I was seeing. Also, when one of the ‘working’ units heated up it caused persistent failure as the oscillator drifted.

Getting the Longest Range

The software way to get the longest range is by maximizing the link budget. The hardware way includes better antennas and more power.

By looking at the analysis at the top of this post, you can see that we maximize link budget by:

  1. Lowest possible bandwidth
  2. Highest possible Spreading Factor

Unfortunately decreasing the bandwidth increases the risk of miscommunication due to frequency drift and inaccuracy. Pycom only supports 125KHz and above, for example. The Semtech reference Sx127x chipsets support bandwidths down to 8KHz.

These settings also affect the data rate. See below. These tables are from the Sx127x specification sheet from Semtech.

Coding Rate Analysis

Coding Rate | CRC Rate | Overhead Ratio
----------------------------------------
1 | 4/5 | 1.25
2 | 4/6 | 1.5
3 | 4/7 | 1.75
4 | 4/8 | 2

So, increasing the coding rate increases reliability while decreasing data rate.

Spreading Factor Analysis

A spreading factor of S converts to a Chip/Symbol of 2**S. Each increase in S of 1 unit is an increase in SNR at the demodulator of 2.5 dB.

So, for example, SF=7 produces Chip/Symbol of 128. SF=8 has 256 Chips/Symbol and 2.5dB better S/N ratio.

Bandwidth Analysis

Halving bandwidth causes an approximately 3–4dB increase in S/N ratio while halving the data rate.

Bandwidth    |   SNR
----------------------
125 KHz | -128
250 KHz | -125
500 KHz | -121
---> SF=8

Effective Data Rate

The relationship between these settings and data rate is approximately:

Data Rate = Bandwidth / (2 ** SF)

Rule of Thumb

Reading through this, a rule of thumb if you only care about transmission reliability, not data rate. — ->

Minimize bandwidth and maximize spreading factor to boost link budget. Maximize coding rate to boost reliability.

Improve Temperature Stability

It’s easy to improve the temperature stability of your LoRa systems. Simply examine the temperature characteristics of the LoRa module and then alter the center frequency based on the known temperature drift. Note that the modules have a temperature sensor (albeit it’s slow and clunky).

True Story…

Temperature Drift Measurements along with Linear Compensation

The above chart shows my measurements of a single module and how the center frequency drifts based on temperature. The entire oscillation circuit (and potentially power supply) will cause variations with temperature.

Here, the variation was visually linear and sure enough a simple least-squares linear fit works great. Note that other crystal cuts and moving the resonance slightly can easily cause the curve to be quadratic or tertiary.

Anyway, here I wrote the new frequency as Fn = Fc + Scale*(Temp — 80), where Fc is the basic correction applied to the module to get it right at 80 (in this case).

Using that simple algorithm and every now and then correcting based on temperature changes I was able to maintain a connection at 32KHz bandwidth — with one unit starting in the refrigerator at 48F and then literally baking on the oven until it hit 141F (at which point I let it cool, sorry not sorry). That’s about 6ppM.