Skip to main content
The ADS-B Framer (adsb_framer) is the first block in the gr-adsb pipeline. It consumes a magnitude-squared power signal, searches for the 8-symbol ADS-B preamble pattern, and annotates the stream with "burst" stream tags at each detected preamble position. Downstream blocks use these tags to locate and demodulate individual ADS-B frames.

Block info

PropertyValue
GRC block IDadsb_framer
GRC labelADS-B Framer
GRC category[ADS-B]
Python classadsb.framer
Constructoradsb.framer(fs, threshold)
Block typesync block

Parameters

fs
float
default:"2e6"
Sample rate in samples per second. The block computes sps = int(fs // 1e6) to determine the number of samples per symbol. The sample rate must be an integer multiple of 1 MHz (fs % 1e6 == 0); the block raises an AssertionError otherwise. The minimum usable sample rate is 2 Msps (2 samples per symbol at the 1 Msym/s ADS-B symbol rate).
threshold
float
default:"0.01"
Detection threshold applied to the magnitude-squared input signal. Any sample at or above this value is treated as a high pulse; samples below it are treated as low. Lower values increase sensitivity but also increase false-positive preamble detections. This parameter can be updated at runtime by calling set_threshold(threshold).

Ports

Inputs

LabelDomainData typeVector length
instreamfloat321
The input must be the instantaneous power of the received signal: |I|² + |Q|². Use a blocks.complex_to_mag_squared block upstream to compute this from a complex IQ source.

Outputs

LabelDomainData typeVector length
outstreamfloat321
The output is a pass-through of the input signal with no modification to the sample values. The burst stream tags described below are attached to this output stream.

Stream tags

When a valid preamble is detected, the Framer emits a stream tag on output port 0:
FieldValue
Key"burst"
Value("SOB", snr) — a tuple of the string "SOB" (Start of Burst) and the SNR in dB
Source"framer"
The tag is placed at the sample index corresponding to the centre of the first preamble pulse. The SNR is computed as:
SNR (dB) = 10 * log10(pulse_amplitude / median_noise) + 1.6
The 1.6 dB correction accounts for the fact that the median of a Rayleigh-distributed noise variable is 1.6 dB below its mean power.

Preamble detection

ADS-B uses Pulse Position Modulation (PPM) at 1 Msym/s. The 8-symbol preamble produces the following half-symbol pulse pattern (sampled at 2× the symbol rate):
[1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
The Framer converts the input to a binary pulse vector by thresholding, then checks each detected rising edge to see if the subsequent 16 half-symbol samples match the pattern above. A preamble is confirmed only when all 16 half-symbol samples match.

History buffer

The Framer sets a history buffer of N_hist = NUM_PREAMBLE_BITS * sps samples (8 × sps). This history allows the work() function to detect preambles whose first pulse falls at the very end of the previous work() call’s input buffer. At 2 Msps, N_hist is 8 samples; at higher sample rates it scales proportionally.

Runtime callback

The detection threshold can be changed while the flowgraph is running:
framer.set_threshold(0.005)
This updates the internal self.threshold value. The next work() call will use the new threshold.

End-of-burst guard

After confirming a preamble, the Framer records the estimated end-of-burst index (prev_eob_idx) based on the shorter 56-bit (Short Squitter) packet length. Subsequent rising edges that fall before this index are skipped, avoiding spurious preamble detections on data pulses within the same packet.

Instantiation example

import gnuradio.adsb as adsb

framer = adsb.framer(fs=2e6, threshold=0.01)
In GNU Radio Companion, set the Sample Rate and Detection Threshold parameters in the block properties dialog. The block ID is adsb_framer.

Build docs developers (and LLMs) love