HAB Base Update V1.4.0

I’ve released a new version of HAB Basem which is intended for easy management of one or more receivers from a Windows PC.

The changes are:

  • Support for Sondehub import via UDP
  • Support for local Sonde data from a rdzTTGOSonde receiver via UDP
  • Map shows the predicted path and landing point of the balloon
  • Balloon burst altitude can be set for the prediction
  • UI changes to fix issues on high-DPI monitors and other systems where Windows has a font stretch factor set to other than 100%.
  • The APRS source can also be used for OGN (Open Glider Network)
  • Fixed error when removing old payloads
  • Settings window for serial sources shows the list of COM ports to choose from
  • Payloads can be removed from the list and map, either till the next telemetry from that payload, or blocked while the program is running.

Download the installer from here.

rdzTTGOSonde

This is receiver for radiosondes, running on a TTGO ESP32/LoRa board with OLED. It emits position packets using UDP on the wireless network to which it is connected. HAB Explora, PADD and Base can all now decode these packets.

To configure:

  • In Settings –> Other, set the UDP Rx port to whatever you like (I use 12004 which is one of a set that I have reserved for HAB use on my networks, but you can use whatever works for you)
  • In the rdzTTGOSonde configuration, set the UDP transmit port to match above (see screenshot below).
  • In the rdzTTGOSonde configuration, set the UDP transmit IP address to either the known IP address of the device running HAB Explora/PADD or, better, use the UDP broadcast value for the local network. For the latter, use the IP address by taking the local subnet value and set all 1’s in the host portion. For example, if a device has an address 192.168.1.156 and a subnet mask 255.255.255.0, then the broadcast address is 192.168.1.255.

These are the settings in the rdzTTGSonde configuration page:

Flight Prediction

For payloads that do not include their own predicted landing position, HAB Base now refers to the online Tawhiri predictor to calculate not only the predicted landing position but also the flight path.

For payloads that are still ascending, the program initially assumes a burst altitude of 30km however this can be adjusted by opening the payload window and choosing the “Settings” tab:

OGN

This is a system used by gliders and other light aircraft, being broadly equivalent to the ADS-B system but at a much lower cost. OGN receivers upload to a server which HAB Base can now receive from. The received packets are in APRS format so to receive them you should create a new APRS Source within HAB Base, and set the host to aprs.glidernet.org:

To configure:

  • Click the “…” button next to an existing source
  • Choose “Add New Source” from the menu
  • Choose APRS/OGN from the “type of new source” list
  • Fill in the code and name as normal
  • Set the host box to be aprs.glidernet.org
  • Leave the port as 14580

Sondehub

If you previously used HAB Base to monitor radiosondes, you noticed a while ago that this stopped working. This is due to the sondehub system being separated from habhub. Sondehub has its own http and websocket APIs, different to habhub.

To import from sondehub to HAB Base, you need a Linux or Windows machine with Python 3 and Pip3 installed, onto which you run a small Python script to import filtered telemetry from sondehub and emit locally via UDP.

The following steps are for Raspberry Pi OS:

sudo pip3 install paho-mqtt
sudo pip3 install boto3
git clone https://github.com/projecthorus/pysondehub.git
cd pysondehub
wget hab.daveakerman.com/files/SondehubToUDP.py

Then to run the script, enter a command of the format:

python3 SondehubToUDP.py <latitude> <longitude> <max_distance_in_km> <target IP address> <port>

You can use these parameters to select a central point (e.g. your location) and the radius of a circle around it, so that the script only emits positions of radiosondes that are within that circle.

The “target IP address” is that of your Windows PC that runs HAB Base.

“Port” can be any unused port number; I use the value 12013 which is part of a set that I reserve for HAB communications on my network.

Example:

python3 SondehubToUDP.py 51.95023 -2.54445 1000 192.168.1.172 12013

The script will display the telemetry for each position report that it receives from sondehub and which is within the circle defined.

Once this is running, open HAB Base and create a new Source. Select the source type as “UDP”, fill in the code and name as usual, and set the port to be the same value you used for the script earlier. e.g.:

Finally, click the Save button.

The new source will then run, e.g.:

Note: Remember that HAB Base has its own distance filter, which it applies to this source, and this would normally be set the same as the value used for the script.

UCS Flight – Video Streaming

This was a school flight, where they built the payload and did the launch, I supplied a self-contained radio tracker, and a 3rd party supplied 2 rugged mobile phones to take video during the flight. It gave me a chance to test a live streaming setup that I intend to use on all of my flights from my launch site.

Since the school’s payload weight was already about right for the parachute size, I decided to use a lightweight tracker in a small foam egg. Based on a small AVR, it doesn’t include landing prediction but is a reliable basic LoRa tracker. I set it to mode 1 with a packet sent every 5 seconds, and I enabled calling mode so that receivers could be set to the calling channel.

Live Streaming

I’ve streamed video from the launch site before, but that has been either directly from a Raspberry Pi with a camera (using ffmpeg to stream to YouTube) or with a camcorder connected to a video capture device connected to a laptop.

For this flight I tested a new, more flexible setup. I used the popular and free OBS (Open Broadcaster Software) which is an incredibly capable program for combining various video and other sources into a single video screen which it can record locally and/or stream to various online services, including YouTube.

The basis of my stream was an IP camera in my garden, looking over the area I use for filling the balloon. All that needed to be done was to find the URL for the camera video stream, and enter that as a video source in OBS.

