There are a lot of Raspberry Pi flight trackers, and nearly all of them are API clients. They ask OpenSky or FlightAware what is overhead, and draw the answer. Which works, and which means your object stops being interesting the moment the Wi-Fi drops, the free tier runs out, or the service changes its terms.
FltCast, by bytecadia, gets the data from the aircraft.
What it is
- A C++ ADS-B flight tracker for Raspberry Pi and HUB75 RGB LED matrices
- An RTL-SDR and antenna receiving the aircraft’s own broadcasts
- Reads SBS aircraft data from port 30003
- Selects the nearest aircraft
- Enriches the data with a local DB lookup
- Renders to a 64×32 LED matrix
- Housed in a 3D-printed case
What ADS-B is, and why receiving it yourself is a different thing
ADS-B — Automatic Dependent Surveillance–Broadcast — is a system in which aircraft continuously transmit their own identity, position, altitude, heading and speed, unencrypted, on 1090MHz. It is mandated for most airspace, it is not a service anyone operates, and anyone with a receiver can hear it.
An RTL-SDR dongle costs around $30, tunes 1090MHz comfortably, and with a quarter-wave antenna cut for the band will pick up aircraft tens of miles away. dump1090 and its forks decode the signal and, by long-standing convention, re-serve it as SBS-format text on TCP port 30003 — which is why FltCast reads that port rather than talking to the radio directly. It is a clean separation: the decoder owns the radio, the application owns the display.
The difference from an API client is not performance. It is ontological:
There is no dependency. No key, no quota, no terms of service, no company. The aircraft will keep transmitting whether or not anyone is still running a website.
There is no network. The device works in a basement with no internet, in a gallery with locked-down Wi-Fi, in a venue where IT will not give you a port. For installation work this is the whole argument — the single most common cause of an unattended piece failing is a network it depended on.
The latency is physical. An API has a polling interval and a server-side aggregation delay. A receiver hears the broadcast as it arrives. The aircraft overhead is the aircraft overhead, not a record of where it was eight seconds ago.
And it is local by construction. You receive what is in range. “Nearest aircraft” is not a geo-query against a global dataset; it is the strongest thing your antenna can hear. The device’s sense of the world is genuinely its own.
The local database lookup is the clever bit
ADS-B broadcasts an ICAO 24-bit address — a unique hex identifier for the airframe — and often a flight callsign. It does not broadcast the aircraft type, the operator, or the registration in a human-readable form.
So a tracker that wants to show “Boeing 737-800, Ryanair” has to look that up. The API version asks a server. FltCast carries a local database — a static file mapping ICAO addresses to registrations and types, which is public data and small enough to ship.
This is the pattern that makes the whole thing offline-capable, and it generalises enormously. Most enrichment does not need to be live. Aircraft registries, train schedules, tide tables, star catalogues, species lists, postcode geometries, chemical properties — all large, all static enough to ship, all routinely fetched from an API because fetching is the default habit. A 50MB file on the SD card removes an entire class of failure.
Why C++ and a 64×32 matrix, and when that’s the right call
HUB75 panels have no controller. Unlike an addressable LED strip, a HUB75 matrix has no memory and no logic — it is a shift-register array that displays exactly one row at a time. To show an image you must continuously scan every row, fast enough that persistence of vision fuses it, while also doing binary code modulation to get colour depth. On a Raspberry Pi this is done by bit-banging GPIO under tight timing, which is why the standard library for it is C++ and why it is sensitive to anything that steals CPU.
Which explains the choices: C++ because the display refresh is a real-time task, and 64×32 because that is a sensible panel size for a desk object and keeps the scan rate comfortable.
It is also why FltCast displays one aircraft at a time rather than a radar view. 64×32 is 2,048 pixels. You can fit a callsign, an altitude and a type, legibly, or you can fit an unreadable map. Picking the nearest aircraft and showing it properly is the correct response to the constraint.
What to build from this
The transferable architecture is: a radio that hears something real, a decoder, a local enrichment database, and a display that shows one thing well. Swap the radio and you have a different piece:
- Marine AIS on 161.975/162.025MHz — ships, same idea, same $30 dongle
- ACARS — aircraft text messaging, on VHF
- Weather satellite imagery from NOAA APT, which is one of the most satisfying things an SDR can do
- Local weather stations, tyre-pressure sensors, utility meters on 433/868/915MHz via
rtl_433, which decodes hundreds of consumer devices - Lightning detection, pager traffic, radiosondes
Each of those is an object that knows something about the physical world around it without asking anyone’s permission. That is a genuinely different quality from a screen showing an API response, and audiences can feel the difference even when they cannot name it.
If you want to start here, our RTL-SDR getting-started guide goes from dongle to decoded signal. And for the other end of this — SDR on a microcontroller with no dongle at all — see ESP-SDR.