Skip to content

Reverse engineering and building firmware for the Meteomodem M20 radiosonde for use in ham radio balloons

License

Notifications You must be signed in to change notification settings

sq2ips/m20-custom-firmware

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

m20-custom-firmware

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.

Code

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.

Stage

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.

What works

  • GPS (NMEA): ✔️
  • GPS (XM1110) ✔️
  • Radio (Horus): ✔️
  • LPS22 barometer + temp sensor: ✔️
  • Uart: ✔️
  • Outside temperature sensor: ✔️
  • humidity sensor: ❌

Features list

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

Planned work

  • making use of STM32 energy saving states
  • Implementing XM1110 GPS speed data
  • implementing humidity sensors
  • implementing APRS

Known issues

  • Problems with ascent rate calculation
  • Wrong external temperature sensors readings
  • High frequency instability (no TCXO)
  • Transmitted frequency "jumps"

Horus 4FSK tone spacing

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:

alt text alt text

Authors

  • PaweĹ‚ SQ2IPS
  • JÄ™drzej SQ2DK

License

See LICENSE

Images

alt text alt text alt text

Schematics

Great pcb reverse enginering work was made by joyel24, PDF link (although there are some errors in it)

Used libraries

GPS

There are 2 variants of GPS modules, both of them are supported.

New GPS (NMEA)

In newer M20 sondes u-blox MAX-M10M that uses NMEA protocol is used.

alt text

Old GPS (XM1110)

In older M20 sondes XM1110 GPS module is used. It transmits data over UART but with custom firmware that transmits only binary protocol data.

alt text

Data format:

alt text

Barometer and temp sensor

LPS22HB sensor is used with SPI interface.

External temperature sensor

A NTC is used for external temperature measuring with addable resistors, the schematic looks like this:

alt text

Radio

TODO

Running the firmware

What you will need

Hardware requirements:

  • A working M20 radiosonde :)
  • A ST-Link v2 programmer USB dongle that looks like this:

alt text

  • 5 male to female goldpin jumper wires
  • A computer with Linux or Windows

Recomended hardware modifications

Load resistor

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:

alt text

Thermal camera image:

alt text

(Image from SP9AOB)

Downloading code

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.

Configuration

Before building the firmware you fist need to configure parameters located in the config.h file. TODO description

Building the firmware

Before flashing the firmware you need to build it first, there are a few ways you can do it depending on the platform:

Building directly on Linux

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:

alt text

Building with Docker on Linux

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.

Building with MinGW on Windows

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

Building with Docker on Windows

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.

Flashing the firmware

Connecting

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:

alt text

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.

Flashing on Linux

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.

Flashing on Windows

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.

Flashing on Windows with ST-Link utility

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.

Debuging (TODO)