Next I wanted to add telemetry from my tracker. I now run my own internet server which runs a program that collects balloon telemetry from various sources, including my LoRa receivers at home. So I needed a way of displaying this telemetry as a text overlay on top of the IP camera video. One of the OBS options is to feed the contents of any program window into the output video stream, so I wrote a small program to collect the telemetry from my server, write that as text on a green background, add this program as a video source into OBS, and finally add a ChromaKey filter within OBS that removes the green background.

I also wanted to add data from my weather station. That station automatically uploads to various services every few seconds, including Wunderground which has an API for getting the current data from any station. So I added some code to my internet server that polls Wunderground for this data every few seconds, and then sends it my overlay program. This is how the ChromaKey works:

Image

Finally, I added the school’s logo as a fixed transparent bitmap, and set OBS to stream to my YouTube channel. Here’s the resulting stream, just before launch:

The Launch

Predictions for the flight were fairly stable, with the landing position moving steadily SE during the day. The launch was a bit later than planned so it did land further SE than planned, but more on that later.

DCIM\100MEDIA\DJI_0009.JPG

The day itself was very hot, during a week-long UK heatwave with daily temperatures up to 30 degrees C. So hot in fact that the mobile phones used for flight overheated when still on the ground! They were cooled prior to launch by dipping them in a tub of water (I told you they were rugged!).

Here are the team, posing with probably the largest helium balloon they’ve ever seen!

Launch was easy enough, though the excited schoolkids launched the balloon before I’d had a chance to get my drone ready to record the launch; I’m hoping to record or possibly stream drone footage on my next flight. So here instead is the launch captured by my field time-lapse camera:

The Flight

The flight proceeded pretty much as expected, however a combination of factors meant that it landed further south than planned, which could have been unfortunate as that took it into the Forest of Dean. Why are balloons magnetically attracted to trees?? Those factors were that after the initial ascent rate being the planned 5-5.5m/s, the ascent slowed once it entered the stratosphere, resulting in it spending longer in a south-westerly direction.

Later, heading west, it ascended almost 3km above the prediction, bringing it further west. So the net shift was a shift south-west from the planned landing near Longhope:

Note the large expanse of green in that map. And note the high density of (very tall) trees that it successfully managed to avoid by landing in a clearing!

Recovery

We were about 2 miles away in out chase car when it landed, without a radio signal from the tracker due to a hill in the way. After stopping to check the landing position and the route, we approached along that road you can see near the landing spot, turned into the drive and called the other chase cars. At that time I spotted the parachute in the field (see arrow at the right of the image):

Once permission was obtained from the landowner, the team walked across the field to recover their precious payload!

And here they are, checking the footage that they got from their 2 phones – one with a regular camera and the other with an infra-red camera:

Finally, if you want to watch any of the launch stream, it’s here:

Receiving From LoRa High Altitude Balloons

Many high altitude balloons these days use LoRa, because it’s simple and inexpensive to use in the balloon and in the receiver, and because it offers extra features such as uplinks that are difficult to do otherwise.

For other systems such as RTTY and APRS, the receiver can be a software defined radio (SDR) or a ham radio receiver. LoRa however is different, and requires a specific LoRa receiver.

Fortunately LoRa transceiver modules are cheap and easily available. Essentially, they just need connecting to a suitable computer which sets the frequency and some other parameters, connecting to a suitable antenna, then the module does all the hard work of receiving, demodulating and decoding the radio signal, delivery a packet (sequence of bytes) containing telemetry or imagery to the attached computer.

This article is about how to obtain or build such a receiver and what software to use with it.

Types Of Receiver

As explained, the LoRa module does all of the hard work, meaning that the attached computer can be quite simple. As simple in fact as a basic Arduino or similar microcontroller. Add some firmware and a small display, and you have something that can display the current position of the balloon. Add a GPS module and it can display the distance and direction to the balloon. What more could you need?

Well, you might want to see the balloon on a map. You might want to have on-screen and audio navigation to drive to the nearest road to the balloon.

Or you might be receiving from home, where you might want to manage multiple LoRa receivers so you can receive from multiple balloons. You also want to upload the telemetry and imagery to the online servers so th\at you can contribute to the tracking of someone else’s flight.

All of these are possible, using Arduno or ESP32 microcontroller, or Android phones or tablets, or a Windows PC. Below I describe the devices apps and programs that I have built and shared for you to use.

Standalone Arduino LCD Receiver

This is as simple as it gets – an Arduino Mini Pro connected to a good old text-mode 2-line LCD, with GPS for positioning and a Lipo for power, with USB charging. Simplicity is a good thing when chasing a balloon, and something like this will find your payload with very little fuss.

P1090766

That photo is from during the build, before it got an Apple-esque single pushbutton for all functions, including frequency selection.

For more information, see my blog article and the github repository.

I want you to take great care of this equipment, Mr Bond.

If the above is a bit too boxy for you, how about chasing a balloon with a watch?

Image

This is the TTGO TWatch2020, which doesn’t contain a LoRa module (their earlier but bulkier watch did), but does have bluetooth meaning it’s easy to link to a TTGO T-Beam which has LoRa, GPS, ESP32 processor and LiPo battery in one package. So the watch does the user interface stuff, allowing choice of frequency etc., and displaying the position of the balloon and the distance and direction to it, while the T-Beam (pictured in a 3D-printed box and attached to an aerial) does all the radio and GPS stuff.

