micro-ROS Devices

Microcontrollers are the backbone of robotics sensor networks and actuator nodes. RosFit supports two paths for MCU connectivity: micro-ROS for full ROS 2 topic compatibility, and native MQTT for lightweight devices that publish directly to the broker.

micro-ROS vs native MQTT

Choosing between micro-ROS and native MQTT depends on whether your MCU needs to participate in the ROS 2 graph or simply push telemetry to the cloud.

Criteriamicro-ROSNative MQTT
ROS 2 topic compatibilityFull — the MCU appears as a native ROS 2 nodeNone — publishes raw JSON/CBOR to MQTT topics
Requires micro-ROS AgentYes — runs on a host (RPi, laptop, or Docker)No — connects directly to the MQTT broker
Transport optionsSerial UART, UDP over Wi-Fi, BLEWi-Fi (TCP/TLS), Ethernet
Message serializationCDR (ROS 2 native)JSON, CBOR, MessagePack, or custom
Firmware complexityHigher — needs RTOS, micro-ROS client libraryLower — standard MQTT client + JSON
Best forSensor nodes that feed into Nav2/MoveIt, mixed ROS 2 graphsStandalone telemetry devices, IoT sensors, simple actuators

Rule of thumb: If the MCU data needs to be consumed by other ROS 2 nodes on the robot (e.g., for SLAM or motion planning), use micro-ROS. If the data only needs to reach the cloud dashboard, native MQTT is simpler and requires no agent.

ESP32 with micro-ROS

The ESP32 family is the most popular target for micro-ROS thanks to its low cost, built-in Wi-Fi/BLE, and active community support.

Supported boards

ChipCPUWi-FiBLEmicro-ROSNative MQTTNotes
ESP32-WROOM-32EDual-core Xtensa LX6 @ 240 MHz802.11 b/g/nBLE 4.2YesYesMost common; recommended starting point
ESP32-S3Dual-core Xtensa LX7 @ 240 MHz802.11 b/g/nBLE 5.0YesYesAI/ML acceleration, USB OTG
ESP32-C3Single-core RISC-V @ 160 MHz802.11 b/g/nBLE 5.0YesYesLow-power, smaller footprint
ESP32-C6Single-core RISC-V @ 160 MHz802.11 b/g/n/ax (Wi-Fi 6)BLE 5.3ExperimentalYesWi-Fi 6 and Thread/Zigbee support

Toolchain setup

Install the micro-ROS build system for ESP-IDF:

# Install ESP-IDF (v5.1+ recommended)
mkdir -p ~/esp && cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git -b v5.1.2
cd esp-idf && ./install.sh esp32
source export.sh

# Create a micro-ROS component
cd ~/my_project
git clone https://github.com/micro-ROS/micro_ros_espidf_component.git components/micro_ros_espidf_component

Transport options

TransportProsConsConfig
Wi-Fi UDPWireless, easy setupHigher latency on congested networksCONFIG_MICRO_ROS_TRANSPORT=udp4
Serial UARTLowest latency, most reliableRequires physical cable to agent hostCONFIG_MICRO_ROS_TRANSPORT=serial
BLELow power, no Wi-Fi infrastructure neededLimited throughput (~20 KB/s)Custom transport layer required

ESP32 native MQTT

For devices that only need to push telemetry to RosFit and receive commands, native MQTT over Wi-Fi is the simplest approach. No micro-ROS Agent is required — the ESP32 connects directly to the EMQX broker.

Arduino example

#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

const char* WIFI_SSID     = "your-wifi";
const char* WIFI_PASS     = "your-password";
const char* MQTT_HOST     = "cloud.rosfit.io";
const int   MQTT_PORT     = 1883;
const char* DEVICE_ID     = "esp32-sensor-01";
const char* MQTT_USER     = "esp32-sensor-01";
const char* MQTT_PASS     = "mqtt_tok_xxxxx";

WiFiClient   net;
PubSubClient mqtt(net);

void publishTelemetry() {
  StaticJsonDocument<256> doc;
  doc["temperature"]   = analogRead(34) * 0.1;
  doc["humidity"]      = analogRead(35) * 0.1;
  doc["soil_moisture"] = analogRead(32) * 0.1;
  doc["timestamp"]     = millis();

  char buf[256];
  serializeJson(doc, buf);

  String topic = String("rosfit/") + DEVICE_ID + "/telemetry";
  mqtt.publish(topic.c_str(), buf);
}

