Project 4: The Aircraft Radar (ADS-B Decoder)

Decode 1090 MHz ADS-B messages from IQ samples, verify CRC, and extract aircraft identity and position.

Quick Reference

Attribute Value
Difficulty Expert
Time Estimate 3-4 weeks
Main Programming Language Python or C (Alternatives: Rust)
Alternative Programming Languages C++, Go
Coolness Level Very High
Business Potential Medium-High (aviation monitoring)
Prerequisites IQ basics, FFT, binary parsing
Key Topics PPM decoding, preamble detection, CRC-24, Mode S frame parsing

1. Learning Objectives

By completing this project, you will:

  1. Detect ADS-B preambles in noisy RF data using correlation.
  2. Extract 112-bit Mode S frames from pulse-position modulation.
  3. Implement CRC-24 to validate frames.
  4. Decode key fields (ICAO, altitude, position, velocity).
  5. Build a deterministic test harness using known ADS-B samples.

2. All Theory Needed (Per-Concept Breakdown)

2.1 Pulse-Position Modulation (PPM) and Preamble Detection

Fundamentals

ADS-B uses pulse-position modulation at 1 Mbps. Each bit is 1 microsecond long and is represented by a pulse in the first or second half of the bit period. A preamble of four 0.5 microsecond pulses marks the start of a frame. To decode ADS-B, you must detect this preamble reliably, then sample the pulses to recover 112 bits. Because ADS-B signals are short and bursty, you cannot rely on continuous synchronization. Instead, you scan the magnitude of the IQ stream for the preamble pattern.

The key trick is that ADS-B ignores phase; you can convert IQ to magnitude and treat it as an amplitude envelope. The preamble is a specific pattern at known offsets: pulses at 0, 1, 3.5, and 4.5 microseconds. A correlation or template match is the standard approach. Once a candidate preamble is found, you slice the following 112 microseconds into bits.

Deep Dive into the Concept

PPM in ADS-B is specifically “pulse position modulation” with fixed pulse width (0.5 us) and fixed bit period (1 us). Each bit is encoded by the position of the pulse within that 1 us slot: a pulse in the first half indicates 1, in the second half indicates 0. In a perfect receiver, you can sample at 2 MSPS (0.5 us resolution) and decide based on which sample in each bit pair is larger. In practice, you want higher sampling (2.4 or 3.2 MSPS) for robustness against timing errors and noise.

The preamble is crucial because it provides both timing and a validity check. It consists of four pulses with specific gaps. A common detection method: compute a correlation score between the magnitude stream and a preamble template. The template is a vector of expected pulse positions. You can compute score = sum(pulses) - sum(non-pulse positions). A high score indicates a likely preamble. This is more robust than simply checking for high amplitude at those positions because it penalizes energy where no pulse should be. It also reduces false detections from noise spikes.

Timing error is the main enemy. If your sampling clock is off or if the signal is slightly frequency-shifted, the pulses may not align perfectly with your sampling instants. You can mitigate this by oversampling (e.g., 2.4 MSPS) and by performing a small timing adjustment after preamble detection (search a few samples around the expected start to maximize correlation). Another improvement is to use a matched filter or integrate over 0.5 us windows rather than single samples. This averages noise and improves SNR.

Another subtlety is amplitude variation across the frame due to multipath or interference. If you use a fixed threshold, you may miss bits or misclassify them. A robust approach is to compute a local threshold based on preamble pulse height. For example, define a threshold as 0.5 * average preamble amplitude. Then classify each bit by comparing the energy in the first half vs second half. This relative approach adapts to different signal strengths and makes decoding more reliable.

How this fits on projects

  • You will implement preamble detection in §5.4 and §5.10.
  • The same correlation approach appears in P10 (GPS acquisition) and P09 (GSM bursts).

Definitions & key terms

  • PPM: Pulse position modulation, encoding bits by pulse timing.
  • Preamble: Fixed pulse sequence marking frame start.
  • Correlation: Measure of similarity between signal and template.
  • Oversampling: Sampling faster than minimum required to improve timing resolution.

Mental model diagram (ASCII)

Magnitude stream -> [Preamble template match] -> Start index -> Bit slicing

How it works (step-by-step, with invariants and failure modes)

  1. Convert IQ to magnitude.
  2. Slide a preamble template and compute score.
  3. If score exceeds threshold, mark start index.
  4. Slice next 112 us into bit windows.
  5. Compare first vs second half to recover bits.

Invariants:

  • Preamble pulses must align within a small tolerance.
  • Bit period is 1 us.

Failure modes:

  • False positives if threshold too low.
  • Missed frames if threshold too high.

Minimal concrete example