See my blog post for details, plus the watch firmware and T-Beam firmware.

Raspberry Pi

Using a single or dual channel LoRa expansion board, it’s easy to build a LoRa receiver based on any Raspberry Pi (aside from the Pico). Uputronics sell a single or dual channel board for which I wrote the Pi LoRa Gateway program.

This is a popular choice for fixed receivers. The software is open source and provides the ability to tune in to, receive and upload both telemetry and images (SSDV). This is the oldest and most capable LoRa HAB receiver software available. Also, it can be linked to the HAB Base software below.

USB OTG Receiver

This is a commercial device that integrates a LoRa module with a pre-programmed microcontroller, for connection to an Arduino phone or tablet, or a PC, to provide a complete receiver setup including mapping and uploads to the central map and imaging servers.

The device is available from Uputronics, and by purchasing you are helping to fund development of the supporting software below:

  • HAB Explora for Android Phones
  • HAB PADD for Android Tablets
  • HAB Base for Windows PCs

HAB Explora

Currently this targets Android only; if you are an iOS user then please get in touch. Its aim in life is to make it easier to chase balloons, by showing the position on a map and by providing navigation via phone navigation app.

Data sources (i.e. sources of balloon telemetry/imagery) include the LoRaGo product above, plus a DIY solution using my firmware. The app is free to use, with funding for development coming from sales of LoRaGo and my BuyMeACoffee account.

HAB PADD

Currently this targets Android only; if you are an iOS user then please get in touch. Its aim in life is to make it easier to chase balloons, by showing the position on a map and by providing navigation via phone navigation app.

Data sources (i.e. sources of balloon telemetry/imagery) include the LoRaGo product above, a DIY solution using my firmware, UDP (e.g. from auto_rx for Sondes), and up to two LoRa Pi Gateways (see above). The app is free to use, with funding for development coming from sales of LoRaGo and my BuyMeACoffee account.

HAB Base

This is a Windows program designed to make it easy to manage one or more LoRa receivers at a base station. If you want to use LoRaGo with a PC, this is for you. If you want a nice GUI to manage your Pi LoRa Gateway, this is for you. If you want to centralise control of multiple LoRa receivers, this is definitely for you!

For more information. see this article.

Again, this is free software, so donations are welcomed !

Uplinks

Whilst most high altitude balloons only transmit data (telemetry and sometimes images) down to the ground, there are several applications for sending data to a balloon, for example:

  • Requesting re-send of missing image packets
  • Balloon repeating of other balloon telemetry
  • Commanded cutdowns etc.

My PITS software and LoRa gateway already provide the first option, and I’ve flown a balloon network before. What my released software has lacked up to now is the ability to upload commands. So now, after a lot of work on the various components, I am pleased to announce an uplink system that:

  • Can command a payload to cutdown, switch an output, control a servo or run a script
  • Works with various trackers: Pi In The Sky, FlexTrack (generic AVR and ESP32 tracker code) and FlexTrak (Pi Zero AVR tracker)
  • Works with various ground station software: Pi LoRa Gateway, HAB Explora, HAB PADD, HAB Base
  • Encrypts the radio link to protect the tracker against 3rd party attacks
  • Works with different radio timing schemes e.g. TDM

Commands

The commands implemented so far are:

  • Cutdown the flight now
  • Set cutdown altitude (tracker will cut down when this altitude is reached)
  • Set an output on
  • Set a servo to specified position
  • Run a named script or command

Not all of these are available in all trackers – for example scripting is only implemented on Pi In The Sky.

Timing

is everything.

Pretty obviously, each command has to be sent when the tracker is listening. So both the tracker and the ground transmitter have to use the same timing scheme so that the tracker listens at certain times and the transmitter only transmits during those times.

Where the tracker needs to transmit a lot – which basically means trackers that send image data as well as telemetry, then the recommended scheme is for the tracker to listen for a few seconds each minute. The transmitter then needs to be set to transmit at some point during the listening window. For example the tracker might listen from the 0s mark to 5 seconds past the minute, and the transmitter is then set to transmit beginning at the 2-second mark. Remember that packets take a finite time to transmit (around 1 second in LoRa mode 1) so be sure to arrange the timings to allow for that.

For trackers that only send telemetry, then a better scheme is to set the tracker in TDM (Time Division Multiplex) mode. This specifies a repeat period – say every 10 seconds – and a time slot within those 10 seconds at which the tracker transmits – say slot 5 which would be at 5, 15, 25, 35, 45 and 55 seconds past the minute. An advantage of this method is that you can have multiple trackers using the same frequency and same TDM period but each with a different slot. Remember that transmit times may preclude the use of adjacent slots. The ground transmitter can then be set to transmit at a certain time, or simply transmit immediately after it receives a packet from a balloon.

Tracker Configuration

Pi In The Sky

Timing Settings

If you are using SSDV, then use settings like these in pisky.txt:

LORA_Uplink_Cycle_1=60
LORA_Uplink_Period_1=5

This sets the tracker to listen for the first 5 seconds of each minute. Use “_1” for a module in CE1 position, or “_0” for CE0.

If you are not using SSDV, then set TDM mode instead:

LORA_Cycle_1=10
LORA_Slot_1=2

This example transmits packets once every 10 seconds, at 2, 12, 22 etc seconds past each minute.

Cutdown Settings

Cutdown needs to be configured, minimally with these settings:

