An ESP32 can talk MQTT to a broker, but it’s not actually sending its sensor data to the broker directly; it’s publishing it to a topic, and the broker is then relaying that message to any client subscribed to that topic.
Let’s get a simple temperature sensor hooked up to an ESP32 and have it report its readings via MQTT.
Here’s the hardware you’ll need:
- ESP32 development board (e.g., ESP32-DevKitC)
- DHT11 or DHT22 temperature and humidity sensor
- Jumper wires
And the software setup:
- Install Arduino IDE: If you don’t have it, download it from the Arduino website.
- Add ESP32 Board Support:
- Go to
File > Preferences. - In the "Additional Boards Manager URLs" field, add this URL:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - Go to
Tools > Board > Boards Manager.... - Search for "esp32" and install the package by Espressif Systems.
- Go to
- Install Libraries:
- Go to
Sketch > Include Library > Manage Libraries.... - Search for and install "DHT sensor library" by Adafruit.
- Search for and install "Adafruit Unified Sensor" by Adafruit.
- Search for and install "PubSubClient" by Nick O’Leary.
- Go to
Now, let’s wire it up. The DHT sensor has three pins: VCC, Data, and GND.
- Connect DHT VCC to the ESP32’s 3.3V pin.
- Connect DHT GND to the ESP32’s GND pin.
- Connect DHT Data to a digital GPIO pin on the ESP32. Let’s use GPIO 4.
Here’s the code. We’ll need your Wi-Fi credentials and the address of your MQTT broker. For testing, you can use a public broker like test.mosquitto.org or set up your own using Mosquitto on a Raspberry Pi or Docker.
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// --- WiFi Configuration ---
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// --- MQTT Configuration ---
const char* mqtt_server = "test.mosquitto.org"; // Or your broker's IP/hostname
const int mqtt_port = 1883;
const char* mqtt_client_id = "esp32_sensor_client";
const char* mqtt_topic_temp = "esp32/sensor/temperature";
const char* mqtt_topic_humidity = "esp32/sensor/humidity";
// --- DHT Sensor Configuration ---
#define DHTPIN 4 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 11 or DHT 22
DHT dht(DHTPIN, DHTTYPE);
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect(mqtt_client_id)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
dht.begin();
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
delay(2000); // Wait a couple of seconds between measurements.
// Reading temperature or humidity takes about 250 milliseconds.
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C ");
// Publish sensor data
char tempString[8];
dtostrf(t, 1, 2, tempString); // Convert float to string: min width 1, 2 decimal places
client.publish(mqtt_topic_temp, tempString);
char humString[8];
dtostrf(h, 1, 2, humString);
client.publish(mqtt_topic_humidity, humString);
Serial.println("Published to MQTT.");
}
Before uploading, make sure to replace "YOUR_WIFI_SSID" and "YOUR_WIFI_PASSWORD" with your actual network credentials.
Once uploaded, open the Serial Monitor (Tools > Serial Monitor, set baud rate to 115200). You should see the ESP32 connecting to Wi-Fi, then connecting to the MQTT broker. It will then start printing the temperature and humidity readings to the serial monitor and publishing them.
To verify, you can use an MQTT client tool like MQTT Explorer or mosquitto_sub on your computer. Subscribe to the topics esp32/sensor/temperature and esp32/sensor/humidity. You should see messages appearing with the sensor readings.
The PubSubClient library handles the MQTT communication. The client.loop() function is crucial; it needs to be called regularly to process incoming messages and maintain the connection. In loop(), we check if the client is connected, and if not, we call reconnect(). Then, we read the DHT sensor, format the readings into strings, and publish them to their respective topics using client.publish(topic, payload). The dtostrf function is used to convert the floating-point temperature and humidity values into null-terminated strings, which is what client.publish expects for the payload.
The next step is to build a system that can receive these messages and act on them, such as displaying them on a web page or triggering an alert.