Picoballoon 2020

STM32 RF GPS low-power probe solar

As in 2019 the Brno Observatory and Planetarium organised a Picoballoon Channelnge in 2020. It's a competition of high altitude ballon probes, the one that sends it's altitude as the last one wins. Each probe must weight under 20 g and share at leas an approximate altitude in the telemetry messages. These probes will be launched on helium filled balloons to altitudes around 5 to 10 kilometers, that means the probe must whistand temperatures below -40 degrees Celsius an rough weather and at the same time, it must be able to send the telemetry data from any point in space. The previous probe I made for the 2019 competition wasn't very successful, a communication with the TTN didn't work as expected as I was only able to receive the join requests, but no payload. Due to the very limited amount of time I had when I started the project, I didn't have a change to properly test the power supply design, it worked, but it's efficiency was miles from perfect. So, a new year is here, let's do it better! Oh, crap, only two months to launch again...


Let's start with a way the probe could be powered. We are limited by 20 g total take-of weight severly, therefore only battery and solar power comes into comparsion. Batteries are heavy, will die eventually, but can provide power all the time until fully discharged. Last time all the probes were killed during night in storm, the last probe alive was running from batteries, therefore could send the telemetry during night and win the competition.

Second option are solar cells, they won't run out of charge, but the probe operation is possible only during the day. Aditionally small solar cells won't generate much power therefore some kind of energy storage (e.g. supercap) is needed. Solar cells are also fragile and can be easily damaged during a transportation or by strong wind gusts (not mentioning hitting a tree during the launch which happened to one team last year). Let's go with the solar way, optionally the solar cells could be replaced by a battery without changing the board.

The solar cells are charging a supercap that can power the probe for dozen of seconds. Last year I was simply charging the supercap through a low drop diode. It worked well, but it can definitely be done better. There are many energy harvesting ICs (LTC3105 for example), but they tend to be expensive, complicated to setup properly and based on few internet discussions also operate poorly on very low level light conditions as these circuits are usually designed for higher power usages than for the 20 g balloon probe. The low light conditions are the main reason why I would use the harvesting IC! Ok, this is not the way. So I kept the diode to charge the supercap directly. When the output voltage of the solar cells is high enough (around 0,6 V) the boost regulator starts to operate boosting it to nearly 3 V. This way I can charge the supercap up to a maximum possible voltage without building a huge solar cell array that would have a high enough voltage. A disadvantage visible on first sigh is missing MPPT feature (maximum power point tracking). To reduce a maximum charging current the output from the boost regulator is fed to supercap through a resistor (with diode to prevent backflow current).

So, we have our supercap fully charged, what next? It can't be directly connected to the circuit it's supposed to power, we need to charge it first before powering a rest of the probe. Last year I used a simple zener diode driven circuit to wait until the supercap voltage reached required voltage before connecting it to the rest of the circuit. Unfortunately, the zener solution was a bit buggy, a small current flowing through the diode before it reached the tripping point was high enough to open the transistors in a loopback configuration (works as a latch to keep the circuit powered until the MCU decides to power off). This year I used a supervisory circuit, basically it's designed to keep a MCU in reset state until the voltage reaches selected value (or generate reset when the voltage falls below the level). The latch used is same as before, low level on power supervisor RST output opens the Q2 which in turn opens the Q1, the circuit is latched. Low level on LatchReset resets the latch, if RST is high again, it will turn off.

Finally voltage on the supercap is boosted to 3,3 V by a boost regulator (controlled by PWR_ENABLE signal). The supercap charging circuit is placed on edge part of the PCB and can be therefore cut away if not needed (powered by battery). In case of battery power, the battery voltage is constantly boosted to 3,3 V and the probe is powered all the time.

Or just run out of time for debugging, snap the solar part away and solder random battery directly to the second boost regulator. I just didn't have time to select the best battery ever, I just rushed into the store with pocket weight, selected lightest battery (GP2 3V lithium battery - 9,5g ) they had and soldered it to the board.


The probe must be able to send telemetry on any place on the Earth. This limits us to very narrow selection of options as we need many receiving stations all over the world or a very antenna (to use long waves bouncing off the ionosphere). I was thinking about a GSM, the probe is flying around 10 km above the ground, so the signal shouldn't have a problem to reach the BTS. Unfortunately the GSM is quite power hungry and required a bidirectional communication. An APRS would be great, but it requires a HAM radio license, so it's still no-go this year. Therefore I've decided to use LoRa together with TTN as the last year. However, I decided to rewrite the LoRaWan stack myself, as the LMIC I was using before is far from perfect. The stack I wrote currently supports only ABP mode with uplink only (no downlink).

This year I switched from OTAA (over the air update) to ABP (activation by personalization) as OTAA required bidirectional communication which turned to be a problem last year. The TTN received the join request from the probe, but that was all, it seems the probe failed to receive a response from network and therefore did never send any useful data back to ground. APB on the other side doesn't need any specific procedure to join the network, all required informations are preprogrammed to the device before launching which enables usage of unconfirmed uplink packets. With APB the transmission is shorter and requires less energy (only uplink is sent, no need to wait for downlink, no additional data are transmitted).