Enable_Cutdown=Y
Cutdown_Period=5
Cutdown_Pin=22

Which enables cutdowns, sets the default cutdown period to 5 seconds, and uses Wiring Pi pin 22 for the cutdown output. The output would normally then connect to a power MOSFET gate which then applies external power to a length of nichrome wire or a small low-value resistor.

The Pi In The Sky software also provides settings for automatic cutdowns such as “above altitude of x metres” or “flights longer than y minutes”; see the source or await documentation on these and other options.

Encryption Password

Set this, and to something other than SECRET, or take the huge risk that someone else will deliberately upload commands to your tracker!

Uplink_Code=SECRET

Ground App Usage

HAB Explora

See my blog post on how to use uplinks from HAB Explora.

If you are using SSDV, then use the “Send on n’th second option”, and set the time to be just before the centre of the tracker’s listening window. e.g. 2 seconds for the settings above.

If you are using the TDM option, then use “Send After Rx” instead.

Don’t use “Send Now” for either option, unless you’re feeling brave.

HAB PADD

See my blog post on how to use uplinks from HAB Explora.

If you are using SSDV, and uploading from a USB or Bluetooth device, then use the “Send on n’th second option”, and set the time to be just before the centre of the tracker’s listening window. e.g. 2 seconds for the settings above.

If you are using the TDM option, and uploading from a USB or Bluetooth device, then use “Send After Rx” instead.

If you are uploading via a LoRa Gateway, then the timing is done by the gateway, so the see section below on how to configure that.

HAB Base

First, select the source device that you wish to transmit through. This can be a serial device (USB or Bluetooth) or a LoRa Gateway. If it’s a gateway then you need to set up the timing scheme separately – see the gateway section below.

For gateway sources you will see:

The target payload should be filled in for you, using the last payload received by that gateway, but you can choose a different payload if you wish. Remember to select the correct LoRa channel 0 or 1 to match the device CE0 or CE1.

Choose the command you want to send, with any parameters as appropriate.

For USB or Bluetooth serial sources, you will see a slightly more complicated panel:

This time you also need to enter the encryption password, and when to send. If you are using SSDV then use the “Send on n’th second option”, and set the time to be just before the centre of the tracker’s listening window. e.g. 2 seconds for the settings above.

If you are using the TDM option then use “Send After Rx” instead.

HAB Gateway

Set the timing in gateway.txt to match the tracker settings. e.g. to transmit at 2 seconds past the minute, with our top-secret encryption code:

UplinkTime_0=2
UplinkCycle_0=60
UplinkCode=SECRET

Command Format

The uplink packets begin with ‘*’ which tells the tracker that a command follows. The basic format is:

* <encrypted message>


The encryption is a simple 7-bit XOR with a secret code known to the transmitter (ground station) and receiver (tracker), with the high bit set on each byte.  Decrypted, the message format is:


* <payload ID> / <command> <parameter 1> [,<parameter 2> etc]

Commands are:

  • C = Cutdown
    • CN = Cutdown now.  Parameter = cutdown time in seconds
    • CA = Cutdown at specified altitude; Parameter = Altitude.
  • H = Reserved
  • D = Reserved
  • P = Switch on output pin
    • P <pin>/<seconds>
  • S = Servo output
    • S <pin>/<seconds>/<position>
  • R = Run script
    • R <script>

HAB Explora Update

Explora is an app for Android phones to aid with chasing balloons. It shares a HAB library with my HAB PADD app and HAB Base Windows program. You can read more about the app here.

I’m about to release an updated version with several changes:

  • AFC on LoRa gateway, USB, Bluetooth sources
  • Frequency search function on LoRa USB and Bluetooth sources
  • Uplink to HAB for AFC LoRa USB and Bluetooth sources
  • More robust parsing
  • Handle regional variations in number formats

AFC

AFC is Automatic Frequency Control. It’s available within Explora for LoRa sources – USB and Bluetooth. Once you start receiving LoRa packets from a balloons, AFC will first correct any frequency error and then will continue to correct any errors of 1kHz or greater, which is useful if the balloon transmitter drifts with temperature.

AFC is recommended for LoRa modes 0 and 1 which are narrow bandwidth and have a correspondingly narrow capture band of +/- 4kHz difference between transmitter and receiver frequencies. For other LoRa modes it is better to leave AFC off as those modes can cope with much greater frequency errors than you will see.

To enable AFC, touch the Settings button then the source you want to set and then the AFC button. Press Apply to save.

Frequency Search

For the LoRa modes 0 and 1, it’s possible that with the transmitter (balloon) and receiver (Explora) set to the same nominal frequency, there’s actually a larger frequency offset between the two than the LoRa modules can cope with. This can make it frustrating to tune in to a transmitter even if you know the nominal frequency it is set to.

To aid with this situation, both LoRa sources now have frequency search functions on their settings screens:

To use, first set the LoRa mode and nominal frequency used by the transmitter, and then click the Search button. Explora will then cycle through the target frequency range, looking for a transmission. Once it starts receiving packets on a specific frequency, it will stop searching and will set the receive frequency to match the transmitted frequency.

Only use this function with LoRa Mode 1. Mode 0 is too slow for the search function to work, and other modes do not need the search function anyway.

Uplinks

I will cover uplinks in detail in a separate blog post, including how to configure your tracker to receive and process the uplinked messages. So here I will just cover how to send uplinks from Explora.

