🔌 Phase 3

ESP32 + WiFi MQTT Integration

Embedded side implementation jahan actual device broker ke saath connect hota hai

📋 Topics Covered in Phase 3

1ESP32 MQTT connection setup
2Simple PubSubClient setup
3Relay control via MQTT topics
4Auto reconnection logic
5Multi-device architecture patterns

⚙️ Step 1: Arduino IDE Setup for ESP32

Add ESP32 Board Manager URL

Arduino IDE me ESP32 board support add karne ke liye:

# 1. Open Arduino IDE
# 2. Go to File → Preferences
# 3. Add this URL in "Additional Board Manager URLs":
https://dl.espressif.com/dl/package_esp32_index.json

Install ESP32 Board Package

# 1. Go to Tools → Board → Board Manager
# 2. Search for "ESP32"
# 3. Install "esp32 by Espressif Systems"

Install Required Libraries

MQTT communication ke liye PubSubClient library install karo:

# Go to Sketch → Include Library → Manage Libraries
# Search and install:
PubSubClient by Nick O'Leary
# Also install (for WiFi):
WiFi (built-in with ESP32 core)
⚠️

PubSubClient Configuration: Default MAX_PACKET_SIZE 128 bytes hai. Large payloads ke liye Header file me change karo:
#define MQTT_MAX_PACKET_SIZE 512

📶 Step 2: WiFi Connection Setup

Ye WiFi-only sketch Arduino IDE me direct compile/upload ho jayega. Current WiFi values already set hain.

// esp32-wifi-test.ino #include <WiFi.h> const char* WIFI_SSID = "Airtel_Yarana"; const char* WIFI_PASSWORD = "Abhishek@7052"; const int WIFI_LED = 2; unsigned long lastWiFiRetry = 0; void setup() { Serial.begin(115200); pinMode(WIFI_LED, OUTPUT); setupWiFi(); } void loop() { if (WiFi.status() != WL_CONNECTED && millis() - lastWiFiRetry > 10000) { lastWiFiRetry = millis(); Serial.println("WiFi disconnected. Connecting again..."); setupWiFi(); } delay(100); } void setupWiFi() { Serial.print("Connecting to WiFi: "); Serial.println(WIFI_SSID); digitalWrite(WIFI_LED, LOW); WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(500); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); int attempts = 0; while (WiFi.status() != WL_CONNECTED && attempts < 30) { delay(500); Serial.print("."); attempts++; } if (WiFi.status() == WL_CONNECTED) { Serial.println(); Serial.println("WiFi Connected!"); Serial.print("IP Address: "); Serial.println(WiFi.localIP()); digitalWrite(WIFI_LED, HIGH); } else { Serial.println(); Serial.println("WiFi Connection Failed!"); } }

🔌 Step 3: MQTT Client Setup

ESP32 broker se connect hoga, command topic listen karega, aur received command ke according relay/status update karega.

MQTT flow

  • ESP32 WiFi se connect hone ke baad MQTT broker se connect hota hai.
  • ESP32 ek command topic subscribe karta hai.
  • Laptop/mobile app us topic par ON, OFF, TOGGLE ya STATUS message publish karta hai.
  • ESP32 command receive karke relay control karta hai aur status publish karta hai.
# Mac / MQTT broker IP
192.168.1.6
# ESP32 device IP from Serial Monitor
192.168.1.46
# MQTT commands me -h ke saath broker IP use hota hai
mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "ON"
# Broker IP: laptop/server ka IP address
MQTT_BROKER = "192.168.1.6"
# Command topic: ESP32 isi topic ko listen karega
home/relay/esp32-001/command
# Status topic: ESP32 apna current status yahan publish karega
home/relay/esp32-001/status

Terminal 1: ESP32 status dekho

mosquitto_sub -h 192.168.1.6 -t "home/relay/esp32-001/#" -v

Terminal 2: ESP32 ko command bhejo

mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "ON"
mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "OFF"
mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "TOGGLE"
mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "STATUS"
💡

Result: ON command send karne par ESP32 Serial Monitor me received message dikhega. Terminal 1 me status/response publish hota hua dikhega.

📝 Step 4: Complete ESP32 MQTT Sketch

Complete working ESP32 sketch jisme WiFi + MQTT + Relay Control + Telemetry sab kuch hai:

