The MQTT library by 256dpi: MQTTClient on Arduino and ESP32
The library named plain "MQTT" in the Library Manager is Joël Gähwiler’s arduino-mqtt, built on the lwmqtt C client. Shiftr.io’s examples use it, and many people pick it over PubSubClient because its message handler hands you the topic and payload as Strings and because it can publish with QoS 1 and 2, not only subscribe with them.
Built in on Mokxi: #include <MQTT.h> and it builds, with nothing to install. Free, and no account needed.
What MQTT does
You make an MQTTClient, call begin() with the broker’s host and the network client to use, register onMessage(), then connect(). From then on client.loop() must run often: it reads what arrived, calls your handler and sends the keepalive. Adding delay(10) after loop() on an ESP8266 gives its WiFi stack time to work.
The buffer size is set when the object is made. MQTTClient client; gives 128 bytes for reading and writing, so a JSON payload of a few hundred bytes needs MQTTClient client(512); and a message that does not fit is dropped.
| Library Manager name | MQTT |
|---|---|
| Author | Joël Gähwiler |
| Include | #include <MQTT.h> |
| Boards | ESP32-C3, ESP32-C6, Seeed XIAO ESP32-C3, ESP32-C3 SuperMini, Seeed XIAO ESP32-C6, ESP32 DevKit, ESP32-DevKitC V4, LOLIN32 Lite, Wemos D1 R32, Cheap Yellow Display, TTGO T-Display, ESP32-S3-DevKitC-1, Seeed XIAO ESP32-S3, Arduino Nano ESP32, ESP8266 NodeMCU, Raspberry Pi Pico W, Arduino Uno R4 WiFi |
| In the simulator | Builds and runs, and says plainly that the hardware behind it is not simulated. |
Install it
It builds on ESP32-C3, ESP32-C6, Seeed XIAO ESP32-C3, ESP32-C3 SuperMini, Seeed XIAO ESP32-C6, ESP32 DevKit, ESP32-DevKitC V4, LOLIN32 Lite, Wemos D1 R32, Cheap Yellow Display, TTGO T-Display, ESP32-S3-DevKitC-1, Seeed XIAO ESP32-S3, Arduino Nano ESP32, ESP8266 NodeMCU, Raspberry Pi Pico W, Arduino Uno R4 WiFi.
In Mokxi it is built in: #include <MQTT.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "MQTT" by Joël Gähwiler from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add MQTT to lib_deps in PlatformIO. Mokxi follows the calls of release 2.5.3, so a sketch written here builds there too.
What to know in the simulator: MQTT needs a TCP connection to a broker, which the simulated network does not carry, so connect() fails with lastError() -3 and says why on Serial. HTTPClient with http://api.mokxi/ is the simulated way to the cloud.
ESP32-C3 · ESP32-C6 · Seeed XIAO ESP32-C3 · ESP32-C3 SuperMini · Seeed XIAO ESP32-C6 · ESP32 DevKit · ESP32-DevKitC V4 · LOLIN32 Lite · Wemos D1 R32 · Cheap Yellow Display · TTGO T-Display · ESP32-S3-DevKitC-1 · Seeed XIAO ESP32-S3 · Arduino Nano ESP32 · ESP8266 NodeMCU · Raspberry Pi Pico W · Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
MQTTClient client(256)
Creates the client with a 256-byte buffer for each direction. The default with no argument is 128 bytes.
client.begin("public.cloud.shiftr.io", net)
Sets the broker host (port 1883 unless you pass one) and the network client, usually WiFiClient net. It does not connect yet.
client.onMessage(messageReceived)
Registers void messageReceived(String &topic, String &payload). Do not publish or subscribe from inside it; set a flag and act in loop().
client.connect("arduino", "public", "public")
Connects with a client ID, user name and password, and returns true when the broker accepts. The tutorials loop on it with a one-second delay.
while (!client.connect("arduino", "public", "public")) {
Serial.print(".");
delay(1000);
}client.subscribe("/hello", 1)
Subscribes to a topic, here with QoS 1. Call it after every successful connect().
client.publish("/hello", "world", false, 1)
Publishes a message; the third argument is retained and the fourth the QoS. Returns false when not connected.
client.setWill("/status", "offline", true, 1)
Sets the last will, the message the broker sends for you if the board drops off without saying goodbye. Call it before connect().
client.lastError()
The lwmqtt error code from the last call, such as -3 for a network connection that failed. returnCode() gives the broker’s own answer to connect().
Example: arduino-mqtt, and why it cannot connect here
On the ESP32-C3-DevKitM-1. It runs in the browser exactly as printed.
#include <WiFi.h>
#include <MQTT.h>
WiFiClient net;
MQTTClient client;
void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
}
void setup() {
Serial.begin(115200);
WiFi.begin("Mokxi-Lab", "breadboard");
client.begin("public.cloud.shiftr.io", net);
client.onMessage(messageReceived);
if (!client.connect("arduino", "public", "public")) {
Serial.print("connect failed, lastError ");
Serial.println(client.lastError());
}
Serial.print("publish: ");
Serial.println(client.publish("/hello", "world"));
}
void loop() {}Common errors and how to fix them
connect() keeps returning false and lastError() is -3
That is LWMQTT_NETWORK_FAILED_CONNECT: the TCP connection to the broker did not open. Check WiFi first, then the host and port. In Mokxi the simulated network carries HTTP only, so this is what every MQTT connect() returns.
Messages over about a hundred bytes never arrive
The default buffer is 128 bytes and holds the topic and the payload together. Make the client with a bigger size, MQTTClient client(512);, as a global so it is created once.
The board freezes or resets inside the message handler
Calling publish(), subscribe() or delay() from inside the onMessage handler re-enters the client while it is still reading. Copy what you need into a variable, set a flag, and publish from loop() instead.
Questions and answers
MQTT or PubSubClient: which should I use?
Both talk MQTT 3.1.1 over a client you pass in. This one gives you String topic and payload in the handler and QoS on publish; PubSubClient has more tutorials. For a first project either works.
Try MQTT without installing anything
Open the example, change the sketch, and keep your version in a free account.