Uplinks to a balloon can be very useful. So useful in fact that they can rescue a flight that would otherwise be lost. If you have a cutdown device on your flight, and you see that the balloon is headed for the sea due to a slow ascent for example, then you can order the payload to cut itself away from the balloon and land on land.

Explora now provides an Uplink page:

The top 3 buttons are for up to 3 balloon payloads being received. The buttons are filled in automatically as payloads are received and, if there is more than one, then you need to select the payload to upload to.

The next 2 buttons show the available sources that allow for uplinks.

The next section shows the different types of uplink command, which are:

  • Cutdown Now
  • Cutdown when balloon reaches specified altitude
  • Switch specified tracker output on
  • Set specified payload servo to given position
  • Run specified script or program on tracker

Not all of these will be available for any given tracker.

The lower section determines when to send the message. For the tracker to see your message, it has to be sent at a time when the tracker is listening and not transmitting. Explora offers 3 options:

  • Send now. It’s up to you to know when to send!
  • Send at particular time in the minute. For trackers that are normally transmitting but sometimes have a short listening period, this is the best option.
  • Send after the next packet is received. This is best for trackers that transmit one packet then wait for a period before sending the next.

Below that section is a box for a password. This is used to encrypt the message before transmission, and should match the password used by the tracker to decrypt the message. This makes it very unlikely that a 3rd party could send valid commands through to your balloon.

Follow me on Twitter for release announcements of this and other apps.

HAB PADD Update

PADD (named after the Star Trek tablets) is an app for Android tablets to aid with chasing balloons. It has a few more functions than my phone app (Explora), and both apps share the same common HAB library with my HAB Base program. You can read more about the app here.

I’m about to release an updated version with several changes:

  • AFC on LoRa gateway, USB, Bluetooth sources
  • Frequency search function on LoRa USB and Bluetooth sources
  • Uplink to HAB for AFC LoRa gsteway, USB, Bluetooth sources
  • More robust parsing
  • Handle regional variations in number formats

AFC

AFC is Automatic Frequency Control. It’s available within PADD for LoRa sources – USB, Bluetooth and the Pi LoRa Gateway. Once you start receiving LoRa packets from a balloons, AFC will first correct any frequency error and then will continue to correct any errors of 1kHz or greater, which is useful if the balloon transmitter drifts with temperature.

AFC is recommended for LoRa modes 0 and 1 which are narrow bandwidth and have a correspondingly narrow capture band of +/- 4kHz difference between transmitter and receiver frequencies. For other LoRa modes it is better to leave AFC off as those modes can cope with much greater frequency errors than you will see.

To enable AFC, touch the Settings button then the source you want to set and then the AFC button. Press Apply to save.

For the gateways, AFC is performed on the gateway itself so PADD just tells the gateway to enable AFC on the selected channel. For USB and BT sources, PADD does the AFC itself.

Frequency Search

For the LoRa modes 0 and 1, it’s possible that with the transmitter (balloon) and receiver (PADD) set to the same nominal frequency, there’s actually a larger frequency offset between the two than the LoRa modules can cope with. This can make it frustrating to tune in to a transmitter even if you know the nominal frequency it is set to.

To aid with this situation, the USB and Bluetooth sources now have frequency search functions on their settings screens:

To use, first set the LoRa mode and nominal frequency used by the transmitter, and then click the Search button. PADD with then cycle through the target frequency range, looking for a transmission. Once it starts receiving packets on a specific frequency, it will stop searching and will set the receive frequency to match the transmitted frequency.

Only use this function with LoRa Mode 1. Mode 0 is too slow for the search function to work, and other modes do not need the search function anyway.

Uplinks

I will cover uplinks in detail in a separate blog post, including how to configure your tracker to receive and process the uplinked messages. So here I will just cover how to send uplinks from PADD.

Uplinks to a balloon can be very useful. So useful in fact that they can rescue a flight that would otherwise be lost. If you have a cutdown device on your flight, and you see that the balloon is headed for the sea due to a slow ascent for example, then you can order the payload to cut itself away from the balloon and land on land.

PADD now provides an Uplink page:

The left column has 3 buttons for up to 3 balloon payloads being received. The buttons are filled in automatically as payloads are received and, if there is more than one, then you need to select the payload to upload to.

The next column shows the various sources, and you can choose from any source that is receiving from one of those payloads.

The top-right of the screen shows the different types of uplink command, which are:

  • Cutdown Now
  • Cutdown when balloon reaches specified altitude
  • Switch specified tracker output on
  • Set specified payload servo to given position
  • Run specified script or program on tracker

Not all of these will be available for any given tracker.

The centre-right of the screen determines when to send the message. For the tracker to see your message, it has to be sent at a time when the tracker is listening and not transmitting. PADD offers 3 options:

  • Send now. It’s up to you to know when to send!
  • Send at particular time in the minute. For trackers that are normally transmitting but sometimes have a short listening period, this is the best option.
  • Send after the next packet is received. This is best for trackers that transmit one packet then wait for a period before sending the next.

Note that for the LoRa Gateway, timing is done by the gateway itself so you need to configure the uplink timings there.

The bottom-right section contains a box for a password. This is used to encrypt the message before transmission, and should match the password used by the tracker to decrypt the message. This makes it very unlikely that a 3rd party could send valid commands through to your balloon.

Follow me on Twitter for release announcements of this and other apps.

Windows LoRa HAB Gateway V1.7

