Telemetry

Last modified by Even Kruse Hvidsten on 2026/06/12 12:29

Warning

work needing to be still done is referenced in the respective section; once a task has been dealt with delete it; once all task have been done delete this warning

Warning

RTFM, if you change anything UPDATE THE FUCKING MANUAL

Table of contents

Description

Specify STM32 board used

The telemetry software section of the project comprised such tasks

  • creating software for relaying CANBUS messages through MQTT via 4G using a Raspberry pi
  • creating software for reading CANBUS messages from main CANBUS loop using STM32 chip and sending via serial to raspberry
  • lowering boot time of Raspberry pi
  • writing script to be launched at boot to connect to the internet via modem
  • making the SD used by the pi read-only; this is needed as micro-sd cards are failure prone, especially on Rpi hardware

Remaining work

here is listed what remains to be done by order of importance

  1. stm32 board code for canbus reading 
  2. 4g modem script
  3. try lowering boot time by profiling
  4. make cmake script to compile everything at once, until now ran gcc command with manual linking
    1. if changes to the location of the json config file are made act accordingly and refer to the section about message relay via rpi
    2. update section "how to compile" if changed
  5. maybe make build system to create directly the whole image with the necessary software; this way is storage device fails it is easier to rebuild the whole system

Architecture description

Canbus message reader STM32

Most of it is still not implemented, but shouldn't take long to implement. 

A simple loop reading the canbus port and relaying it to the serial interface will be more than enough; depending on board used package filtering could be done either on the STM board or raspberry pi

Message Relay via raspberry pi

This is the meaty boy of the project; the file to refer to is mqtt_usb_sender.c.

Most of the C code created is commented using doxygen, so

  • if modification are made, comment using the same system (i'm seeing you not writing comments 🙂)
  • for specific function description look at the code; there will be a comment explaining it

Typical flow of the app

  1. it loads the config found at MQTTUsbSenderConfig.json; this json file will have to be in the same folder level as the main C compiled object. 
  2. will create the connect with the MQTT broker
  3. will either enter normal or test operating mode
    1. normal mode will run until killed
    2. test mode will force join all active thread and print the number of messages each one of them sent
  4. will launch a thread per serial connection
  5. such thread will
    1. setup the serial port (which in linux is simply a file descriptor) by what specified in MQTTUsbSenderConfig.json
    2. open a reading loop in which will read up to 256 chars, format it into an MQTT message and send it asynchronouslyù

Libraries used (and why)

  • PahoMQTT
    • simple, has C and python implementations 
    • well documented
  • CJson 
    • more complete libraries exist, but here we need to read just a small config file
    • can be linked very simply as it is a single file

JSON config file format

Warning

remember that if you need to change the config file format you also need to change the parser function loadInitialConfig and the wiki description

this is the typical format for the description of serial ports and the broker used by the application 

{
 "ADDRESS": "tcp://192.168.204.107:1883",
 "CLIENTID": "racingpi",
 "TESTTIMEOUT": 20,
 "INPUT": [
 {
     "PORT": "/dev/ttyUSB0",
     "TOPIC": "testTopic",
     "IN_SPEED": 115200,
     "OUT_SPEED": 115200,
     "comment": "hello there,general kenobi"
    }
  ]
}

each single serial port is an element of the list INPUT of this format, comments can be omitted

{
     "PORT": "/dev/ttyUSB0",
     "TOPIC": "programmingSocks",
     "IN_SPEED": 115200,
     "OUT_SPEED": 115200,
     "comment": "eat past go fasta"
}

Test mode

Mostly used for performance evaluation over a short test; the duration of such test is specified in MQTTUsbSenderConfig.json.

If modifications are needed remember to take into consideration pthread_setcanceltype as this will make sure it will wait for a system call to join the thread when a cancellation was asked; this way you should avoid most errors/lost messages. 

Connecting the pi to the internet

Still not implemented; just a bash script to be added to the startup script referenced in the next section. 

reference material can be found here: 

Boot script

While looking around the github page you might find a .sh script called mqtt_boot.sh; this bash script is run by systemD at boot.

It can be modified to include also the commands to connect via 4g in the future. 

If the underling OS is wiped/changed drastically remember to re-setup such script to launched at boot; asking any LLM how to do it should be enough. 

Boot time optimization

For now it is simply an headless (IE no desktop interface software like x11, gnome, Etc..) installation of Raspberry OS; this setup starts in around 15-20s. 

Further optimization can be done by profiling the boot to strip not needed functionality; reference to how here

How to compile the project

for now gcc is used to compile with manual linking

First follow the installation guides for pahoMQTT anc CJson libraries.

Then here the typical command i used until now 

gcc -o mqtt_usb_sender mqtt_usb_sender.c -lpaho-mqtt3c -lcjson

FAQ

the setup is the one of the original creator, how do i access the pi?

until now work was done via ssh (credential are user: racingpi , password: 1234) using my personal wi.fi hotspot; the simpler way is to use the physical Lan port of the py, then if needed change the wifi config to the new user. 

I see some errors in the log from the a serial interface, what is wrong?

It is mostly a matter of flags used when reading the serial port, refer to the documentation of the attached serial device.

Also remember that most Linux distros could have some serial issues because of braille devices driver (IE BRLTTY); disabling them could help. 

I would like to test the software but i don't have a serial device with me

you're in luck; you can use serialSim.py to simulate a serial device; you just need to open on Linux two fake serial port, put one of them in the sim and the other in the config, then launch the python script 

I don't have linux

It's the year of desktop linux; jokes aside, you can compile on the pi, use wsl or just adapt when needed with some wizardry. 

Local testing

Setup

Connecting to the RPi

Until the PCIe to USB adapter for the modem arrives, use one of the Align computers with LAN port and set the ethernet port from client to a router

nmcli con mod "[name_of_connection]" ipv4.method shared

To find the name of the ethernet connection, run 

nmcli con show

Check that there is a connection between the computer and RPi over ethernet 

nmcli dev status

Connect to the RPi over ssh, run, and use password 1234

ssh racingpi@[ip_address]

To find the IP of the RPi, check the ARP cache with 

ip neigh show

If its not cached, run

cd /var/lib/NetworkManager
cat dnsmasq-[dev_name].leases // dev_name = DEVICE (nmcli con show)

Broker

Currently testing with a local broker running on Align PC (AR-D02), to use the one running on Align server, update the address in the config file on the RPi. To start, stop or check the status of the broker on AR-D02, run 

docker start emqx
docker stop emqx
docker ps

Simulating serial-device

To test without telemetry PCB, simulating the serial-device connection, use the networking tool socat to establish a virtual connection through a pseudo-terminal. Run this on the computer sending the fake data. If using the serialSim.py script, the link name can be found in the file, look for VN200_PORT.

socat pty,raw,echo=0,link=[some_name] TCP-LISTEN:7000,reuseaddr,fork

Connect the RPi to the other end with (run this on the RPi)

socat pty,raw,echo=0,link=[some_name] TCP:[some_ip]:7000

Set the link name to the port name in the config file, and the ip is the default gateway address. The default gateway address is the address assigned to the computer's ethernet interface when using the port as a router. Run ip addr show and look for the ipv4 of the ethernet port device name.

Running

After the connection is established, run the program on RPi

./mqtt_usb_sender

Then run the python script to send fake data. To see the messages the broker is distributing, subscribe to the same topic (see the config file for name), run

mosquitto_sub -h localhost -p 1883 -t "[name]"