The goal of this project is to reverse engineer the Meteomodem M20 radiosonde and build custom firmware for its usage in ham radio baloons based on the Horus Binary V2 radio protocol.
The code is writen in C using STM32CubeMX and Low Layer (LL) libraries and compiled using arm-none-eabi toolchain. Now it fits into the original STM32L051R6T6 chip.
In this stage the code works to the point where it gets GPS and sensors data, then sends it using Horus Binary V2 protocol over radio. However this code is currently in the experimental/testing phase and there are some problems with it. Keeping that in mind, making flights with it is possible. Thanks to SP9AOB and SP6MPL for conducting test flights. If you are making a flight with this firmware let me know, it really helps with finding bugs and testing the code.
- GPS (NMEA): ✔️
- GPS (XM1110) ✔️
- Radio (Horus): ✔️
- LPS22 barometer + temp sensor: ✔️
- Uart: ✔️
- Outside temperature sensor: ✔️
- humidity sensor: ❌
The currently implemented features are:
- GPS time, position, altitude, speed, ascent rate and number of satellites (NMEA and XM1110)
- Sending data over radio using Horus Binary V2 protocol
- Getting battery voltage
- Getting temperature and pressure
- Getting external temperature
- Watchdog timer
- making use of STM32 energy saving states
- Implementing XM1110 GPS speed data
- implementing humidity sensors
- implementing APRS
- Problems with ascent rate calculation
- Wrong external temperature sensors readings
- High frequency instability (no TCXO)
- Transmitted frequency "jumps"
Due to hardware limitations (system clock PLL setting options) it is not possible to generate a clock signal for the radio module whose frequency is divisible by 9. That results in no possibility of having a 270Hz tone spacing standardized by the RS41ng project. The tone spacing is set to 244Hz acquired by an 8MHz clock signal. The limitation is directly connected with the method of implementing FSK and there seems to be no way to overcome it without hardware intervention. The effect is that receiving stations must set a different from standard tone spacing or the SNR will be very low, for comparison:
- Paweł SQ2IPS
- Jędrzej SQ2DK
See LICENSE
Great pcb reverse enginering work was made by joyel24, PDF link (although there are some errors in it)
- NMEA parsed based on https://github.com/sztvka/stm32-nmea-gps-hal
- LPS22 implementation based on https://github.com/KitSprout/KSDK/tree/master/firmwareSTM32/KSSTM_Module_LPS22HB/Program/modules
- Radio modules implementation based on https://github.com/adamgreig/wombat
- Horus Binary encoder based on https://github.com/whallmann/RS41HUP_V2/blob/master/horus_l2.c
There are 2 variants of GPS modules, both of them are supported.
In newer M20 sondes u-blox MAX-M10M that uses NMEA protocol is used.
In older M20 sondes XM1110 GPS module is used. It transmits data over UART but with custom firmware that transmits only binary protocol data.
Data format:
LPS22HB sensor is used with SPI interface.
A NTC is used for external temperature measuring with addable resistors, the schematic looks like this:
TODO
Hardware requirements:
- A working M20 radiosonde :)
- A ST-Link v2 programmer USB dongle that looks like this:
- 5 male to female goldpin jumper wires
- A computer with Linux or Windows
If you have a sonde with new GPS module, there is a additional parallel 62 Ohm resistor added at the output of the voltage converter, all it does it drawing ~53mA from the line and converting it to heat. I have no idea why it was added, removing it does not make the power supply unstable or anything like that, maybe it was added for draining the battery quicker. You can safely remove this resistor to save some energy from the battery. This is the resistor:
Thermal camera image:
(Image from SP9AOB)
First you need to obtain the code, you can do it with git
:
git clone https://github.com/sq2ips/m20-custom-firmware.git
From github website "code" button, or directly from here, and then unzip the file.
Before building the firmware you fist need to configure parameters located in the config.h
file.
TODO description
Before flashing the firmware you need to build it first, there are a few ways you can do it depending on the platform:
To build directly on linux you need the arm-none-eabi toolchain, you can install it from your package manager depending on the linux distro. For example, on Debian it will look like this:
sudo apt install gcc-arm-none-eabi
WARNING: in different distros version of the toolchain can varry and result in a too big result file
A way to avoids this problem is downloading the toolchain from here. After downloading you need to extract it:
tar -xvf arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz
and install the binaries into your system:
sudo cp arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi/bin/* /usr/local/bin/
You will also need make
to build.
sudo apt install make
After installing everything you can go into the directory where you do downloaded the code, then:
cd m20
And now you can make
the firmware:
make
After succesful building you should see a memoy usage table like this:
First you need to get Docker, you can install it from your package manager depending on the linux distro. For example, on Debian it will look like this:
sudo apt install docker
Then you need to add your user into the docker group like so:
sudo groupadd docker && sudo usermod -aG docker $USER
Now restart:
sudo reboot
Now you need to start the docker daemon:
sudo systemctl start docker
But you will need to do it again after reboot of your computer, you can set it to autostart:
sudo systemctl enable docker
Now you should cd into the directory of the downloaded code, then:
cd m20
And now build the Docker image:
docker build -t m20 .
It will need some time to download an install the packages, after it finishes run:
docker run --rm -v $(pwd):/opt/m20 m20:latest
It will build the code and after finishing you should see a memory usage table, the compiled binaries should be in the build/
directory.
If you did the steps next time building you will need to only run the last command.
First download MSYS2, then install it, after finishing the setup you should now see a terminal.
Now install make
:
pacman -Sy make
Confirm the instalation and wait for the packages to download and install. TODO
First download Docker Desktop and install it, then run the Docker engine.
Open Windows PowerShell and go into the directory of the project then m20/
, next run:
docker build -t m20 .
It will need some time to download an install the packages, after it finishes run:
docker run --rm -v .:/opt/m20 m20:latest
It will build the code and after finishing you should see a memory usage table, the compiled binaries should be in the build/
directory.
Before flashing you first need to connect the sonde to your computer through the ST-LINK programmer. You can do it using 5 goldpin cables. This is the sonde pinout:
Follow it and the pinout of the programmer printed on the case. After connecting it and the programmer to your USB port you are now ready to flash the firmware. You don't need to solder the wires, instead you can just put them into the connector, it should make enough contact for the firmware to flash.
For flashing you will need the OpenOCD you can install it from your package manager depending on the linux distro. For example, on Debian it will look like this:
sudo apt install openocd
After installing it and ensuring that you are in the m20
directory. Then check if ST-Link is connected and then you can remove the write protection (only before the first flash):
make protect
or if you don't have make
or want to run it directly:
openocd -s ./openocd/ -f ./openocd/openocd_m20.cfg -c "init; halt; flash protect 0 0 7 reset; exit"
After it finishes you can flash the built firmware:
make flash
or directly
openocd -s ./openocd/ -f ./openocd/openocd_m20.cfg -c "program build/m20.elf verify reset exit"
After it finishes your sonde should now work with the new firmware.
First download OpenOCD select the file with ending win32-x64.zip
, then extract it.
Go to the path of the project then to m20/
. Ensure that ST-Link is connected and then remove the write protection (only before the first flash):
<path\to\openocd>\bin\openocd.exe -s openocd -f openocd\openocd_m20.cfg -c "init; halt; flash protect 0 0 7 reset; exit"
replace <path\to\openocd>
with path of the extracted program.
After it finishes you can flash the built firmware:
<path\to\openocd>\bin\openocd.exe -s openocd -f openocd\openocd_m20.cfg -c "program build/m20.elf verify reset exit"
After it finishes your sonde should now work with the new firmware.
Fisrt download the utility, extract, install and run it. Connect to the ST-Link and open the binary compiled file with .bin extension. Then go to Target -> Flash & Verify, check that the adress is set to 0x80000000 and the flash.