void onCommand(char* topic, byte* payload, unsigned int length) {
  StaticJsonDocument<256> doc;
  deserializeJson(doc, payload, length);

  const char* cmd = doc["command"];
  if (strcmp(cmd, "set_valve") == 0) {
    int pin   = doc["data"]["pin"];
    bool open = doc["data"]["open"];
    digitalWrite(pin, open ? HIGH : LOW);
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) delay(500);

  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  mqtt.setCallback(onCommand);

  while (!mqtt.connected()) {
    mqtt.connect(DEVICE_ID, MQTT_USER, MQTT_PASS);
    delay(1000);
  }

  String cmdTopic = String("rosfit/") + DEVICE_ID + "/command";
  mqtt.subscribe(cmdTopic.c_str());
}

void loop() {
  mqtt.loop();
  publishTelemetry();
  delay(5000);
}

ESP-IDF with X.509 mTLS

For production deployments, use ESP-IDF with TLS client certificates instead of username/password authentication:

esp_mqtt_client_config_t mqtt_cfg = {
    .broker.address.uri       = "mqtts://cloud.rosfit.io:8883",
    .broker.verification.certificate = server_ca_pem,
    .credentials = {
        .authentication = {
            .certificate = client_cert_pem,
            .key         = client_key_pem,
        },
    },
};

ESP-IDF also enables advanced features:

  • Device Shadow — Subscribe to rosfit/{device_id}/shadow/desired and publish reported state to rosfit/{device_id}/shadow/reported.
  • OTA updates — Listen on rosfit/{device_id}/ota for firmware URLs, download and flash using the ESP-IDF OTA API.
  • Persistent sessions — Use MQTT clean session = false so the broker queues messages while the device sleeps.

STM32

STM32 microcontrollers are common in industrial and safety-critical robotics applications. micro-ROS supports several STM32 families via the micro_ros_stm32cubemx_utils package.

Supported boards

SeriesExample boardsRTOSTransportNotes
STM32F4Nucleo-F446RE, F407VG DiscoveryFreeRTOSSerial UARTMost widely tested with micro-ROS
STM32L4Nucleo-L476RGFreeRTOS, ZephyrSerial UARTLow-power variant for battery-operated nodes
STM32F7Nucleo-F767ZIFreeRTOSSerial UART, EthernetDual-core, hardware crypto for TLS
STM32H7Nucleo-H743ZI, H745 DiscoveryFreeRTOS, ZephyrSerial UART, EthernetHigh-performance, up to 480 MHz

Getting started

# Clone the micro-ROS tools
git clone https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup
rosdep update && rosdep install --from-paths src --ignore-src -y
colcon build
source install/setup.bash

# Create and configure the firmware workspace
ros2 run micro_ros_setup create_firmware_ws.sh freertos nucleo_f446re
ros2 run micro_ros_setup configure_firmware.sh nucleo_f446re --transport serial
ros2 run micro_ros_setup build_firmware.sh
ros2 run micro_ros_setup flash_firmware.sh

Connect the STM32 to a micro-ROS Agent host (Raspberry Pi or laptop) via USB/UART:

ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0 -b 115200

Other MCUs

micro-ROS and native MQTT support extends beyond ESP32 and STM32. The following boards have community-tested RosFit integrations:

BoardArchitecturemicro-ROSNative MQTTNotes
Teensy 4.0 / 4.1ARM Cortex-M7 @ 600 MHzYes (serial)Yes (Ethernet on 4.1)Excellent real-time performance
Arduino Portenta H7Dual-core STM32H747Yes (serial, Wi-Fi)Yes (Wi-Fi, Ethernet)Industrial IoT form factor, MicroPython support
Renesas RA6M5ARM Cortex-M33 @ 200 MHzYes (serial, Ethernet)Yes (Ethernet)TrustZone security, official micro-ROS support
Raspberry Pi Pico WRP2040 dual-core ARM M0+Experimental (serial)Yes (Wi-Fi)Ultra low-cost, good for sensor arrays

For any board that supports a serial connection to a micro-ROS Agent, the RosFit bridge running on the agent host will forward topics to the cloud automatically. For boards with native MQTT, configure them to publish to the standard rosfit/{device_id}/telemetry topic structure.