LoRa modules tend to have cheap and cheerful crystals that aren’t particularly accurate, resulting in any given 434MHz module being up to about 5kHz off the nominal frequency, any given pair of modules could disagree by to 10kHz.

For the bandwidth setting most often used in HAB, the total offset between transmitting and receiving modules has to be no more than 5kHz otherwise no packets will be received, so it’s entirely possible for 2 modules not to work when set to the same nominal frequency.

The result then is some frustration till the user tries adjusting the receive frequency till it works. To make this easier, I’ve added some new functions to help with finding a signal. These are currently in my Windows LoRa Gateway, but will soon make their way to my Android apps. These functions are:

  1. Band Scan – Scan the entire 434MHz band for a signal, and show the results on a chart.
  2. Local Search – Adjust the set frequency up and down by up to 10kHz till packets are received.
  3. AFC – Automatic Frequency Control – To keep the receiver and transmitter locked in case either drift (possible during flight if the transmitter gets cold).

Band Scan

Click on the new “Band Scan” tab at the bottom, then click the “Scan Band For Signal” button.

The scan range is currently fixed at 434MHz to 434.7MHz. The chart shows the RSSI across the band, sampled at 12.5kHz intervals. It’s best to have the LoRa mode set to 1 for this test.

Clearly, there’s a strong local signal at about 434.45MHz.

Local Search

Ensure that you’ve set the LoRa mode correctly, and the nominal frequency that the transmitter is set to, then click on the new “Search +/- 1kHz” button. The program will search near that frequency until it starts to find packets.

This should be used for Mode 1 only: Mode 0 is too slow for this search, and other modes do not need searching anyway (they have wider acceptable frequency offsets).

AFC

Once the receiver is receiving packets OK, check the AFC box to keep it locked in to the transmitter.

Get It

The executable is here.

Or you can download the source and build yourself. It’s written with in Delphi and uses the TMS Async library.

Pi Pico Balloon Tracker

Balloon Tracking

As you may know, my main hobby is flying weather balloons, using GPS/radio trackers to relay their position to the ground, so they can be tracked and hopefully recovered. Trackers minimally consist of a GPS receiver feeding the current position to a small computer, which in turn controls a radio transmitter to send that position to the ground. That position is then fed to a live map to aid chasing and recovering the flight.

system-1024x813-500x396

This essential role of the tracker computer is thus a simple one, and those making their own trackers can choose from a variety of microcontrollers chips and boards, for example Arduino boards, PIC microcontrollers or the BBC Microbit. Anything with a modest amount of code memory, data memory, processor power and I/O (serial, SPI etc depending on choice of GPS and radio) will do. A popular choice is the Raspberry Pi, which whilst a sledgehammer to crack a nut for tracking, does make it easy to add a camera.

Pi Pico

When I see a new type of processor board, I feel duty bound to make it into a balloon tracker, so when I was asked to help test the new Pi Pico doing so was my first thought. It has plenty of I/O – SPI ports, I2C and serial all available – plus a unique ability (not that I need it for now) to add extra peripherals using the programmable PIO modules, so there was no doubt that it would be very usable. Also, having much more memory than typical microcontrollers, it offers the ability to add functions that would normally need a full Raspberry Pi board – for example on-board landing prediction. More on that later.

Tracker Components

So a basic tracker has a GPS receiver and radio transmitter. To connect these to the Pico, I used a prototyping board where I mounted a UBlox GPS receiver, LoRa radio transmitter, and sockets for the Pico itself. I don’t use breadboards as they are prone to intermittent connections that then waste programming time chasing a “bug” that’s actually a hardware problem. Besides, trackers need to be robust so I would need to solder one together eventually anyway.

Pico top, GPS bottom-left; LoRa bottom-right

The particular UBlox GPS module I had handy only has a serial port brought out, so I couldn’t use I2C. No matter because, unlike most Arduino boards, the Pico isn’t limited to a single serial port.

The LoRa module connects via SPI and a single GPIO pin which the module uses to send its status (e.g. packet sent – ready to send next packet) to the Pico.

Finally, with the tracker working, I added an I2C environmental sensor to the board via a pin header, so the sensor can be placed in free air outside the tracker.

Finally, with the tracker working, I added an I2C environmental sensor to the board via a pin header, so the sensor can be placed in free air outside the tracker.

Development Setup

I decided to use C for my tracker rather than Python, for a variety of reasons. The main one is that I have plenty of existing C tracker code to work from, for Arduino and Raspberry Pi, but not so much Python. Secondly, I figured that most of the testers would be using Python so there might be more of a need to test the C toolchain.

The easiest route to getting the C/C++ toolchain working is to install on a Pi4. I couldn’t quite get the VSCode integration working (finger trouble I think) but anyway I’m quite happy to code with an editor and separate build window. So what I ended up with was Notepadd++ on my Windows PC to edit the code, with the source on a Pi 4. I then had an ssh window open to run the compile/link steps, and a separate one running the debugger. The debugger downloads the binary to the Pico via the latter’s debug port.

For regular debug output from the program I connected a Pico serial port to an FTDI USB Serial TTL adapter connected back to my PC – see the pic.

At some point I’ll revisit this setup. First, it’s now possible to printf to a virtual USB serial port, so that frees up that Pico serial port. Secondly, I need to get that VSCode integration working.

Tracker Code

