Your submission was sent successfully! Close

You have successfully unsubscribed! Close

Thank you for signing up for our newsletter!
In these regular emails you will find the latest updates about Ubuntu and upcoming events where you can meet our team.Close

Getting started with micro-ROS on the Raspberry Pi Pico

Please note that this blog post has out technical information that may no longer be correct. For latest updated documentation about robotics in Canonical please visit

Running micro-ROS on Raspberry Pi Pico

In this post we will see how the Raspberry Pi Pico can natively speak to a ROS2 graph using micro-ROS. We will set up a project in VSCode, compile and upload it to the microcontroller. We thus assume that you are somewhat familiar with ROS2 development and VSCode.

What is this all about?

Running ROS2 on microcontrollers.

The Raspberry Pi Pico

The Raspberry Pi Pico, announced in late January 2021, is the newest release of the Raspberry Pi Foundation which received a ton of attention (a quick search on Google and/or Youtube will convince you). And that’s for a good reason. Compared to its well known predecessors, this new board differs in two major ways: it is an in-house designed open-hardware microcontroller! Yes, the chip itself is designed by the Pi’s engineers and it is fully Open-hardware. As usual with the Pi foundation, it is incredibly affordable at just 4$.

The details concerning the board itself, the differences between microprocessor and microcontroller, the 101 getting started or what can the Pi Pico do; all of that is beyond the scope of this post. But I strongly encourage you having a look for yourself, whether you are familiar with microcontrollers or not.


In the ROS (1) realm, microcontrollers have always been sort of second class citizens. They can’t interact directly with the ROS graph and developers have to rely on libraries such as rosserial. But ROS2 is a whole new world and things are changing.

> micro-ROS puts ROS 2 onto microcontrollers, making them first class participants of the ROS 2 environment.

The micro-ROS project is an effort led by big industrial  names such as Bosch, eProsima, Fiware Foundation, notably through the OFERA H2020 project, and a myriad of partners and collaborators including e.g. Amazon and Canonical.

So what is it? It is essentially a thin wrapper (see its design document) on top of ‘DDS for eXtremely Resource Constrained Environments’ (DDS-XRCE), running on a real-time OS, and allowing microcontrollers to ‘speak’ to a ROS2 graph (the usual talker/listener) using an optimized subset of the DDS protocol. A mouthful. It relies on a ‘bridged’ communication architecture with a ‘broker’ named the ‘micro-ROS Agent‘. The agent is in charge of the interfacing between the ROS2 graph and one or several micro-ROS devices.

More details can be found on the micro-ROS website including how it compares/differs from rosserial (see here and here).

Getting started

Alright, so now that we have clarified a couple of terms, let us get started, step by step, with the official micro-ROS on Raspberry Pi Pico example available on github. Note that for this tutorial I am running Ubuntu 20.04 with the VSCode snap.

If you are not running Ubuntu 20.04 yet, you could consider using an LXD container. You can refer to our previous post ‘ROS Development with LXC’ to help you get started setting up the container.

Installing dependencies

Let’s simply start by installing the necessary dependencies,

sudo apt install build-essential cmake gcc-arm-none-eabi libnewlib-arm-none-eabi doxygen git python3

Fetching the sources

We will now create a workspace and fetch all the sources,

mkdir -p ~/micro_ros_ws/src
cd ~/micro_ros_ws/src
git clone --recurse-submodules
git clone

The first repository is the Pi Pico SDK provided by the Pi foundation. The second contains a precompiled micro-ROS stack together with a hello-world-like example.

Setting up VSCode

Let us now open the example in VSCode and set it up. To follow along, you will need two VSCode extensions that are rather common for C++ development. These extensions are the C++ extension and CMake tools for VSCode. After installing them, we will create a configuration file for CMake tools and set a variable so that our project knows where to find the Pi Pico SDK. To do so, simply type,

cd ~/micro_ros_ws/src/micro_ros_raspberrypi_pico_sdk
mkdir .vscode
touch .vscode/settings.json

Open the newly created file with your favorite editor,

vi .vscode/settings.json

