MQTT robot telemetry with ESP32: topics, QoS and code

Design MQTT topics for a robot, pick the right QoS, publish telemetry from an ESP32 and avoid the buffering and Wi-Fi traps that break it.

Reference
RE-871
Published
Read
4 min

About the author · Sources, testing and AI policy

Robot telemetry dashboard showing battery and speed charts

MQTT is the cheapest way to get robot telemetry off the machine and onto a dashboard. One broker, a few topics, and an ESP32 publishing battery, speed and fault data over Wi-Fi.

This guide covers the topic design, the QoS choices, a working ESP32 publisher, a subscriber that logs to a database, and the Wi-Fi and memory traps that break telemetry in the field.

Why MQTT suits a robot

  • Small messages over a small bandwidth link.
  • Publish and subscribe, so many dashboards can read one robot.
  • A broker decouples the robot from whoever is watching it.
  • Last Will and Testament tells you when a robot drops off.
  • Retained messages mean a new subscriber sees the last known state immediately.
  • Runs comfortably on an ESP32 with a few KB of RAM per connection.

Design the topic tree first

robots/<robot_id>/status
robots/<robot_id>/battery
robots/<robot_id>/velocity
robots/<robot_id>/fault
robots/<robot_id>/cmd/velocity
robots/<robot_id>/cmd/estop
TopicDirectionQoSRetained
statusRobot to broker1Yes
batteryRobot to broker0Yes
velocityRobot to broker0No
faultRobot to broker1Yes
cmd/velocityOperator to robot1No
cmd/estopOperator to robot1No

Keep commands and telemetry in separate subtrees. It makes broker access control simple: the dashboard can read everything under the robot, but write only under cmd/.

QoS without overthinking it

QoSGuaranteeUse for
0At most once, fire and forgetFast telemetry, velocity, battery
1At least once, may duplicateCommands, faults, status
2Exactly onceBilling or records, rarely a robot

QoS 1 can deliver duplicates, so make the receiving handler idempotent. A command with a sequence number that ignores repeats is safer than one that executes twice.

A working ESP32 publisher

The PubSubClient library is the common choice. Connect, publish on a timer, and use a Last Will so the broker marks the robot offline when the link dies.

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

WiFiClient net;
PubSubClient mqtt(net);
const char* robot = "robot-01";

void connect() {
  while (!mqtt.connected()) {
    if (mqtt.connect(robot, nullptr, nullptr,
        "robots/robot-01/status", 1, true, "offline")) {
      mqtt.publish("robots/robot-01/status", "online", true);
    } else {
      delay(2000);
    }
  }
}

void setup() {
  WiFi.begin("SSID", "PASSWORD");
  mqtt.setServer("192.168.1.50", 1883);
  mqtt.setBufferSize(512);
}

void loop() {
  if (!mqtt.connected()) connect();
  mqtt.loop();
  static unsigned long last = 0;
  if (millis() - last > 2000) {
    last = millis();
    char buf[96];
    snprintf(buf, sizeof(buf),
      "{\"v\":%.1f,\"b\":%d}", 0.42, 87);
    mqtt.publish("robots/robot-01/telemetry", buf);
  }
}

Note the explicit buffer size. The default 256-byte packet limit is the most common reason a JSON payload silently fails to publish.

The broker

Mosquitto on a small VPS or a Raspberry Pi handles a workshop full of robots. Open 1883 only inside your network, and 8883 with TLS if anything crosses the internet.

sudo apt install mosquitto mosquitto-clients
mosquitto_sub -h localhost -t 'robots/#' -v

Create a username and password per robot, and give the dashboard a separate read-only account. An open broker on a factory network is a remote-control hole.

From broker to dashboard

  • Node-RED: fastest path to charts and alerts, runs on the same Pi.
  • InfluxDB plus Grafana: better for history and long-term trends.
  • Home Assistant: useful for small service robots and lab setups.
  • A Python subscriber: writes to Postgres when you need custom logic.

A simple Python subscriber that stores every message with a timestamp is often all a first deployment needs. Build the dashboard after the data is reliable.

Field problems and what causes them

SymptomLikely cause
Messages stop after a few minutesKeepalive too short for Wi-Fi latency
Publish returns falsePayload larger than the buffer
Reconnect loopDuplicate client ID from a cloned device
Dashboard shows stale dataRetained message never updated, or LWT not set
Commands arrive twiceQoS 1 duplicate without an idempotency check
Robot busy or slowPublishing too often from the main control loop

What not to put on MQTT

  • Safety stop commands over Wi-Fi. Hardwire the E-stop.
  • High-rate control loops. Use a local bus or micro-ROS.
  • Large images or point clouds. Send a link or a summary.
  • Credentials in plain text on port 1883 across the internet.
  • Anything you cannot afford to lose without an acknowledgement path.

Related: ESP32 pinout for robotics, micro-ROS tutorial, Raspberry Pi 5 robot guide, robot battery guide, mobile robot charging and docking.

Is MQTT good for robot telemetry?

Yes for low-rate telemetry such as battery, status, faults and position. It is not suitable for safety stops or high-rate control loops, which should stay on hardware or a local bus.

Which QoS should I use for robot data?

QoS 0 for fast telemetry like velocity and battery, QoS 1 for commands and faults. QoS 2 is rarely worth the overhead on a robot.

Why does my ESP32 stop publishing to MQTT?

The usual causes are a payload bigger than the 256-byte default buffer, a keepalive too short for Wi-Fi latency, or a duplicate client ID after cloning a device.

Can I send emergency stop over MQTT?

No. A safety stop must be hardwired and independent of Wi-Fi, the broker and the network. MQTT can notify people that a stop happened, not perform it.

Do I need TLS for MQTT on a robot?

If traffic crosses the internet, yes, use port 8883 with certificates. Inside an isolated workshop network, 1883 with per-device credentials is common but still needs access control.

For driving rather than telemetry, a phone app over WebSocket is simpler.

Streaming attitude data is easier once the MPU6050 angle estimation loop is stable and calibrated.

Telemetry should never block the motor loop, which is why the task and queue design separates comms from control.

For telemetry rather than driving, the same network foundation is covered in this control guide.

MQTT is one of the transport options in a factory deployment, described alongside OPC UA in the IIoT monitoring guide.

Sources and further reading

Pass it onWhatsAppLinkedIn

Keep reading

Continue learning

The Build Note

One short email when something is worth your bench time.

A new build sheet, a part price that moved, or a mistake worth avoiding. No daily drip, no recycled news.

One short email when a build or a price is worth your time. Unsubscribe in one click.