// esp32-mqtt-relay-complete.ino // Complete ESP32 MQTT Control with Relay // =========================================== // INCLUDES // =========================================== #include <WiFi.h> #include <PubSubClient.h> // =========================================== // CONFIGURATION - CHANGE THESE! // =========================================== // WiFi const char* WIFI_SSID = "Airtel_Yarana"; const char* WIFI_PASSWORD = "Abhishek@7052"; // MQTT Broker const char* MQTT_BROKER = "192.168.1.6"; const int MQTT_PORT = 1883; const char* MQTT_USER = ""; // Leave empty if no auth const char* MQTT_PASSWORD = ""; // Device ID - MUST BE UNIQUE per device const char* DEVICE_ID = "esp32-001"; // MQTT Topics const char* TOPIC_CMD = "home/relay/esp32-001/command"; const char* TOPIC_STATUS = "home/relay/esp32-001/status"; const char* TOPIC_TELEMETRY = "home/relay/esp32-001/telemetry"; const char* TOPIC_RESPONSE = "home/relay/esp32-001/response"; // Hardware Pins const int RELAY_PIN = 26; // Relay signal pin const int LED_PIN = 2; // Built-in LED // =========================================== // GLOBAL OBJECTS // =========================================== WiFiClient espClient; PubSubClient mqttClient(espClient); // State variables bool relayState = false; unsigned long lastTelemetry = 0; unsigned long lastWiFiRetry = 0; const int TELEMETRY_INTERVAL = 30000; // Send telemetry every 30 seconds // =========================================== // SETUP // =========================================== void setup() { Serial.begin(115200); Serial.println("ESP32 MQTT Relay Starting..."); // Configure pins pinMode(RELAY_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT); digitalWrite(RELAY_PIN, LOW); // Relay OFF at start digitalWrite(LED_PIN, LOW); // Connect to WiFi setupWiFi(); // Setup MQTT mqttClient.setServer(MQTT_BROKER, MQTT_PORT); mqttClient.setCallback(mqttCallback); Serial.println("✅ Setup Complete!"); } // =========================================== // MAIN LOOP // =========================================== void loop() { if (WiFi.status() != WL_CONNECTED) { if (millis() - lastWiFiRetry > 10000) { lastWiFiRetry = millis(); Serial.println("WiFi disconnected. Connecting again..."); setupWiFi(); } delay(100); return; } // Maintain MQTT connection if (!mqttClient.connected()) { reconnectMQTT(); } mqttClient.loop(); // Send telemetry periodically if (millis() - lastTelemetry > TELEMETRY_INTERVAL) { sendTelemetry(); lastTelemetry = millis(); } delay(10); // Small delay to prevent watchdog } // =========================================== // WiFi Setup // =========================================== void setupWiFi() { Serial.print("Connecting to WiFi: "); Serial.println(WIFI_SSID); WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(500); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); int attempts = 0; while (WiFi.status() != WL_CONNECTED && attempts < 30) { delay(500); Serial.print("."); digitalWrite(LED_PIN, millis() % 1000 < 500 ? HIGH : LOW); attempts++; } if (WiFi.status() == WL_CONNECTED) { Serial.println(); Serial.println("WiFi Connected!"); Serial.printf("IP: %s\n", WiFi.localIP().toString().c_str()); Serial.printf("RSSI: %d dBm\n", WiFi.RSSI()); digitalWrite(LED_PIN, HIGH); // LED ON when connected } else { Serial.println(); Serial.println("WiFi Failed!"); } } // =========================================== // MQTT Reconnection // =========================================== void reconnectMQTT() { while (!mqttClient.connected()) { Serial.print("MQTT connecting..."); // Create unique client ID char clientID[50]; snprintf(clientID, sizeof(clientID), "%s-%d", DEVICE_ID, millis()); // Connect with or without auth bool connected; if (strlen(MQTT_USER) > 0) { connected = mqttClient.connect(clientID, MQTT_USER, MQTT_PASSWORD); } else { connected = mqttClient.connect(clientID); } if (connected) { Serial.println(" Connected!"); mqttClient.subscribe(TOPIC_CMD); Serial.printf("Subscribed: %s\n", TOPIC_CMD); // Publish online status (retained) mqttClient.publish(TOPIC_STATUS, "{\"state\":\"online\"}", true); } else { Serial.printf(" Failed (rc=%d)\n", mqttClient.state()); delay(5000); } } } // =========================================== // MQTT Message Handler // =========================================== void mqttCallback(char* topic, byte* payload, unsigned int length) { // Convert payload to string char msg[length + 1]; memcpy(msg, payload, length); msg[length] = '\0'; Serial.printf("[%s]: %s\n", topic, msg); // Parse command if (strcmp(msg, "ON") == 0) { relayState = true; digitalWrite(RELAY_PIN, HIGH); digitalWrite(LED_PIN, HIGH); Serial.println("Relay: ON"); mqttClient.publish(TOPIC_RESPONSE, "{\"result\":\"ok\",\"relay\":\"on\"}"); publishStatus(); } else if (strcmp(msg, "OFF") == 0) { relayState = false; digitalWrite(RELAY_PIN, LOW); digitalWrite(LED_PIN, LOW); Serial.println("Relay: OFF"); mqttClient.publish(TOPIC_RESPONSE, "{\"result\":\"ok\",\"relay\":\"off\"}"); publishStatus(); } else if (strcmp(msg, "TOGGLE") == 0) { relayState = !relayState; digitalWrite(RELAY_PIN, relayState ? HIGH : LOW); digitalWrite(LED_PIN, relayState ? HIGH : LOW); Serial.printf("Relay: %s\n", relayState ? "ON" : "OFF"); char response[100]; snprintf(response, sizeof(response), "{\"result\":\"ok\",\"relay\":\"%s\"}", relayState ? "on" : "off"); mqttClient.publish(TOPIC_RESPONSE, response); publishStatus(); } else if (strcmp(msg, "STATUS") == 0) { Serial.println("Status requested"); publishStatus(); } } // =========================================== // Publish Device Status // =========================================== void publishStatus() { char payload[200]; snprintf(payload, sizeof(payload), "{\"device\":\"%s\",\"relay\":%s,\"rssi\":%d,\"uptime\":%lu,\"ip\":\"%s\"}", DEVICE_ID, relayState ? "\"on\"" : "\"off\"", WiFi.RSSI(), millis() / 1000, WiFi.localIP().toString().c_str() ); mqttClient.publish(TOPIC_STATUS, payload, true); Serial.printf("Status: %s\n", payload); } // =========================================== // Send Telemetry Data // =========================================== void sendTelemetry() { char payload[200]; snprintf(payload, sizeof(payload), "{\"device\":\"%s\",\"rssi\":%d,\"uptime\":%lu,\"freeheap\":%lu}", DEVICE_ID, WiFi.RSSI(), millis() / 1000, (unsigned long) ESP.getFreeHeap() ); mqttClient.publish(TOPIC_TELEMETRY, payload); Serial.printf("Telemetry: %s\n", payload); }
💡