My Pi and Arduino tracker programs work slightly differently. On the Pi, to separate the code for the different functions (GPS, radio, sensors etc) I use a separate thread for each. That allows for example a new packet to be sent to the radio transmitter without delay, even if a slow operation is running concurrently elsewhere. On the Arduino, with no threads available, the code is still split into separate modules but each one is coded to run quickly without waiting in a loop for a peripheral to respond. For example some temperature sensors can take a second or so to take a measurement, and it’s vital not to sit in a loop waiting for the result.

The C toolchain for the Pico doesn’t, by default, support threaded code unfortunately. Rather than rebuild it with support added, I opted for the approach I use with Arduino. So the main code starts with initialising each module individually, and then sits in a tight loop calling each module once per loop. It’s then up to each module to return control swiftly so that the loop keeps running quickly and no module is kept waiting for long.

Code Modules

The GPS code uses a serial port to receive NMEA data from the GPS. NMEA is the standard ASCII protocol used by pretty much every GPS module that exists, and includes the current date, time, latitude, longitude, altitude and other data. All we need to do is confirm that the data is valid, then read and store these key values. The other important function is to ensure that the GPS module is in the correct “flight mode” so that it works at high altitude – without this then it will stop providing new positions about 18km altitude.

View NMEA Data Log

The LoRa radio code checks to see when the module is not transmitting, then builds a new telemetry message containing the above GPS data plus the name of the balloon, any other sensor data, and the landing prediction (see later). This message is passed to the LoRa chip via SPI, then the chip switches on its radio and modulates the radio signal with the telemetry data. Once the message has been sent then the chip switches on its DIO0 output which is connected to the Pico so it knows when it can send another message. All messages are received on the ground (in this case by a Pi LoRa receiver) and then uploaded to an internet database that in turn drives a live Google map:

Sensors

Usefully for balloon trackers, the Pico can be powered directly from battery via an on-board buck-boost converter. The input voltage connects through a potential divider to an analog sense input (ADC3) to allow for easy measurement of the battery voltage. Note that the ADC reference voltage is the 3.3V rail, which is noisy especially when used to power external devices such as the GPS and LoRa both of which have rather spiky power consumption requirements, so the code averages out many measurements. An alternative would be to add a precise reference voltage to the ADC but I went for the zero cost software option.

The board temperature can also be measured, this time using ADC4. That’s less useful though for a tracker than an external temperature measurement, so I added a BME280 device for that. The Pico samples include code for the BME connected via SPI, but I chose I2C so I needed to replace the SPI calls with I2C calls. Pretty easy. The BME280 returns pressure – probably the most interesting environmental measurement for a balloon tracker – and humidity too.

Landing Prediction

So far, everything I’ve done could also be done on a basic AVR chip e.g. the Arduino Mini Pro, with some spare room. However, one very useful extra is to add a prediction of the landing point.

We use online flight prediction prior to launch, to determine roughly where the balloon will land (within a few miles) so we know it’s safe to launch without landing near a city for example. This uses a global wind prediction database plus some flight parameters (e.g. ascent rate and burst altitude) to predict the path of the balloon from launch to landing. It can be very accurate if those parameters are followed through on the flight itself.

Of course the actual flight never quite follows the plan – for example the launch might be later than planned, and in changing wind conditions that itself can move the landing point by miles. So it’s useful to have a live prediction during that flight, and indeed we have that, using the same wind database. However, since it’s online, and 3G/4G can be patchy when chasing a balloon, it’s useful to have an independent landing prediction. This can be done in the tracker itself, by storing the wind speed and direction (deduced from GPS positions) on the way up, measuring the descent rate after burst, applying that to an atmospheric density model to plot the future descent rate to the ground, and then calculating the effect of the wind during descent and finally producing a landing position.

Typical Arduino boards don’t have enough memory to store the measured wind data, but the Pi Pico has more than enough. I ported my existing code which:

  1. During ascent, it splits the vertical range into 100 metres sections, into which it stores the latitude and longitude deltas as degrees per second.
  2. Every few seconds, it runs a prediction of the landing position based on the current position, the data in that array, and an estimated descent profile that uses a simple atmospheric model plus default values for payload weight and parachute effectiveness.
  3. During descent, the parachute effectiveness is measured, and the actual figure is used in the above calculation in (2).
  4. Calculates the time it will spend within each 100m section of air, then multiplies that by the stored wind speed to calculate the horizontal distance and direction it is expected to travel in that section.
  5. Adds all those sectional movements together, adds those to the current position, and produces the landing prediction.
  6. Sends that position down to the ground with the rest of the telemetry.

More Information

If you’re interested in flying your own balloon, start with this helpful guide:

T-Watch 2020 HAB Tracker

Earlier this year I posted an article about the TTGO Watch with the optional LoRa/GPS board, and how to program it to track LoRa high altitude balloons. Since then I’ve used it on a real flight where I found it ideal for checking that the balloon tracker was running fine while I filled the balloon.

Since then, LilyGo have started shipping a new watch which is slimmer (good!) but lacks the option of adding GPS or LoRa. So at first glance it doesn’t seem useful for HAB. However the watch does still have Bluetooth so it can be linked to a suitable GPS/LoRa device via a wireless link. For tracking balloons this is actually a better option, since the LoRa device can be much more easily connected to a good aerial, like so:

Image

So here we have a compact 434MHz Yagi antenna, connected to a TTGO T-Beam LoRa/GPS device with battery, housed in a 3D-printed enclosure and connected over Bluetooth to the T-Watch 2020. This is ideal for that “last mile” tracking once the balloon has landed.

