ROS2 on STM32 serial to SBC

Hi all,

I’m building a small ROS 2 robot with an STM32 microcontroller and an SBC running a Zenoh router (rmw_zenoh). I want to keep the MCU side Zenoh-native with Zephyr RTOS, and I’m trying to figure out the best communication stack between the STM32 and the rest of the graph.

I’ve been looking at three options:

  1. micro-ROS (classic) — well documented, but I’m not sure whether I’d still need zenoh-bridge-dds on the SBC side given I’m already running rmw_zenoh there
  2. Zenoh-Pico with rmw_zenoh_pico (eSOL) — conceptually a perfect fit, but the repo seems to only target Linux/RPi so far, and I’m not sure how much work porting to STM32 + Zephyr would be
  3. Pico-ROS — appeals to me architecturally (native Zenoh, no micro-ROS overhead), but documentation is very sparse and I couldn’t find real-world STM32 examples

I’m not necessarily looking for a solution that works out of the box — I’m happy to do integration work. What I’m really after is whether anyone has actually tried any of these on STM32 + Zephyr, what pain points they hit, and whether there’s a better path I’m missing.

Any experience or pointers would be greatly appreciated!

To narrow things down…

What physical interface ( UART /Serial, Ethernet, or CAN ) are you planning to use between the STM32 and the SBC, and also which STM32 series chip are you targeting, and what SBC are you using ?

When we had the same issue, I decided on neither because I don’t want us to be locked in for a specific middleware just because of the microcontroller.
Also, the existing solutions seemed quite complicated for something as simple as data exchange.

Instead, I developed this little helper to exchange arbitrary data structs using C++ reflection

We use this to pass information between the microcontroller and a separate ROS 2 node on the PC, communicating over USB serial.
The node handles ROS 2 communication and bridges the data exchange between ROS and the microcontroller.

Hi I am just in the process to switch the communication between SPC (Raspberry Pi 4) and my STM32 (Core2 from Husarion) from Micro-ROS to serial communication with Crosstalk (thanks @StefanFabian ). Currently the ros2_control interface works with a small MCU simulator. The next step will be to implement crosstalk in my firmware.

Some pitfalls I had were installing libserial (in the end build from source works) and the integration of libserial in the CMakefile.txt. The simulation works with socat.

If you want to have a look my GitLab repos are:

1 Like

What issues did you have with libserial?
We use it with rosdep key without installing from source.
For example, in our open-source ESP32-based remote E-Stop:

I first installed libserial with apt get install and then while colcon build I got an error message about CMake_config (don’t remember the correct text). This message disappeared after buildind libserial from source…

The bigger problem was the configuration of libserial in CMakeLists.txt because I could not find an example of libserial usage in ros2 packages. Because of this a link to your esp32_estop_ros package in the crosstalk library would be very helpful.

My current problem is that my firmware uses mbed 6 which seems to be not compatible with refl-cpp because of

include/crosstalk.hpp:4593:27: error: reference to 'debug' is ambiguous

errors. Maybe I switch to the Arduino framework (mbed has EOL in July 2026).

1 Like

For a robot I’m currently working on, I went back and forth about this quite a bit before deciding to give the micro-ROS + micro-XRCE-DDS serial protocol + micro-xrce-DDS-agent stack a try. This is on a (Nucleo) STM32L432KC, and I even decided to forgo a proper RTOS for now, and am just rolling baremetal with platformio.

I ultimately landed on micro-ROS for the following reasons:

  1. I was trying to avoid creating my own communication solution.
    1. ROS already has an interface description language for defining interfaces and generating code for them, so I was keen on letting micro-ROS handle this for me. I was originally considering protobufs/nanoPb, but I wanted to give the existing micro-ROS solution a chance.
    2. Further, a communication protocol is more than just message definitions. Depending on how crazy you want to get, you need rules to decide what to do when you send/receive messages, what to do when a checksum fails, do we need to use a CRC, or will a simple parity bit work? For my project, I wasn’t looking to develop an entire protocol, and this is exactly the kind of thing that the micro-XRCE-dds serial protocol was designed for (as far as I can gather).
  2. micro-ROS is more than just communication: Outside of the communication, micro-ROS lets us easily set up timers, subscribers, publishers, callbacks, Nodes, etc. For most projects, I think you can easily get away with not needing any of that stuff, but it made development much easier for me.
  3. Back to communication, though: micro-ROS (like ROS) is, from what I can gather, supposed to be rmw-agnostic, for the most part. I.e., it (in theory) shouldn’t matter if I want to use rmw_embedded_rtps or rmw_zenoh_pico (or maybe even SafeDDS). As long as I have some kind of networking/lwip stack available, both should work. AND, all your publisher/subscriber code can remain unchanged.

However, I don’t love my setup currently. I still have a number of grievances:

  1. micro-ROS is a leaky-abstraction. I spent way more time than I wanted to learning more about how it is set up in order to get certain features working.
  2. Ultimately, I want a setup using micro-ROS + rmw_zenoh_pico + zephr, on an MCU with some kind of ethernet interface, but I haven’t had time to investigate / make that happen yet.

I would be curious to see how difficult it would be to just get GitHub - esol-community/rmw_zenoh_pico: Zenoh-pico implementation for micro-ROS · GitHub working with a baremetal or FreeRTOS setup first. I also seem to remember seeing an example github repo for embedded rtps on an stm32 (maybe it was this page).

I know no-one asked for all that context above, but I wanted to write my chain-of-thought down here, as I am still looking for a solution like you. Maybe someone with more intimate micro-ROS knowledge can comment, as well.

As reference, I have this architecture (uC+pico-ROS <—> SBC+rmw_zenoh ) working with an ESP32: GitHub - xopxe/oruga_ws · GitHub