On the electronic side, there's nothing special, I'm using a simple 1/4 wave wire antenna with no counterpoise except the PCB ground. It should be good enough to send data to the network. The radio module used is a well known RFM95 with up to 20 dBm power output. As I don't have an equpment needed to measure the SWR of the antenna, the maximum transmitter power is reduced to up to 17dBm. The module is designed for 868 MHz band (used in Europe), for usage outside Europe, it's necessary to switch to different frequencies (e.g. 902-928 MHz in USA) according to frequency plan. The RFM95 allows user to set operation frequency in a wide range, but the output filters together with the antenna tuned to different frequency will reduce the ERP. As I'm running out of time, the band selection based on GPS is implemented, but the filters on the RFM95 and antenna design are not modified, hopefully enough power will get through.


The probe is equipped with MS5607 air pressure sensor and Si7020 relative humidity sensor for measuring physical properties of the surrounding air. Aditionally to measure a precise position of the probe (very rough position can be estimated from the TTN gateways that received the probe transmission) the probe also contains a low cost SIM28ML GPS only (no GLONASS, etc) receiver. To keep the power consumption as low as possible the GPS is connected to power supply through P-MOSFET and can be cut from power any time. To significantly speedup the GPS fix after power on, the GPS module provides a separate backup power input, if connected it allows GPS module to keep the RAM content. Therefore we can do warm start instead of cold boot and find a position within few seconds instead of 30+ seconds as in cold start. Unfortunately the backup voltage must remain above 2 V to retain the RAM content, so the supercap shouldn't go below 2 V which could be a problem. This mode is much more useful in battery powered design as the battery voltage can be boosted up to 3,3 V all the time.

It's important to keep the GPS running until a fix for the first time. I just set timeout to 30 seconds and launched the probe, never got the gps fix since then. That happens when you first power up the probe from it's battery like 1 hour before the competition start and don't have time for enough testing.

MCU, firmware,...

The probe is powered by STM32F030, it would be better to use some low-power MCU, but I've started working on the design pretty late, so I went with a MCU familly I know well and I already wrote a lot of libraries for. The main loop is pretty straightforward:

  • Power up, initialize peripherals, etc.
  • Power on GPS, measure system voltages, pressure, humidity
  • Wait for GPS fix or timeout
  • Power off the GPS
  • Send data over LoRaWan
  • Reset latch (dies if supercap voltage is too low, or continues to work if above 2,7 V, doesn't matter if running from battery)
  • Sleep for 30 minutes
  • Repeat (GPS is turned on every 4 cycles)

The quiescent current is given by sum of quiescent currents of the boost regulator, MCU in sleep, sensors (for GPS only backup current is important) and is in range of dozens of uA. The working current as peaking around 20-25 mA during GPS position acquisition.


The probe board was designed as two side PCB with component mounted from both sides to reduce a size of the board. The circuit needed for solar power is separated from a rest of the board by thin bride, so it can be snapped off if not needed in final probe.


The TTN serves as the first endpoint for received data. I'm using storage integration module to store the received messages temporarily (storage integration keeps data for 7 days). The primary backed is running on my server and it's using TTN http integration. The TTN sends a post request to my server everytime a new packet arrives. The request contains a JSON with various metadata about the packet received and the packet content of course. The data are parsed from binary format (generated by the probe) into reasonable values on TTN side using the javascript payload decoder feature of the TTN. This way the storage backend and the JSON data sent over HTTP contain already parsed data that can be used directly.

The endpoint running on my side is written in PHP (it took me a while to remember how to use it, languages I'm not using for a while get rusty pretty fast! Should have used python I guess :D). One PHP script processes the POST request, verifies Auth header to avoid other people spoofing the data and stores the data in a sqlite database. Second script keeps care of generating a html user frontend. Basically it fills a table with all received data and shows it to user. A bit of javascript glue is used to show a map with probe path to user (using Mapy.cz api ).

Reality, it never works as expected

Well, the PCBs arrived four days before the launch itself (delayed due to china new year and coronavirus panic). I've assembled the board, loaded the firmware and... Nothing. After three days of debugging, everything was working as expected, almost. The RFM95 is supposed to consume below 1 uA in sleep mode, it was eating almost 2 mA, I guess it could be caused by floating pins of the module (I shutdown the MCU after packet is sent, all ports go to highZ mode). Never mind, I've just cut the 3V3 rail to RFM95 and soldered it to the GPS power transistor. Now the MCU rebooted immediately after every boot. Nice, soldered some caps closely to the GPS power transistor, it works now.

As I'm running from the battery, I've updated the contol loop to:

  • Boot, initialize peripherals
  • Measure pressure, voltages
  • Wait for gps fix or timeout
  • Send data over LoRa
  • Setup RTC alarm for 30 minutes and shutdown

The first LoRa packet was sent around 22:30 the day before launch, the probe was connected to a battery for the first time at 9 am and it was launched at 11 am same day. Immediately after launch I've noticed the GPS is not getting fix - 30 seconds timeout is not enough to receive almanach and other GPS crap during cold start. Crap. So I don't have GPS fix and the GPS is draining the battery by 20 mA every 30 minutes for 30 seconds for nothing. Thanks gods I've implemented the timeout, or not? Maybe it would get fix after like 10 minutes for the first time and then only few seconds would be needed. Never mind, next time...

Anyway, aside of this issues, the probe worked pretty well, last signal received was from the edge od the Black sea from somewhere around 7 km above ground at 18:39 UTC. Then it went away from Europe's network of TTN gateways and without GPS working, it won't retune to different frequencies. And I don't think the battery will survive a full circle around the Earth.


  • Design files on github
  • Tracking (might be removed after the competition)

Previous Post Next Post