This is an idea that has been on my mind for a long while to do, and now with the lockdown I’ve had some time to work on it.

ADS-B is used by aircraft to transmit their position to the ground. This information isn’t encrypted, and anyone can build themselves a receiver to take those transmissions and draw the aircraft on a map. This is very popular now especially with the availability of inexpensive radio receivers (e.g. the RTL SDR) and single-board computers (e.g. Raspberry Pi). The software is free and typically it’s used to feed online maps such as In fact sites like that usually provide a Raspberry Pi image file already set up to feed data to their servers where data from all the feeders is collated and used to drive an online map.

Why Put One On A Balloon?


Also, it would be interesting to see how much further the receiver can “see” once above local geography and how well that improves with altitude as Earth’s curvature becomes less of an issue.

So, my plan is to fly an ADS-B receiver, have it relay selected aircraft telemetry to the ground, and monitor how many aircraft it can see and the maximum distance of a received ADS-B transmission.


First thing is to set up an ADS-B receiver. I used the prebuilt Raspberry Pi image from flightaware, but others are available or the required software can be installed onto a vanilla Pi Raspbian image. For development I’m using a Pi 3B+, which I will swap for an A+ for the flight. The RTL SDR is one of these:


This is the program that deals with incoming ADS-B packets. Usefully, it emits a datastream on network port 30003, which can be examined on Linux with a command like this:

nc localhost 30003

and even in lockdown, this shows a very fast stream of messages flying up the screen:


As you can see, there are different message types; they are all documented at

Processing the Messages

My first coding job was to connect to this network port, apply some filtering to discard the messages I don’t need, and then parse and process the ones that I do. Specifically, those are the messages that contain aircraft positions.

So I took my standard PITS software, added a new thread for ADS-B, and had this open port 30003 and filter/parse/process the incoming messages.

Next job was to maintain a list of received aircraft, containing the latest position plus other information such as when it was received, how far away the aircraft is, etc.

Megabits Through Punybaud

For transmission to the ground we only have very low power and hence low bandwidth. I could have chosen something faster but I settled on a LoRa transmission in the 434MHz band, with a throughput of approx 200 bytes per second.

Each LoRa packet is a maximum of 255 bytes, which including the balloon position itself allows for flight positions per packet. I could have used binary packets but that would mean changing the receiver software and having all the other balloon receivers do a software update, so I compromised by packing each aircraft position into binary and then converting to base64 ASCII before appending to a standard UKHAS ASCII position sentence. The result was up to 7 aircraft positions per paclet, which equates to just over 5 aircraft updates per second.

That rate is nowhere near the incoming ADS-B update rate, however I don’t need aircraft to update quickly on the map – one update every 20 seconds say would be fine, which allows for 100 active aircraft. As I’m particularly interested in the most distant aircraft, I built a scheme where that aircraft is given priority in the transmission queue, so it is updated every 7 seconds and all the others are updated cyclically. Only active aircraft are transmitted, so aircraft that are now too distant will not be included in the cycle.

Here’s the log output from the tracker showing the data packets and some of the operation:

Array 119 used 51 --> 68 bytes 'TKZDJJZPQj/jBsBwlGKIMQE5XWebWFFCkuhDwBhHZ14rAjxLLyeCU0LBHI3AoIx1jl8G'
POSITIONS IN SENTENCE 3 - 3 are '71,5,67,'
LORA1: $$ADSB,6191,12:53:56,51.95033,-2.54445,00136,12,3,72,6069.6,TKZDJJZPQj/jBsBwlGKIMQE5XWebWFFCkuhDwBhHZ14rAjxLLyeCU0LBHI3AoIx1jl8G*5908
Array 119 used 68 --> 92 bytes 'rOX8PCBQQu/m+b9YGy8TnwE5XWeRVVFCsvRDwDFHZ14pAjxLLyeCU0LBHI3AoIx1jl8GTKZDMZZPQvQaB8BwlGKILwE='
POSITIONS IN SENTENCE 4 - 3 are '33,5,67,71,'
LORA1: $$ADSB,6192,12:53:58,51.95033,-2.54445,00136,12,3,72,6069.6,rOX8PCBQQu/m+b9YGy8TnwE5XWeRVVFCsvRDwDFHZ14pAjxLLyeCU0LBHI3AoIx1jl8GTKZDMZZPQvQaB8BwlGKILwE=*9CD6


This is my standard LoRa Gateway receiving the packets:

I’ve set this feeder to deliver incoming packets to my server, using these settings:


That server used to be on an Amazon EC2 Ubuntu machine, but Amazon pricing is less predictable than CV-19 transmission so I’ve recently moved it to OVH; their simpler control panel is a welcome bonus.


The server program is written in Delphi, which can (amongst other things) target Windows or Linux for console apps. I’m testing on Windows but transfer to the actual Linux server is trivial.

I used this same scheme last year for my Apollo flight where, as this time, I wrote a custom web dashboard that was fed from the server. Since then I’ve started reworking the system so that it maintains a small database (a kind of habhub-lite) for flights, payloads and listener stats etc.

So this server accepts messages from the LoRa Gateway, does some processing (such as extracting the flight telemetry from the base64 strings) and then feeds balloon and aircraft positions to a web application. Here’s the log from the server in action:

Web App

Again, this is written in Delphi, using the TMS Web Core system which provides an IDE to design the web page in a similar way to regular Delphi GUI apps, to write the code again very similar to a regular Delphi app, with the difference being that instead of being compiled and linked into an .exe or .apk or whatever binary, it produces HTML and Javascript as understood by any number of browsers. TMS include a number of design controls including a Google map, so building an app like the following is not a difficult process:


The app connects to over a web socket, from which it receives balloon telemetry (which feeds the status box at top-right and draws the balloon on the map) plus aircraft telemetry which it displays in the grid on the right and as aircraft icons (pointing in the approx correct direction) on the map.

The Flight

I don’t have a date for this yet, but with lockdown easing it might be feasible soon. I have some final things to do in the software, such as retiring aircraft from the map/grid when they haven’t been seen for a while, but I don’t expect major changes.

One Reply to “HAB Tracker with ADS-B Receiver”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.