# energy in each half-bit
b = []
for i in range(112):
    a = samples[start + 2*i]
    b0 = samples[start + 2*i + 1]
    b.append(1 if a > b0 else 0)

Common misconceptions

  • “Phase matters for ADS-B.” It does not; magnitude is enough.
  • “2 MSPS is always sufficient.” It is the minimum; higher is more robust.

Check-your-understanding questions

  1. Why is ADS-B preamble detection necessary?
  2. What sampling rate gives 0.5 us resolution?
  3. Why is relative thresholding better than fixed threshold?

Check-your-understanding answers

  1. It provides timing and validates potential frames.
  2. 2 MSPS gives 0.5 us per sample.
  3. It adapts to varying signal strength and reduces false decisions.

Real-world applications

  • Aircraft tracking and situational awareness.
  • Air traffic monitoring networks.

Where you’ll apply it

  • This project: §3.4, §5.10.
  • Also used in: P10 GPS.

References

  • “The 1090 MHz Riddle” (Junzi Sun), Chapters 2-3
  • ADS-B technical references and Mode S specs

Key insights

Reliable ADS-B decoding begins with robust preamble detection and timing.

Summary

You learned how PPM and preambles define ADS-B frames and how to detect them in noisy RF data.

Homework/Exercises to practice the concept

  1. Generate a synthetic ADS-B preamble and verify detection correlation.
  2. Add noise and measure false positives at different thresholds.
  3. Test 2 MSPS vs 3.2 MSPS and compare decode rates.

Solutions to the homework/exercises

  1. The correlation peaks at the correct start index.
  2. Low thresholds increase false positives; high thresholds miss frames.
  3. Higher sample rate improves decode success under noise.

2.2 CRC-24 and Mode S Frame Parsing

Fundamentals

ADS-B frames are 112 bits and include a 24-bit CRC at the end. The CRC allows the receiver to validate the frame and reject corrupted data. Without CRC verification, you would parse many false or noisy frames. The CRC polynomial for Mode S is well-defined and must be implemented correctly. Once a frame passes CRC, you can parse fields: the ICAO address, message type, altitude, position, velocity, and other data.

Deep Dive into the Concept

CRC (cyclic redundancy check) is a polynomial division over GF(2). The message bits are interpreted as a polynomial, divided by a generator polynomial, and the remainder becomes the CRC. On reception, you compute the CRC over the received bits (excluding the CRC field) and compare with the received CRC. For ADS-B, the CRC-24 polynomial is standard: x^24 + x^23 + x^18 + x^17 + x^14 + x^11 + x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x + 1. Implementing CRC in software can be done with bitwise shifting or table-based methods for speed.

Mode S frames contain multiple message types. The first 5 bits are the “DF” (downlink format). ADS-B extended squitter uses DF=17. The next 24 bits are the ICAO address. The message type (TC) is in bits 33-37 and determines how to interpret the payload. For example, TC 9-18 often encode airborne position; TC 19 encodes velocity. Position decoding uses Compact Position Reporting (CPR), which requires pairing even and odd frames. That is beyond basic parsing but you can implement a simplified position decoder if you capture both frame types within 10 seconds.

Parsing altitude is another tricky field. Altitude is encoded in 11 bits with a Q-bit. If Q=1, altitude is in 25-foot increments. If Q=0, it uses Gillham code, which is more complex. A basic decoder can handle only Q=1 cases and ignore others.

The CRC can also be used for error correction in some cases (Mode S parity can be used to recover ICAO address for some DF types), but for this project you only need validation. Ensuring you interpret bits in the correct order (MSB-first) is critical. ADS-B bits are transmitted MSB first per field. If you reverse bit order, CRC will fail even if your extraction is correct.

How this fits on projects

  • You will implement CRC in §5.10 and test in §6.
  • CRC concepts also appear in P06 (AIS) and P08 (POCSAG BCH).

Definitions & key terms

  • CRC-24: 24-bit cyclic redundancy check used in ADS-B.
  • DF: Downlink format (frame type).
  • ICAO address: 24-bit unique aircraft identifier.
  • TC: Type code that defines payload meaning.
  • CPR: Compact Position Reporting algorithm for latitude/longitude.

Mental model diagram (ASCII)

[112-bit frame] -> [CRC check] -> [Parse fields] -> [Decoded aircraft data]

How it works (step-by-step, with invariants and failure modes)

  1. Extract 112 bits after preamble.
  2. Compute CRC over first 88 bits.
  3. Compare with last 24 bits.
  4. Parse DF and ICAO.
  5. Interpret payload based on TC.

Failure modes:

  • Bit order reversed -> CRC fail.
  • Wrong polynomial -> CRC fail.
  • CPR requires even/odd frames; missing pair yields no position.

Minimal concrete example

