Offline Retro ADS-B Radar: a Standalone Aircraft Tracker

by MWPaus in Circuits > Raspberry Pi

70 Views, 1 Favorites, 0 Comments

Offline Retro ADS-B Radar: a Standalone Aircraft Tracker

1000020083.jpg
20260619-202937.png
PXL_20260617_074259277.jpg
20260619-221912.png

I live more or less directly under one of the approach paths of a large airport and often wondered what aircraft was passing nearby. Being the geek I am, I thought I should find a solution to this problem.


Websites like flightradar24 and adsb-exchange exist, but they require constant internet access and some level of user interaction. I wanted something that sits on the shelf, switches on, and shows the planes nearby. No login, no internet, no subscription. Simple.


Most aircraft send ADS-B (Automatic Dependent Surveillance–Broadcast) information via radio signals at 1090 MHz. The information broadcast includes the aircraft's GPS position, altitude, velocity, and identity.

Thanks to some clever people that discovered that common, cheap TV tuner hardware could be used as very flexible radio signal receivers, we can listen in on these ADS-B transmissions and decode them ourselves using nothing more than a ~$20 USB dongle, an antenna, a low-powered computer and free software.


This is a low(ish)-power, compact, fully offline aircraft monitoring station. It receives the ADS-B radio signals that aircraft broadcast on 1090 MHz, decodes them locally, and draws them on a 5" touchscreen as a retro radar-style display — aircraft dots coloured by altitude, heading lines, fading position trails, coastlines, airports and cities.

The unit boots straight into the radar with no desktop, and because all the map data lives on the device, it works completely off-line (no internet access). With an optional GPS module it becomes genuinely portable and re-centres itself wherever you are.


The whole thing is built around a compact Crystalfontz CFA050A0-PI-M 5" touchscreen module (with attached Raspberry Pi CM4 or CM5) and an RTL-SDR USB dongle for the radio side.

I couldn't find existing light-weight software to display the map and ADS-B information so with the help of Claude I wrote a program in C. It uses the SDL3 graphics library, which is easy to use, fast, and well suited to being run on a Raspberry Pi.


Why the Crystalfontz CFA050A0-PI-M?

The display is the part of this build I'd most want to justify, because it's the most expensive single component and the one that shapes everything else:

  1. It's a Compute-Module carrier *and* a screen in one compact board. The Raspberry Pi CM4/CM5 plugs directly into the back. There's no separate Pi, no ribbon cable to a screen, no HDMI — it's one tidy sandwich.
  2. High pixel density. 720×1280 on a 5" IPS panel is genuinely sharp and bright, which matters for thin radar lines and small callsign text.
  3. It's supported by Raspberry Pi OS out of the box. You enable it with a couple of `config.txt` overlays rather than chasing down drivers.
  4. Capacitive multi-touch. Pinch-to-zoom and drag-to-pan on the radar feel right, and the software is built to be driven entirely by touch.


Why an RTL-SDR?

The RTL-SDR is the obvious choice for ADS-B reception for a few reasons:

  1. It's cheap. A dongle that can receive 1090 MHz ADS-B costs about the price of a couple of coffees, versus hundreds for a dedicated receiver.
  2. It's well supported. The decoding software (`readsb`, `dump1090`, etc) is mature, open source, and for the most part 'just works'.
  3. It uses USB. No GPIO wrangling for the radio side — the Raspberry Pi Compute Module does the rest.
  4. It's good enough. ADS-B is a strong, structured signal. You don't need an expensive radio to decode it well; antenna and placement matter far more than the dongle.

If you already own a fancier SDR (HackRF, BladeRF, an Airspy via SoapySDR), the build supports those too — the dependency list includes the libraries for them.


Project Difficulty

If you're handy with a soldering iron and a 3D printer (or know someone that is), then this project isn't too difficult. The most difficult part is soldering the USB wires between the RTL-SDR and the CFA050A0-PI-M (wires are soldered to keep the finished unit compact). The USB-C power supply wires also need to also be soldered, but USB-C power is optional.

On the software side, Linux experience would be useful, but not necessary. Hopefully the step-by-step instructions are detailed enough for pretty much anyone.

Supplies

Most parts are linked to Amazon for reference. Stock and prices change, so shop wherever suits you.

