What is modelled. Signals are complex baseband at one sample per chip, so the sample rate equals the bandwidth. Semtech does not publish LoRa's coding; the packet format here (whitening, header checksum, Hamming codes, diagonal interleaver, Gray mapping, reduced-rate first block, low data rate optimization) follows the published reverse engineering (Robyns et al. 2018; Tapparel et al., gr-lora_sdr). Bit ordering and the CRC-16 variant are modelled and may not match a real radio bit for bit. The channel adds white Gaussian noise, a carrier frequency offset and a sub-chip timing offset; there is no fading or clock drift. The receiver's oversampling is modelled: after synchronizing it demodulates at the quarter-chip sampling phase nearest its timing estimate. The payload is whatever you type; the second transmitter sends made-up sensor readings.
A packet on the air
Each LoRa symbol is a chirp: a tone that sweeps across the whole bandwidth in 2SF chips. The data is carried by where the sweep starts; when it reaches the top it wraps to the bottom. A packet opens with a run of plain up-chirps (the preamble), two sync-word symbols, two and a quarter down-chirps, then the header and payload. Well below 0 dB SNR the sweeps disappear into the noise in this view, yet the receiver can still decode them.
Spectrogram of the received signal
The zoomed views follow the playhead; notches in the bars mark symbol boundaries. Each up-chirp climbs from −BW/2 to +BW/2; a data symbol starts part way up and wraps to the bottom; the down-chirps fall.
Current symbol, received samples
Encoding the payload
Before modulation the bytes are whitened (XORed with a fixed pseudo-random sequence so long runs of equal bits do not repeat), a CRC-16 is appended, and a header carries the length and coding rate with its own 5-bit checksum. Each 4-bit nibble becomes a Hamming codeword of 5 to 8 bits. The interleaver then spreads every codeword diagonally across several symbols, so one badly received symbol damages only one bit of each codeword. Last, Gray mapping makes a one-bin error in the receiver flip only one bit.
| # | Char | Byte | Whitening | Sent |
|---|
Interleaver block
Left: the block's codewords, one row each, bits left to right. Right: the symbols sent, one row each. Colors show which codeword each bit came from: every symbol holds one bit of every codeword, on a diagonal. The last column is the chirp value after Gray mapping.
Preamble detection and synchronization
The receiver does not know when a packet starts. It cuts the signal into symbol-long windows, dechirps each one and takes its FFT. Inside the preamble every window holds the same chirp, so the FFT peak lands in the same bin again and again, whatever the timing. A run of equal peaks means a packet. The bin of that peak mixes timing error and carrier offset; the down-chirps shift the other way under a timing error but the same way under a frequency offset, so up- and down-chirp peaks together separate the two. The phase step of the peak from one preamble symbol to the next gives the fraction of a bin.
FFT peak in each window
| Run found at | SF | Bin | Result | Transmitter |
|---|
Dechirping
Multiplying each symbol by the complex conjugate of a plain up-chirp cancels the sweep. What is left is a steady tone whose frequency is the symbol's value: the chirp's starting point becomes a frequency. Down-chirps are multiplied by an up-chirp instead. This view uses the receiver's own timing and frequency estimates from stage 3, so every symbol turns into a flat line.
Dechirped spectrogram
Current symbol after dechirping
FFT peak per symbol
An FFT of the dechirped symbol gathers all 2SF chips into one bin. The noise stays spread across all bins, so measured against the noise in one bin the peak rises by the SNR plus 10·log10(2SF) dB of processing gain: 21 dB at SF7, 36 dB at SF12. That processing gain is how LoRa decodes below the noise floor. The receiver simply takes the largest bin as the symbol value.
Spectrum of every symbol in the frame
Current symbol's FFT
Decoding
The receiver runs the transmit chain backwards: symbol values, Gray code, de-interleaving, Hamming decoding, de-whitening. The first eight symbols always use the most robust settings (coding rate 4/8, two fewer bits per symbol) so the header gets through; the header then says how long the payload is and which coding rate it uses. Rates 4/7 and 4/8 correct one bit per codeword; 4/5 and 4/6 can only detect errors. The CRC-16 decides whether the packet is accepted.
| # | Part | Peak bin | Sent | Peak (dB) | Next (dB) | Result |
|---|
Payload received
Symbol error rate against SNR
Each step up in spreading factor doubles the symbol length and buys about 2.5 to 3 dB of margin, at roughly half the bit rate. The sweep sends random symbols through noise at every SNR from −30 to +5 dB for SF7 to SF12 and counts wrong FFT peaks, with perfect timing. The solid lines are the theory for picking the largest of 2SF bins in white noise. The triangles mark the demodulator SNR limits listed in Semtech's SX1276 datasheet; a real radio also has to find and synchronize each packet, which the sweep leaves out.
Symbol error rate
| SF | Chips per symbol | Bit rate | Processing gain | Datasheet SNR limit | Sensitivity | SNR at 1% SER, theory | SNR at 1% SER, measured |
|---|
Collisions and the capture effect
LoRa devices transmit whenever they like, so packets overlap. When two packets use the same spreading factor, each receiver window can hold two FFT peaks and the receiver keeps the larger one: the stronger packet usually survives (the capture effect) and the weaker is lost; at similar power both can fail. Packets with different spreading factors barely interfere, because a chirp with the wrong slope does not collapse into one bin; it spreads over all of them. This receiver listens on every spreading factor in use, like a gateway.
Who is on the air
| Frame | SF | Timing error (chips) | CFO error (Hz) | Symbol errors | Header | CRC | Payload |
|---|