def crc24(bits):
    poly = 0xFFF409
    reg = 0
    for b in bits:
        reg = ((reg << 1) | b) & 0xFFFFFF
        if reg & 0x1000000:
            reg ^= poly
    return reg & 0xFFFFFF

Common misconceptions

  • “CRC only detects errors.” It also can be used for parity in some Mode S frames.
  • “ICAO is always present.” It depends on DF type.

Check-your-understanding questions

  1. Why is CRC essential in noisy RF decoding?
  2. What does DF=17 indicate?
  3. Why do some position decodes require both even and odd frames?

Check-your-understanding answers

  1. It rejects corrupted frames and false detections.
  2. ADS-B extended squitter.
  3. CPR algorithm needs both to resolve ambiguity.

Real-world applications

  • ADS-B receiver networks (FlightAware, ADSBExchange).
  • Aviation data analytics.

Where you’ll apply it

References

  • “The 1090 MHz Riddle” by Junzi Sun
  • Mode S technical docs

Key insights

CRC validation is the gatekeeper that turns noisy pulses into trustworthy aircraft data.

Summary

You learned how to verify ADS-B frames with CRC and parse fields to extract useful aircraft information.

Homework/Exercises to practice the concept

  1. Implement CRC and validate against known ADS-B messages.
  2. Parse ICAO addresses and verify consistency across frames.
  3. Decode altitude with Q-bit set.

Solutions to the homework/exercises

  1. CRC should match published examples.
  2. ICAO should stay consistent for the same aircraft.
  3. Altitude = (N * 25) - 1000 ft for Q=1.

3. Project Specification

3.1 What You Will Build

A command-line ADS-B decoder that reads IQ data, detects frames, validates CRC, and outputs decoded aircraft messages.

3.2 Functional Requirements

  1. Detect ADS-B preamble in magnitude stream.
  2. Extract 112 bits and validate CRC-24.
  3. Parse ICAO address, type code, altitude (Q=1), and velocity (TC19).
  4. Output decoded messages in a structured format (JSON or text).

3.3 Non-Functional Requirements

  • Performance: Decode at least 5 valid frames per minute from live data.
  • Reliability: False-positive rate < 1% after CRC.
  • Usability: Clear output and options for live/file input.

3.4 Example Usage / Output

$ python adsb_decoder.py --input adsb.iq --fs 2.4e6
[MSG] ICAO=A12B3C ALT=35000ft SPD=450kt

3.5 Data Formats / Schemas / Protocols

  • IQ input: u8 interleaved.
  • Output: JSON lines
    {"icao":"A12B3C","alt_ft":35000,"speed_kt":450,"tc":19}
    

3.6 Edge Cases

  • Weak frames with partial bits.
  • Overlapping transmissions causing collisions.
  • CRC failures due to noise.

3.7 Real World Outcome

A live stream of decoded aircraft data suitable for plotting on a map.

3.7.1 How to Run (Copy/Paste)

python adsb_decoder.py --input adsb.iq --fs 2400000 --min-snr 6

3.7.2 Golden Path Demo (Deterministic)

Use a known ADS-B test IQ file containing a single aircraft. Expected output: consistent ICAO, altitude, and velocity.

3.7.3 CLI Transcript (Exact)

$ python adsb_decoder.py --input test_adsb.iq --fs 2400000
[MSG] ICAO=ABC123 ALT=32000ft TC=9
[MSG] ICAO=ABC123 ALT=32000ft TC=19 SPD=440kt

3.7.4 Failure Demo

$ python adsb_decoder.py --input noisy.iq --fs 2400000 --min-snr 12
[WARN] No valid frames found
[EXIT] code=3

4. Solution Architecture

4.1 High-Level Design

IQ -> Magnitude -> Preamble Scan -> Bit Slicing -> CRC -> Parser -> Output

4.2 Key Components

| Component | Responsibility | Key Decisions | |———–|—————-|—————| | Preamble Detector | Find frame start | Correlation threshold | | Bit Slicer | Convert pulses to bits | Sampling rate and timing | | CRC Engine | Validate frames | Polynomial correctness | | Parser | Decode payload | TC-specific logic |

4.3 Data Structures (No Full Code)

class AdsbFrame:
    bits: list[int]
    icao: str
    tc: int

4.4 Algorithm Overview

Key Algorithm: Preamble Correlation + Bit Slicing

  1. Compute correlation with preamble template.
  2. Slice bits using relative thresholds.
  3. Validate CRC.
  4. Parse fields.

Complexity Analysis:

  • Time: O(N) scanning + O(112) per frame
  • Space: O(1) per frame

5. Implementation Guide

5.1 Development Environment Setup

python -m venv .venv
source .venv/bin/activate
pip install numpy

5.2 Project Structure