and add the following,

    "cmake.configureEnvironment": {
       "PICO_SDK_PATH": "/home/$USER/micro_ros_ws/src/pico-sdk",

This variable is an environment variable that is only passed to CMake at configuration time. See the CMake-Tools documentation for more info.

Let us now open the project,

code .

Before running the CMake configuration and building it, we must select the appropriate ‘kit’ (maybe VSCode has already asked you to do so). Open the palette (ctrl+shift+p) and search for CMake: Scan for Kits and then CMake: Select a Kit and make sure to select the compiler we’ve installed above, that is GCC for arm-non-eabi.

We’re all set, let us build the example! Open the palette again and hit CMake: Build.

Running the example

Wait a minute. What does it do?

Right, let’s break down very briefly what the example does. It sets up a node called pico_node, then a publisher publishing a std_msgs/msg/int32.h message on the topic pico_publisher, a recurring timer and an executor to orchestrate everything. Every 0.1 second, the executor spins. But only every second, the timer will have the publisher publish a message and increase the message data by 1. Simple. So let’s try it out.

Uploading to the Pi Pico

If everything went fine during compilation, you should see a new build folder in your project view. In this folder, you will find the file that we should now upload to the Pi Pico, it is named here pico_micro_ros_example.uf2.

To upload it, simply connect the board with a USB cable while pressing the tiny white button labelled BOOTSEL. Doing so, the Pi Pico will mount similarly to a flash drive allowing us to very easily copy/paste the .uf2 file. Head to a terminal and type,

cp build/pico_micro_ros_example.uf2 /media/$USER/RPI-RP2

Once the file is copied, the board will automatically reboot and start executing the example.


Installing the micro-ros-agent

We have seen in the introduction that micro-ROS has a bridged communication architecture. We thus have to build that bridge. Well, fortunately the development team has built it already and distributes it both as a Snap or a Docker image. Here we’ll make use of the former.

If you are using Ubuntu 16.04 or later, snap is already pre-installed and ready to go. If you are running another OS, you can either install snap or make use of the Docker image. To install the micro-ros-agent snap, type,

sudo snap install micro-ros-agent

After installing it, and because we are using a serial connection, we need to configure a couple of things. First we need to enable the hotplug feature,

sudo snap set core experimental.hotplug=true

and restart the snap demon so that it takes effect,

sudo systemctl restart snapd

After making sure the Pi Pico is plugged, execute,

$ snap interface serial-port
name:    serial-port
summary: allows accessing a specific serial port
  - micro-ros-agent
  - snapd:pico (allows accessing a specific serial port)

What we see here is that the micro-ros-agent snap has a serial plug while a pico slot magically appeared. As per the semantic, we probably should connect them together. To do so run,

snap connect micro-ros-agent:serial-port snapd:pico

We are now all set to finally run our example.

Actually running the example

With the Pi Pico plugged through USB, we will start the micro-ros-agent as follows,

micro-ros-agent serial --dev /dev/ttyACM0 baudrate=115200

Wait a couple seconds for the Pi Pico’s LED to light up indicating that the main loop is running. In case it does not light up after a few long seconds (count up to 10 mississippi), you may want to unplug/replug the board in order to reboot it. The initialization procedure of the example lacks a few error checking… Hey, could improving that, be your first project?

So now the LED should shine a bright green. That’s cool. Do you know what’s cooler? Running on your host machine,

$ source /opt/ros/dashing/setup.bash
$ ros2 topic echo /pico_publisher
data: 41
data: 42

Awesome! And hitting a

$ ros2 node list

proves that the micro-ROS node running on the Raspberry Pi Pico is visible to ROS2 on the host machine. Yatta! #VictoryDance

What’s next?

For a long time it wasn’t convenient to mix microcontrollers and ROS. But this is about to seriously change as we’ve just seen. No doubt that both micro-ROS and the Raspberry Pi Pico will bolster great robotics applications (and more!).

In this tutorial we’ve reached a great starting point with a ROS2-based project ready to spin on the suppa-cool suppa-affordable Raspberry Pi Pico.

Of course this wouldn’t have been possible without the micro-ROS dev team and Cyberbotics engineer Darko Lukić (@lukicdarkoo) who put together the initial example we’ve just used. As often, there are super smart people out there making complicated stuff very accessible, shout out to them.

I’m personally going to keep playing with micro-ROS on Pi Pico, first because it is fun and second because I have a couple of ideas up my sleeves. Make sure to keep an eye on this blog to hear all about them.

What about you? Do you have some cool projects already in mind?

This post first appeared at

rapsberry pi logo

Ubuntu Desktop for Raspberry Pi

Watch the live event of the 20.10 launch the and find out all the news about the new Ubuntu Desktop image for Raspberry Pi.

Discover more ›

Newsletter signup

Get the latest Ubuntu news and updates in your inbox.

By submitting this form, I confirm that I have read and agree to Canonical's Privacy Policy.

Are you building a robot on top of Ubuntu and looking for a partner? Talk to us!

Contact Us

Related posts

Optimise your ROS snap – Part 2

Welcome to Part 2 of the “optimise your ROS snap” blog series. Make sure to check Part 1 before reading this blog post. This second part is going to present...

Optimise your ROS snap – Part 1

Do you want to optimise the performance of your ROS snap? We reduced the size of the installed Gazebo snap by 95%! This is how you can do it for your snap....

ROS orchestration with snaps

Application orchestration is the process of integrating applications together to automate and synchronise processes. In robotics, this is essential,...