Core Electronics

  1. Crystalfontz CFA050A0-PI-MBCT 5" 720×1280 capacitive touchscreen
  2. Raspberry Pi Compute Module 4 Lite or 5 Lite
  3. microSD card (8GB+)
  4. CR1225 coin cell battery
  5. RTL-SDR USB dongle
  6. 1090 MHz ADS-B antenna
  7. Cooling fan (30x7mm)
  8. 22/24 AWG Hook-up wire
  9. M2.5 x 10mm screws
  10. M3 x 10mm screw
  11. M3 x 6 x 5 threaded brass insert
  12. Strong double-sided tape


Power Supply - Option 1 - 5V Plug-Pack

The first power supply option — the simplest option — is to use a decent 5V plug-pack/wall-wart to power the project. Raspberry Pis are quite picky about their power supply, so when I say "decent" I really mean it. If the power supply isn't up to the job, it'll be quite unstable.

The power supply needs to supply stable 5V DC at a minimum of 3 amps.

An example plug-pack can be seen here. 5V 3A plug-pack with a 5.5mm x 2.1mm barrel jack, center positive


Power Supply - Option 2 - USB-C / USB-PD

The second power supply option is more difficult to set up, and more expensive, but is more flexible and reliable. In my experience USB-PD power supplies (and cables) can't really be trusted to supply 5V at high current, so if going with this power supply option we'll be requesting 8–12V (depending on what voltage the trigger board supports) from USB-PD then regulating it down to 5V using the MINI360 buck regulator board.

  1. USB-PD "trigger" board
  2. MINI360 regulator
  3. USB-PD charger


Tools Required

You don't need much in the way of hardware tools.

Hardware / hands-on:

  1. An electronics multi-meter
  2. A fine-tipped soldering iron
  3. A 3D printer, or a print service, for the case
  4. A small phillips screwdriver (for the case and CM mounting screws)
  5. Wire cutters
  6. A USB to microSD adaptor (some laptops have them built-in)


Software / Setup Requirements:

  1. Another computer (Linux, macOS or Windows) to flash the OS image
  2. Raspberry Pi Imager Software for writing the OS to the microSD card

Flash Raspberry Pi OS Onto a MicroSD Card