adsb/
├── src/
│   ├── main.py
│   ├── preamble.py
│   ├── bitslicer.py
│   ├── crc24.py
│   └── parser.py
└── tests/

5.3 The Core Question You’re Answering

“How do you detect a 112-bit message hidden in a noisy RF burst?”

5.4 Concepts You Must Understand First

  1. Preamble detection and PPM (§2.1)
  2. CRC and Mode S parsing (§2.2)

5.5 Questions to Guide Your Design

  1. What threshold yields the best trade-off between false positives and misses?
  2. How will you handle overlapping frames?
  3. How do you validate parsing without known-good data?

5.6 Thinking Exercise

Draw the preamble on a 0.5 us grid and mark expected high/low positions.

5.7 The Interview Questions They’ll Ask

  1. Why is 2 MSPS the practical minimum for ADS-B?
  2. What is the role of CRC in RF decoding?
  3. What is the Mode S frame length?

5.8 Hints in Layers

  1. Convert IQ to magnitude and normalize.
  2. Use a preamble template with positive and negative weights.
  3. Compare two samples per bit to classify 0/1.
  4. Verify CRC before parsing fields.

5.9 Books That Will Help

| Topic | Book | Chapter | |——-|——|———| | ADS-B | “The 1090 MHz Riddle” | Ch. 2-4 | | CRC | Rice, “Digital Communications” | Ch. 9 |

5.10 Implementation Phases

Phase 1: Foundation (4-6 days)

Goals: Detect preamble in magnitude stream. Tasks: Implement correlation and thresholding. Checkpoint: Detect preamble in synthetic data.

Phase 2: Core Functionality (7-10 days)

Goals: Extract bits and validate CRC. Tasks: Bit slicing, CRC-24 implementation. Checkpoint: Pass CRC for known frames.

Phase 3: Polish & Edge Cases (4-6 days)

Goals: Parse fields, output results. Tasks: Implement TC parsing, add filtering. Checkpoint: Decode multiple aircraft.

5.11 Key Implementation Decisions

| Decision | Options | Recommendation | Rationale | |———-|———|—————-|———–| | Sampling rate | 2.0 vs 2.4 MSPS | 2.4 MSPS | More robust timing | | Detection | Threshold vs correlation | Correlation | Fewer false positives | | Output | Text vs JSON | JSON lines | Easy ingestion |


6. Testing Strategy

6.1 Test Categories

| Category | Purpose | Examples | |———|———|———-| | Unit | CRC and parsing | Known ADS-B frames | | Integration | End-to-end decode | Recorded ADS-B IQ | | Edge | Noise and collisions | Corrupted frames |

6.2 Critical Test Cases

  1. Frame with known ICAO and altitude.
  2. Corrupted frame should fail CRC.
  3. Two overlapping frames should be rejected or handled.

6.3 Test Data

Known ADS-B messages from public samples.

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

| Pitfall | Symptom | Solution | |———|———|———-| | Wrong bit order | CRC fails | Verify MSB/LSB ordering | | Too low threshold | Many false frames | Increase or use correlation | | PPM drift | Bits misaligned | Adjust timing offset |

7.2 Debugging Strategies

  • Plot magnitude around detected preamble.
  • Compare bits with known frames from dump1090.

7.3 Performance Traps

  • Correlating at every sample without downsampling.
  • Excessive Python loops (use numpy where possible).

8. Extensions & Challenges

8.1 Beginner Extensions

  • Output raw frames to a log file.

8.2 Intermediate Extensions

  • Implement CPR to decode full positions.

8.3 Advanced Extensions

  • Real-time map visualization.
  • Multi-receiver MLAT for position accuracy.

9. Real-World Connections

9.1 Industry Applications

  • Air traffic surveillance and ADS-B networks.
  • dump1090: widely used ADS-B decoder.
  • pyModeS: Mode S decoding library.

9.3 Interview Relevance

  • Demonstrates signal detection, CRC, and protocol parsing.

10. Resources

10.1 Essential Reading

  • “The 1090 MHz Riddle” by Junzi Sun
  • Mode S ICAO documentation

10.2 Video Resources

  • SDR ADS-B tutorials (RTL-SDR blog)

10.3 Tools & Documentation

  • dump1090: reference implementation

11. Self-Assessment Checklist

11.1 Understanding

  • I can explain PPM and ADS-B preamble.
  • I can compute and verify CRC-24.

11.2 Implementation

  • Decoder finds and validates frames.
  • Parsed fields match known aircraft data.

11.3 Growth

  • I understand CPR and can implement it next.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Decode frames and validate CRC.
  • Output ICAO and altitude.

Full Completion:

  • Decode position and velocity for multiple aircraft.

Excellence (Going Above & Beyond):

  • Live map visualization and CPR decoding.