ESP32 MQTT Home Automation (Hands-on Project)
Connect your ESP32 NodeMCU to a public MQTT broker, publish sensor readings, and subscribe to control an LED.
Welcome to the ESP32 MQTT Hands-on Project! Now that we have covered the theory of MQTT, let's put it into action by building a real IoT project.
In this tutorial, we will:
- Connect an ESP32 to a local Wi-Fi network.
- Establish a connection to a free, public MQTT broker (
broker.hivemq.com). - Publish simulated temperature values from the ESP32 every 5 seconds.
- Subscribe to a command topic on the ESP32 to remotely turn the onboard LED ON or OFF.
🛠️ Requirements & Parts List
Here is what you will need for this project:
- ESP32 NodeMCU Board (Any standard ESP32 development board).
- Micro-USB Cable (To connect the ESP32 to your computer).
- Arduino IDE (Installed on your computer).
- Onboard LED (Usually pre-connected to GPIO 2).
Installing the MQTT Library:
To handle MQTT communications in Arduino IDE, we need to install the PubSubClient library:
- Open Arduino IDE.
- Navigate to Sketch ➡️ Include Library ➡️ Manage Libraries.
- In the Library Manager search bar, type PubSubClient (by Nick O'Leary).
- Click Install.
Note: The PubSubClient library is one of the most stable and popular MQTT client libraries for Arduino-compatible microcontrollers.
🔌 Connection & Circuit Setup
To keep things simple for testing, we will use the onboard blue LED pre-wired on the ESP32 board.
- Onboard LED Pin: GPIO 2 (labeled as
2orD2on most ESP32 boards).
If you want to control a physical appliance instead, connect a 5V relay module as follows:
- Relay VCC ➡️ ESP32 Vin (5V Supply)
- Relay GND ➡️ ESP32 GND
- Relay IN ➡️ ESP32 GPIO 2
💻 Arduino Source Code
Copy the code below into your Arduino IDE.
Make sure to update:
ssidandpasswordwith your Wi-Fi credentials.client_id(on Line 74) to a unique string to avoid server conflicts.
#include <WiFi.h>
#include <PubSubClient.h>
// --- WiFi Configuration ---
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// --- MQTT Broker Configuration ---
// We are using HiveMQ's free public sandbox broker
const char* mqtt_broker = "broker.hivemq.com";
const int mqtt_port = 1883;
// --- MQTT Topics ---
const char* publish_topic = "sparkovation/esp32/temp";
const char* subscribe_topic = "sparkovation/esp32/led";
// ESP32 Client Instances
WiFiClient espClient;
PubSubClient client(espClient);
const int ledPin = 2; // Onboard LED Pin
unsigned long lastMsg = 0;
float temperature = 24.0;
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.print("IP address: ");
Serial.println(WiFi.localIP());
}
// Callback Function: Triggered when a new message arrives on a subscribed topic
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("]: ");
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println(message);
// Switch LED control logic
if (String(topic) == subscribe_topic) {
if (message == "ON") {
digitalWrite(ledPin, HIGH);
Serial.println("LED turned ON!");
} else if (message == "OFF") {
digitalWrite(ledPin, LOW);
Serial.println("LED turned OFF!");
}
}
}
// Reconnect Function: Reconnects to the broker if connection drops
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a unique client ID to prevent connection collisions
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("connected!");
// Re-subscribe to control topic
client.subscribe(subscribe_topic);
Serial.print("Subscribed to: ");
Serial.println(subscribe_topic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" trying again in 5 seconds");
delay(5000);
}
}
}
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop(); // Keeps the MQTT client running and handles keep-alives
unsigned long now = millis();
// Publish simulated temperature reading every 5 seconds
if (now - lastMsg > 5000) {
lastMsg = now;
// Simulate slight temperature changes (+/- 0.5 degrees)
temperature += random(-5, 6) / 10.0;
// Convert float value to a string
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
Serial.print("Publishing temperature: ");
Serial.println(tempString);
client.publish(publish_topic, tempString);
}
}🔍 Testing the Setup
Once the code is uploaded to your ESP32, you can test publishing and subscribing using one of the following methods:
Method 1: HiveMQ Web Client (No Installation)
- Open the HiveMQ Websocket Client Demo in your web browser.
- Leave the default settings and click Connect.
- Under the Subscriptions panel, click Add New Topic Subscription and subscribe to:
sparkovation/esp32/temp. You should start seeing the ESP32's temperature values appear here every 5 seconds! - Under the Publish panel, enter the topic
sparkovation/esp32/ledand writeON(case-sensitive) in the message box. Click Publish and watch the ESP32 onboard blue LED turn ON. - Publish
OFFto turn the LED OFF.
Method 2: MQTT Explorer (Desktop Client)
For a comprehensive desktop testing tool, download MQTT Explorer.
- Host:
broker.hivemq.com - Port:
1883 - Click Connect. This tool lets you view the entire topic tree hierarchically, watch live published changes, and publish control values instantly.
🛠️ Common Troubleshooting
- Serial Monitor shows
rc=-2(Connection Failed):- Cause: The broker is unreachable. Make sure your local router is connected to the internet. Since this is a public broker sandbox, the broker itself might occasionally be down.
- Serial Monitor shows
rc=-4(Connection Timeout):- Cause: Your router or firewall may be blocking outgoing traffic on Port 1883. Try connecting the ESP32 and computer to a mobile hotspot.
- ESP32 is stuck printing dots (
....) and not connecting to Wi-Fi:- Cause: Double-check your SSID and Password. Remember that ESP32 only supports 2.4GHz Wi-Fi bands; it cannot connect to a 5GHz network.
🎉 Congratulations!
You have successfully built and tested a real-time MQTT home automation node! You can now expand this setup by connecting DHT22 sensors, active relays, and linking them to your favorite home automation dashboards.