Testing the ESP32:
1. Upload sketch to ESP32
2. Open Serial Monitor at 115200 baud
3. From another terminal: `mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "ON"`
4. ESP32 will respond and relay will activate!

🏢 Step 5: Multi-Device Topic Pattern

Agar same project me multiple ESP32 devices hon, to har device ka ID aur topic unique rakha jata hai.

# Pattern
home/relay/DEVICE_ID/command
home/relay/DEVICE_ID/status
# Example device 1
home/relay/esp32-001/command
home/relay/esp32-001/status
# Example device 2
home/relay/esp32-002/command
home/relay/esp32-002/status

Multiple ESP32 setup

  • ESP32-001 ke code me DEVICE_ID = esp32-001 rakho.
  • ESP32-002 ke code me DEVICE_ID = esp32-002 rakho.
  • Dashboard ya terminal jis device ko control karega, usi device ke command topic par message publish karega.
  • Status dekhne ke liye same device ka status topic subscribe kiya jayega.

📋 Quick Test Commands

brew services start mosquitto
lsof -nP -iTCP:1883 -sTCP:LISTEN
nc -vz 192.168.1.6 1883
mosquitto_sub -h 192.168.1.6 -t "home/relay/esp32-001/#" -v
mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "ON"
mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "OFF"
mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "TOGGLE"
mosquitto_pub -h 192.168.1.6 -t "home/relay/esp32-001/command" -m "STATUS"
# Serial Monitor output WiFi Connected IP Address: 192.168.1.46 MQTT Connected Subscribed: home/relay/esp32-001/command Message received: ON Relay: ON Status published: home/relay/esp32-001/status