CloudAMQP with MQTT and Arduino
We recommend PubSubClient, the most widely used MQTT client for Arduino. The examples run on an ESP32 with the Arduino core for the ESP32. Install the esp32 board package and the PubSubClient library in the Arduino IDE, or with arduino-cli:
arduino-cli lib install PubSubClient
Publish and subscribe
Set your WiFi network and the MQTT details from your instance’s details page in the CloudAMQP console at the top of both sketches. Port 8883 uses TLS.
Save the publisher as publisher/publisher.ino:
#include <PubSubClient.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
const char* WIFI_SSID = "your-wifi";
const char* WIFI_PASSWORD = "your-wifi-password";
// The MQTT details from your instance's details page in the CloudAMQP console
const char* MQTT_HOST = "host.cloudamqp.com";
const int MQTT_PORT = 8883; // TLS
const char* MQTT_USERNAME = "vhost:user";
const char* MQTT_PASSWORD = "password";
WiFiClientSecure secureClient;
WiFiClient plainClient;
PubSubClient mqtt(MQTT_PORT == 8883 ? static_cast<Client&>(secureClient) : plainClient);
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) delay(500);
// Verify the server against the CA certificates built into the ESP32 core
secureClient.useBuiltinCACertBundle();
mqtt.setServer(MQTT_HOST, MQTT_PORT);
if (!mqtt.connect(("publisher-" + WiFi.macAddress()).c_str(), MQTT_USERNAME, MQTT_PASSWORD)) {
Serial.printf("Connection failed: %d\n", mqtt.state());
return;
}
// PubSubClient can only publish with QoS 0
mqtt.publish("hello", "Hello world!");
Serial.println(" [x] Sent 'Hello world!'");
mqtt.disconnect();
}
void loop() {}
Save the subscriber as worker/worker.ino:
#include <PubSubClient.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
const char* WIFI_SSID = "your-wifi";
const char* WIFI_PASSWORD = "your-wifi-password";
// The MQTT details from your instance's details page in the CloudAMQP console
const char* MQTT_HOST = "host.cloudamqp.com";
const int MQTT_PORT = 8883; // TLS
const char* MQTT_USERNAME = "vhost:user";
const char* MQTT_PASSWORD = "password";
WiFiClientSecure secureClient;
WiFiClient plainClient;
PubSubClient mqtt(MQTT_PORT == 8883 ? static_cast<Client&>(secureClient) : plainClient);
// PubSubClient acks each QoS 1 message when the callback returns
void onMessage(char* topic, byte* payload, unsigned int length) {
Serial.printf(" [x] Received '%.*s'\n", length, (char*)payload);
}
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) delay(500);
// Verify the server against the CA certificates built into the ESP32 core
secureClient.useBuiltinCACertBundle();
mqtt.setServer(MQTT_HOST, MQTT_PORT);
mqtt.setCallback(onMessage);
if (!mqtt.connect(("worker-" + WiFi.macAddress()).c_str(), MQTT_USERNAME, MQTT_PASSWORD)) {
Serial.printf("Connection failed: %d\n", mqtt.state());
return;
}
mqtt.subscribe("hello", 1);
Serial.println(" [*] Waiting for messages");
}
void loop() {
mqtt.loop();
}
Upload the worker to one board and open the serial monitor at 115200 baud, then upload the publisher to another.
The example is in arduino/pubsubclient in cloudamqp/examples. Running it needs an ESP32, so its CI only compiles the sketches.
Good to know
- Put the vhost in the username, as
vhost:user. MQTT has no vhost of its own, and the console shows the username that way. - Verify the server certificate.
useBuiltinCACertBundle()checks it against the CA certificates built into the ESP32 core 3.x, which adds about 70 KB to the sketch. Don’t usesetInsecure(), which skips the check. - PubSubClient only publishes with QoS 0, so the broker doesn’t confirm a message. It subscribes with QoS 1, and acks each message when the callback returns.
- Call
loop()often. It receives messages and keeps the connection alive. PubSubClient doesn’t reconnect; checkconnected()inloop()and connect and subscribe again.