Screenshot from 2026-06-19 15-59-08.png
  1. Put the microSD in your main computer.
  2. Open Raspberry Pi Imager ([get it here](https://www.raspberrypi.com/software/)).
  3. Select "Raspberry Pi 5" if you have a CM5, or "Raspberry Pi 4" if you have a CM4. Click next.
  4. Select "Raspberry Pi OS (other)", then "Raspberry Pi OS Lite (64-bit)" (see screenshot). Click next.
  5. Choose your microSD card in the storage list.
  6. Proceed to Customisation.
  7. Hostname - Enter a hostname, it can be anything but "adsb" would be a good name for this project.
  8. Localisation - set as appropriate for your location.
  9. User - I suggest using "adsb" for the username (the rest of the guide uses it), and select your own password.
  10. Wi-Fi - The initial setup of the project requires wifi and internet access. Enter the appropriate details here.
  11. Remote access - Enable SSH, and select "use password authentication".
  12. RaspberryPi Connect - leave it disabled
  13. Write the image. When complete, remove the microSD card from the computer.

Configure the OS for the Crystalfontz Display

Out of the box, Raspberry Pi OS won't drive the LCD panel correctly — you'll need to edit a simple text configuration file.

  1. Insert the microSD card back into your main computer. You should see a drive appear in your file manager called "bootfs".
  2. Open the "bootfs" drive in file explorer (or similar), and edit the "config.txt" file.
  3. At the very end of the file, copy & paste this text:
###############################################
#Settings for the Crystalfontz CFA050A0-PI-M series of modules
[all]
#enable I2C and SPI peripherals
dtparam=i2c_arm=on
dtparam=spi=on
#enable I2C-0 pins 44/45 (appears as i2c-10)
dtparam=i2c_vc=on
#enable the required video driver to use DSI1
dtoverlay=vc4-kms-v3d
ignore_lcd=1
#display orientation (0=default, 1=90deg, 2=180deg, 3=270deg)
display_lcd_rotate=0
#misc settings
camera_auto_detect=0
max_framebuffers=2
#enable USB on-the-go mode
otg_mode=1
[cm5]
#turn on GPIO35 as quickly as possible for PCF8574
gpio=35=op,dh
dtoverlay=gpio-hog,gpio=35
#enable the overlay for the CFA050A0-PI-M for the CM5
dtoverlay=crystalfontz-cfa050_pi_m,captouch,cm5
[cm4]
#enable the overlay for the CFA050A0-PI-M for the CM4
dtoverlay=crystalfontz-cfa050_pi_m,captouch
############################################
  1. Save the file, and close the text editor software.
  2. Safely "eject" the microSD card from the computer.

3D Print the Case

PXL_20260519_075133141.jpg

I designed the case in Onshape. If you haven't come across it, it's 3D CAD software that runs entirely in your browser, and the free plan is generous enough for hobby projects like this one.

If my design of the case doesn't quite meet your needs, you can copy my Onshape project into your own Onshape account and modify it however you like.

You can find the case OnShape project here.

I have also shared the 3D model files (STL's) on the Printables website here.

I printed the case using Polymaker translucent red PET-G filament in my QIDI Plus4 3D printer.

There are no specific requirements for the plastics used in this case, so you could print it out of any type or colour of plastic that you like.

I do suggest that you use a 0.4mm nozzle and print it quite slowly. There are some fine details in the print that do need to print at a decent quality.

Once the case pieces are printed, a M3x6x5 threaded brass insert needs to be melted into the back case just below where the RTL-SDR module sits (see photo).

Please see a YouTube guide if you haven't done this before. This is a decent example.

Prepare the RTL-SDR USB Module

PXL_20260519_075305289.jpg
PXL_20260519_080444317.jpg
PXL_20260619_044341087_drawn.jpg
PXL_20260519_081908746.jpg

I'm usually reluctant to modify a neat, self-contained product like the RTL-SDR, but in this case it's the only way to keep the overall footprint down. Plugging in a standard USB cable would have added about 10mm of width and 10mm of depth to the case — a meaningful chunk when the whole thing is this compact. So rather than use a normal cable, we make our own from a few lengths of hookup wire. Using proper shielded USB cable would be best (what I used) but as the length is so short, hookup wire works fine.

These instructions are for a genuine RTL-SDR.com - RTL-SDR V3 or V4. If you have a different RTL-SDR unit, you'll need to adjust the steps below to suit.


  1. Remove the 2 screws at each end of the RTL-SDR case, remove the brass nut on the outside of the antenna connector, then remove the aluminium end panels.
  2. Slide out the RTL-SDR board.
  3. Using some de-soldering wick, or a de-soldering gun, remove as much solder as possible from the 4 pins of the USB connector, and the 2 USB connector frame pins.
  4. Very carefully remove the USB connector from the board.
  5. Looking at the top of the PCB (the component side), the 4 USB connections are GND, USB+, USB-, 5V in order from left to right (see photo).
  6. Solder an individual length of hook-up wire (about 12cm long, we'll trim these shorter later) to each of the four USB connection points on the PCB. If you wish to use standard USB wire colours for the wires: GND=Black, USB+=Green, USB-=White, 5V=Red.
  7. Place the board back into the original aluminium case, then screw back into place the aluminium end panels. Do not screw back on the brass antenna nut (we'll do this later).
  8. Loosely twist the four USB wires together.
  9. Place the RTL-SDR module in the front half of the case, with the antenna connector inserted through the hole in the case top (see photo).
  10. Screw the brass antenna connector nut on the connector on the outside of the case. This holds the RTL-SDR in the correct place inside the case.

Prepare USB-C / USB-PD Power Supply (optional)

PXL_20260519_083757462.jpg

If you're going with the USB-C power option (see "Power supply - Option 2 - USB-C / USB-PD" section above), you'll need to follow these steps:

  1. Solder a short length of wire (2-3cm long) from the trigger boards VCC+ output to the IN+ input on the MINI360 regulator board.
  2. Solder another short length of wire (2-3cm long) from the trigger boards GND output to the GND input on the MINI360 board.
  3. Solder two pieces of hookup wire about 10cm in length to the MINI360's OUT+ and GND pins.


Configuration and testing (do not skip this):

  1. Check the description / information for the USB-PD trigger board, and configure it to supply 8V, 9V or 12V (lower voltage is preferred). In the case of the trigger board I purchased, it was configured for 8V by setting tiny dip-switches on the board.
  2. If the MINI360 regulator board has configurable voltage output by using switches or soldered jumpers, select 5V output. If it has adjustable output using a trim-pot, continue the next steps.
  3. Connect the USB-PD trigger board to a USB-PD charger using a USB-C cable.
  4. Using the multi-meter, check the voltage between the VCC+ output and GND output on the trigger board. It should be the same level as you selected above (8, 9 or 12V).
  5. Using the multi-meter, check the voltage between the OUT+ and GND pins (or ends of the soldered wires) on the MINI360 regulator board. If the board has adjustable voltage, adjust the trim-pot using a tiny screwdriver until it's output is between 5.0V and 5.2V.
  6. The output voltage of the MINI360 (or similar) regulator must be 5.0V to 5.2V. If its lower or higher, the sensitive compute module may be permanently damaged.


Mount the boards in the case:

  1. Using the double-sided tape, attach the USB-PD trigger board and MINI360 board to the back case (see photo)

Finishing Off the Hardware

PXL_20260518_120921770_drawn.jpg
PXL_20260518_120921770_usb.jpg
PXL_20260519_081932166.jpg
PXL_20260619_024439232.jpg
PXL_20260619_024449843.jpg
PXL_20260519_091004718.jpg
PXL_20260518_114107938.jpg
PXL_20260518_121030463.jpg
PXL_20260519_082458570.jpg

The Crystalfontz CFA050A0-PI-M and especially the Raspberry Pi compute module are quite fragile, both physically and electrically. Be as gentle as possible when following the next steps, and triple check everything is wired correctly before supplying power. Do not place the Raspberry Pi compute module on the CFA050A0-PI-M until the last step.


Initial Crystalfontz CFA050A0-PI-M prep:

  1. Solder closed JMP2, JMP3, JMP4, JMP6 and JMP7 by bridging the two close pads of each jumper together (see photo).
  2. Make sure all other JMPx are not soldered/bridged.


RTL-SDR wire connection to the CFA050A0-PI-M:

  1. Loosely place the CFA050A0-PI-M in it's mounting position in the front of the front case (we do this to make sure the wires are placed correctly)
  2. Solder the RTL-SDR USB wires to the CFA050A0-PI-M. The position and identification of the wire locations can be seen in the photo.


Solder USB-PD power to the CFA050A0-PI-M (optional):

  1. Solder the MINI360 OUT+ wire to pin 2 on the 40-pin header (see photo).
  2. Solder the MINI360 GND wire to pin 6 on the 40-pin header (see photo).

Make sure these are soldered in the correct position, getting one wrong will likely destroy the compute module. Also make sure you verified the MINI360 is supplying the correct voltage (see above).


Powering the cooling fan:

  1. If the purchased fan has a connector(s) on the end of it's wires, cut them off.
  2. Strip the wire ends, and solder the fans wires to the CFA050A0-PI-M as shown in the photo.


Last steps:

  1. Insert the CR1225 coin cell battery in the CFA050A0-PI-M battery holder (it slides into the side, button side down towards the board).
  2. Insert the Raspberry Pi compute module on the CFA050A0-PI-M board. Make sure the connectors and screw mounting holes line up, then press down firmly on the compute module until it clicks into place.
  3. Insert the microSD card into the microSD card slot on the CFA050A0-PI-M. It'll click into place.


Finishing off Assembly:

  1. Clip the fan into the mounting on the back of the case. The blades should face the case, so air is blown into the case.
  2. Carefully close up the case making sure no wires are pinched between the two sides of the case.
  3. Using the M2.5 screws, screw the case into the mounting posts on the back of the CFA050A0-PI-M.
  4. Screw the M3 screw into the remaining screw near the RTL-SDR.


Power it Up:

First, make sure you're close to your Wi-Fi access point. The Raspberry Pi's built-in Wi-Fi antenna isn't the best, so a strong signal helps during software setup.

Plug the 5V plug-pack into the barrel jack on the back of the case, or supply power from a USB-PD charger. The fan should spin up indicating it does have power.

Give the compute module time to boot — around 5 minutes. On the very first boot, Raspberry Pi OS resizes the partitions on the microSD card, which can take a while. If you don't see anything on the display after 5 minutes, unplug the power for 10 seconds, then plug it back in.

After applying power again, you should see some Linux status text on the LCD display. It's alive!

Get Connected to the Raspberry Pi Compute Module

While the project when finished will operate without any networking or internet access, we do need it to setup the software first.

Finding the IP address:

Before you can connect, you need to know the Pi's address on your network.

There are a few ways to find it:

  1. Check the LCD. The boot text on the display often shows the assigned IP address as part of the network startup messages. Look for a line mentioning `eth0` or `wlan0` followed by an address like `192.168.1.x`.
  2. Try the hostname. Raspberry Pi OS advertises itself over the network via mDNS, so you can often skip the IP hunt entirely and just use `adsb.local` (or whatever hostname you set when creating the microSD card image). A quick `ping adsb.local` command will confirm it's reachable and show you the IP.
  3. Ask your router. Log into your router's admin page and look for the DHCP client list or "connected devices." The Pi will usually show up by hostname.
  4. Scan the network. A tool like Fing (phone app), Angry IP Scanner (desktop), or `nmap -sn 192.168.1.0/24` on the command line will list everything on your network and its addresses.


Connecting via SSH:

Once you have the IP (or hostname), you need to connect using an SSH client from a computer (or phone).

The command is the same almost everywhere:

ssh adsb@192.168.1.x

Replace the address with whatever you found above. The first time you connect it'll ask you to confirm the host fingerprint — type `yes` — then enter your password.

Some SSH software, by platform:

  1. Linux / macOS: Nothing to install. Open a terminal and use the built-in `ssh` command shown above.
  2. Windows: Modern Windows has the same `ssh` command built in — just open PowerShell or Windows Terminal. If you prefer a GUI, **PuTTY** is the long-standing favourite.
  3. Phone / tablet: Termius (iOS and Android) is polished and free for basic use; JuiceSSH is a solid Android option.

Install Dependencies and Build the Software

This step gets the `adsb-radar` software (and the bundled `readsb` decoder) compiled and running on the device. When connected to the Raspberry Pi Compute Module using SSH:

Install the build dependencies:

sudo apt update
sudo apt install build-essential cmake git libdrm-dev libgbm-dev libzstd-dev \
zlib1g-dev librtlsdr-dev libusb-1.0-0-dev libncurses-dev \
libsoapysdr-dev libhackrf-dev libbladerf-dev libad9361-dev libiio-dev \
libudev-dev libinput-dev libudev1


Set some user permissions.

These permission changes are required for the software to run correctly.

sudo usermod -aG video adsb
sudo usermod -aG render adsb
sudo usermod -aG input adsb


Get the adsb-radar source-code:

git clone https://github.com/MWP/adsb-radar.git
cd adsb-radar


Compile the adsb-radar and readsb software.

This can take quite some time depending on Wi-Fi strength and Internet speed. This produces `build/adsb-radar` and `build/readsb`, with the assets and default config copied alongside them automatically.

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DSDL_UNIX_CONSOLE_BUILD=ON
cmake --build build -j4


Reboot the Raspberry Pi compute module:

sudo reboot

Software Testing

To test both the `readsb` and `adsb-radar` software works correctly, we'll need two SSH connections to the Raspberry Pi at the same time.

After the Raspberry Pi has rebooted from the previous step, open two SSH sessions on your computer (as performed earlier). You'll need to be able to switch between them easily.


Run readsb, then leave it running:

cd ~/adsb-radar
./build/readsb --no-interactive --metric --write-json=/tmp --write-json-every=1 --device-type rtlsdr --ppm=0

readsb should not give any errors, and occasionally output some aircraft information. It'll also create and populate the `/tmp/aircraft.json` file with whatever it's hearing. If an aircraft flies over and nothing appears, that points at antenna or placement rather than software.


Configure adsb-radar:

In the second SSH session, we'll need to do some initial configuration of the `adsb-radar` software.

  1. Use `nano` text file editor to edit the configuration file:
cd ~/adsb-radar
nano adsb-radar.ini
  1. Set your GPS location. Find the `center_lat` and `center_lon` settings in the file, and change them to your current GPS location (you can find this using google maps, click on a location close to you on the map). For example mine is set to Adelaide, Australia.
[view]
center_lat = -34.9127
center_lon = 138.6813
  1. Exit `nano` by pressing `ctrl-x` keys, and answer Yes to saving the file.


Test adsb-radar:

Run adsb-radar:

cd ~/adsb-radar
./build/adsb-radar


The software runs using the configuration file `adsb-radar.ini` found in the same directory (the file you just edited). If everything runs correctly, the `adsb-radar` software will load three map files (airports, coastlines, city-names), then display the map on the LCD display along with any aircraft that have been detected by the `readsb` software. You should be able to use the touch screen to move the map around, zoom in and out, etc.

Pressing the exit button at the bottom left will close the software.

If you have any problems, please ask for help in the github issues page or here on the instructables project comments.


Finish up Testing:

Once you're satisfied `readsb` and `adsb-radar` are working correctly, we are done with testing.

In both the SSH sessions press `ctrl-c` to stop `readsb` and `adsb-radar` from running.

Finishing Off the Software

When we turn on power to the project, we want `readsb` and `adsb-radar` to start quickly without any user intervention. These configuration files will make that happen.


Use `nano` to edit the file `/etc/systemd/system/readsb.service`:

sudo nano /etc/systemd/system/readsb.service

Copy and paste this text into it:

[Unit]
Description=readsb ADS-B decoder
After=network.target
Wants=network.target

[Service]
Type=simple
User=adsb
ExecStart=/home/adsb/adsb-radar/build/readsb --no-interactive --metric \
--write-json=/tmp --write-json-every=1 --device-type rtlsdr --ppm=0
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Press `ctrl-x` to exit `nano`, save the file when it asks.


Use `nano` to edit the file `/etc/systemd/system/adsb-radar.service`:

sudo nano /etc/systemd/system/adsb-radar.service

Copy and paste this text into it:

[Unit]
Description=ADS-B Radar Display (KMS/DRM)
After=readsb.service systemd-user-sessions.service getty@tty1.service
Wants=readsb.service
Conflicts=getty@tty1.service

[Service]
Type=simple
User=adsb
WorkingDirectory=/home/adsb/adsb-radar
ExecStartPre=/usr/bin/chvt 1
ExecStart=/home/adsb/adsb-radar/build/adsb-radar
Restart=on-failure
RestartSec=2
SupplementaryGroups=video render input
TTYPath=/dev/tty1
StandardInput=tty
TTYReset=yes
TTYVHangup=yes

[Install]
WantedBy=multi-user.target

Press `ctrl-x` to exit `nano`, save the file when it asks.


We then need to enable these service files, and reboot.

In an SSH session:

sudo systemctl daemon-reload
sudo systemctl enable readsb.service adsb-radar.service
sudo reboot


When the Raspberry Pi Compute Module restarts, `adsb-radar` should be running and detecting aircraft.

Further Configuration of Adsb-radar

This is where you make the adsb-radar yours — centre the map on your location, pick units, change rendered map(s), set aircraft appearance, etc.

Configuration lives in `adsb-radar.ini`, which is located in `/home/adsb/adsb-radar/`.

The file is very well commented, describing all the options.

Completed Build and Conclusions

PXL_20260617_074511702.jpg
PXL_20260617_074259277.jpg

That's it. A self-contained, offline aircraft radar that boots into a clean retro display and shows me exactly what's going over the house. No internet, no phone, no accounts. It draws very little power and starts fast.


What works well:

  1. Reception is genuinely good with a half-decent 1090 MHz antenna — regularly see aircraft 200+ km away on a clear day.
  2. The all-on-one-board layout (CM + display in one sandwich) keeps it compact and tidy.
  3. Touch pan/zoom feels natural, and booting quickly straight to fullscreen radar with no desktop is exactly the appliance-like feel I wanted.


What's still rough / Future improvements:

  1. The case is functional but not too pretty. It could do with some tweaks.
  2. Aircraft show as hex codes rather than friendly types/registrations (an offline lookup database is on the to-do list).
  3. Software setup is quite involved. It would be great to offer a pre-configured microSD image.
  4. Internal GPS unit.
  5. Rechargeable battery.
  6. Per-aircraft selection showing a detail panel when you tap a plane.


Suggestions and pull requests are very welcome.


Credits:

  1. Crystalfontz for the CFA050-PI-M display and its setup documentation.
  2. `readsb` by wiedehopf — the ADS-B decoder bundled with the build
  3. SDL3, SDL3_ttf, FreeType and cJSON — the libraries the display is built on
  4. Coastline data derived from Natural Earth (public domain) via geojson-maps.kyd.au; airport and city data from OpenStreetMap via Overpass
  5. adsb-radar developed with assistance from Claude Code; all code authored, reviewed and directed by me