TTGO T-Watch 2020

As you can see, this is much slimmer than the previous model (which is why there’s no space for the LoRa/GPS board), and looks more like a regular watch and less like something that only a geek would wear! Though if this is a concern then you probably don’t want to be seen carrying a Yagi either!

Otherwise it’s very similar to the original watch, with the same touchscreen display and the same processor. There are some differences internally but those are taken care of my the supplied Arduino library – you just tell it which model you have.

TTGO T-Watch 2020

TTGO T-Beam Board

This is a useful board that can be used as a LoRa receiver or even a LoRa HAB tracker. It has an ESP32 processor plus UBlox GPS and LoRa module (be careful to order one for the correct frequency band!).

LILYGO® TTGO T Beam V1.1 ESP32 433/868/915/923Mhz WiFi Wireless Bluetooth  Module GPS NEO 6M SMA LORA 32 18650 Battery Holder|Circuits| - AliExpress

It also includes a battery holder for a standard 18650 LiPo, so all it needs for this project is a suitable case. If you have access to a 3D printer then you’ll find no shortage of designs to choose from on thingiverse. Note that many designs include a hole for the OLED which most of the T-Beam boards do not have, so select appropriately.

Antenna

For chasing, a small Yagi aerial is ideal as it provides all you need – directional, easy to carry, and some gain. I got this model from Aliexpress:

Image

This model has an SO239 socket so I added an adapter to SMA and then a short SMA-SMA cable to connect to the T-Beam.

Image

Programming

Both the T-Beam and T-Watch can be programmed using the Arduino IDE, and LilyGo supply a library with examples for the latter.

To program the T-Beam, install an ESP32 board package into the IDE connect the watch to the host computer via a micro USB cable.  In the IDE, choose the “TTGO T-Beam” board option and select the correct serial port.

To program the T-Watch 2020, install the Lilygo library, and connect the watch to host the computer via a micro USB cable.  In the IDE, choose the “TTGO T-Watch” board option and select the correct serial port.

T-Beam Firmware

The aim here is to provide the the following capabilities for the host ESP32:

  1. Receive GPS latitude, longitude, altitude and direction
  2. Receive packets received by the LoRa module
  3. Set the LoRa module frequency and other settings
  4. Provide Bluetooth (BLE) serial link

Essentially, this is the same as what I have done before with Bluetooth-connected receivers, but I had to make a change to the BLE code to make it possible for the ESP32 in the watch to connect easily. Get the code from github.

T-Watch 2020 Firmware

Get the my firmware from github.

Operation

This is the same as for the original watch, so see my article on that.

There are no settings for the BLE link – the watch looks for a nearby BLE device with the serial port characteristic.

HAB Tracker with ADS-B Receiver

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 https://uk.flightaware.com/. 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?

Because.

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.

How?

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:

dump1090

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:

MSG,6,1,1,43C6E7,1,2020/05/13,12:38:15.140,2020/05/13,12:38:15.169,,,,,,,,1177,0,0,0,
MSG,5,1,1,AE4ECE,1,2020/05/13,12:38:15.145,2020/05/13,12:38:15.170,,12000,,,,,,,0,,0,
MSG,5,1,1,AE4ECE,1,2020/05/13,12:38:15.159,2020/05/13,12:38:15.173,,12000,,,,,,,0,,0,
MSG,8,1,1,A0A522,1,2020/05/13,12:38:15.165,2020/05/13,12:38:15.218,,,,,,,,,,,,0
MSG,3,1,1,06A2DE,1,2020/05/13,12:38:15.175,2020/05/13,12:38:15.220,,37000,,,50.64683,-6.32924,,,0,,0,0
MSG,3,1,1,4AB42F,1,2020/05/13,12:38:15.189,2020/05/13,12:38:15.223,,,,,,,,,0,,0,0
MSG,8,1,1,06A2DE,1,2020/05/13,12:38:15.190,2020/05/13,12:38:15.223,,,,,,,,,,,,0
MSG,8,1,1,06A2DE,1,2020/05/13,12:38:15.191,2020/05/13,12:38:15.223,,,,,,,,,,,,0
MSG,8,1,1,06A2DE,1,2020/05/13,12:38:15.194,2020/05/13,12:38:15.224,,,,,,,,,,,,0
MSG,8,1,1,06A2DE,1,2020/05/13,12:38:15.198,2020/05/13,12:38:15.225,,,,,,,,,,,,0
MSG,8,1,1,06A2DE,1,2020/05/13,12:38:15.200,2020/05/13,12:38:15.225,,,,,,,,,,,,0
MSG,8,1,1,06A2DE,1,2020/05/13,12:38:15.206,2020/05/13,12:38:15.226,,,,,,,,,,,,0
MSG,5,1,1,4012AD,1,2020/05/13,12:38:15.208,2020/05/13,12:38:15.226,,20100,,,,,,,0,,0,

As you can see, there are different message types; they are all documented at http://woodair.net/SBS/Article/Barebones42_Socket_Data.htm

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:

FLIGHT ID 4CA643
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
FLIGHT ID ACE5FC
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
FLIGHT ID 3C4B2F

Receiving

This is my standard LoRa Gateway receiving the packets:

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

EnableHablink=Y
HablinkAddress=51.89.167.6

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.

Server

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:

Image

The app connects to hab.link 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.

Subscribe to RSS Feed Follow me on Twitter!