ESP32 WiFi and MQTT — Connect Sensors to the Cloud with Arduino IDE
The ESP32 is a low-cost, low-power microcontroller with integrated WiFi and Bluetooth, making it the most popular chip for IoT projects that need wireless connectivity and sensor processing.
Why ESP32 Matters
Before ESP32, building a WiFi-connected IoT device required either an Arduino + separate WiFi module (ESP8266) or expensive development boards. The ESP32 integrates dual-core processing, WiFi, Bluetooth, and a rich peripheral set into a chip costing under $5. It’s used in commercial smart plugs, environmental monitors, and industrial sensors. With 512KB SRAM and up to 16MB flash, it can run TLS connections, MQTT clients, and even TensorFlow Lite Micro for edge AI.
Plain-Language Explanation
Think of an ESP32 as an Arduino that can talk to the internet without any extra parts. You write code on your computer, upload it over USB, and the ESP32 connects to your WiFi network. Once online, it can read sensors, control relays, and send data to any cloud platform using MQTT or HTTP.
The magic is that it costs less than a coffee and uses less power than a nightlight. A battery-powered ESP32 can run for months by sleeping between readings.
graph TD
Computer[Computer
Arduino IDE] -->|USB Upload| ESP[ESP32]
ESP -->|GPIO| DHT[DHT22
Temp/Humidity]
ESP -->|GPIO| Relay[Relay Module]
ESP -->|WiFi| Router[WiFi Router]
Router --> Internet[Internet]
Internet --> MQTT[MQTT Broker
Mosquitto / Cloud]
MQTT --> Dashboard[Dashboard
Node-RED / App]
style ESP fill:#e7352c,color:#fff
style MQTT fill:#e67e22,color:#fff
style Dashboard fill:#27ae60,color:#fff
Arduino IDE Setup
- Install Arduino IDE (2.x recommended)
- Add ESP32 board URL: File → Preferences → Additional Boards Manager URLs:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - Install ESP32 boards: Tools → Board → Boards Manager → search “ESP32”
- Install libraries: Library Manager → “PubSubClient” (MQTT) and “DHT sensor library”
Wiring: DHT22 Temperature/Humidity Sensor
| ESP32 Pin | DHT22 Pin |
|---|---|
| 3.3V | VCC (pin 1) |
| GPIO 4 | Data (pin 2) |
| GND | GND (pin 4) |
Add a 10kΩ pull-up resistor between VCC and Data pins.
Code: WiFi + MQTT Sensor Publisher
// esp32_mqtt_sensor.ino
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// WiFi credentials
const char* WIFI_SSID = "YourNetwork";
const char* WIFI_PASS = "YourPassword";
// MQTT broker
const char* MQTT_SERVER = "broker.example.com";
const int MQTT_PORT = 1883;
const char* MQTT_TOPIC = "home/livingroom/env";
const char* MQTT_USER = "";
const char* MQTT_PASS = "";
// Sensor
#define DHTPIN 4 // GPIO 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
void setup() {
Serial.begin(115200);
dht.begin();
connectWiFi();
mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
}
void loop() {
if (!mqttClient.connected()) {
reconnectMQTT();
}
mqttClient.loop();
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Sensor read failed");
delay(5000);
return;
}
// Format: {"temp":23.5,"hum":55.2}
char payload[100];
snprintf(payload, sizeof(payload),
"{\"temp\":%.1f,\"hum\":%.1f}",
temperature, humidity);
Serial.print("Publishing: ");
Serial.println(payload);
mqttClient.publish(MQTT_TOPIC, payload);
delay(10000); // Read every 10 seconds
}
void connectWiFi() {
Serial.print("Connecting to WiFi");
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnectMQTT() {
while (!mqttClient.connected()) {
Serial.print("Connecting to MQTT...");
if (mqttClient.connect("ESP32-Sensor-1", MQTT_USER, MQTT_PASS)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" retrying in 5s");
delay(5000);
}
}
}Expected Serial Monitor output:
Connecting to WiFi....
WiFi connected
IP address: 192.168.1.42
Connecting to MQTT...connected
Publishing: {"temp":24.7,"hum":55.2}
Publishing: {"temp":24.8,"hum":55.0}
Publishing: {"temp":25.1,"hum":54.8}Deep Sleep Mode (Battery Operation)
For battery-powered projects, the ESP32’s deep sleep mode reduces power consumption from ~80mA to ~10µA:
// Deep sleep between readings extends battery life to months
void setup() {
Serial.begin(115200);
// Read sensor and publish...
// ...
Serial.println("Entering deep sleep for 60 seconds");
esp_sleep_enable_timer_wakeup(60 * 1000000); // 60 seconds in microseconds
esp_deep_sleep_start(); // CPU off, RTC on
}
void loop() {
// Never reached — ESP32 wakes, runs setup(), then sleeps again
}Over-the-Air (OTA) Updates
Once deployed, physically accessing an ESP32 to update code is impractical. OTA updates let you upload new firmware over WiFi:
#include <ArduinoOTA.h>
void setup() {
// ... WiFi connection code ...
ArduinoOTA.setHostname("ESP32-Sensor-1");
ArduinoOTA.begin();
Serial.println("OTA ready");
}
void loop() {
ArduinoOTA.handle(); // Handle OTA updates
// ... MQTT code ...
}Common Mistakes
Wrong GPIO numbers: ESP32 GPIO numbering differs from pin numbers on the board. Check a pinout diagram — GPIO 4 is NOT pin 4 on the physical header.
Power supply insufficient: ESP32 can draw 500mA during WiFi transmission. A USB port can handle this, but battery regulators often can’t. Use a 3.3V regulator rated for 1A minimum.
MQTT keepalive too long: Default MQTT keepalive (15 seconds) causes reconnections if you only publish every 10 minutes. Set a longer keepalive or disable it.
No watchdog: If MQTT connection hangs, the ESP32 stops responding. Enable the watchdog timer to auto-reset:
esp_task_wdt_init(10, true);WiFi reconnection not handled: WiFi drops happen. Always check
WiFi.status()and reconnect in the main loop.
Practice Questions
Why is ESP32 preferred over Arduino Uno for IoT? ESP32 has built-in WiFi and Bluetooth, more RAM (512KB vs 2KB), dual-core processor, and costs under $5. Arduino Uno needs external modules for connectivity.
How does deep sleep extend battery life? Deep sleep turns off the CPU, WiFi, and most peripherals, reducing current from ~80mA to ~10µA. The device wakes periodically (RTC timer), reads sensors, transmits data, and sleeps again.
What is the PubSubClient library used for? It implements the MQTT protocol on ESP32, allowing the device to publish sensor data and subscribe to topics on an MQTT broker.
Why add a pull-up resistor to the DHT22 data line? The DHT22 uses an open-drain protocol requiring a pull-up resistor (typically 4.7kΩ-10kΩ) to hold the data line high when the sensor isn’t driving it.
How does OTA firmware update work? The ESP32 runs a web server that receives new firmware binaries over WiFi and writes them to flash, eliminating the need for USB cable connection for updates.
Mini Project
Build a WiFi-connected environmental monitor:
Components: ESP32, DHT22 sensor, breadboard, jumper wires.
Wiring as described above. The code publishes temperature and humidity via MQTT every 10 seconds. Deploy the code, subscribe to the topic with an MQTT client:
mosquitto_sub -h broker.example.com -t "home/livingroom/env" -vExpected output:
home/livingroom/env {"temp":24.7,"hum":55.2}
home/livingroom/env {"temp":24.8,"hum":55.0}
home/livingroom/env {"temp":25.1,"hum":54.8}Cross-References
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro