🏠 Smart Home Automation System using ESP32
Build a fully web-controlled IoT home system with DHT22 sensors, PIR motion detection, OLED display, and an HTTP control panel. Fully testable in Wokwi — no hardware needed.
DHT22 Sensor
Real-time temperature & humidity monitoring with auto fan control logic.
PIR Motion Detection
Detects movement and automatically controls the smart light in AUTO mode.
Web Control Panel
Built-in HTTP server at port 80 — control everything from your browser.
OLED Display
128×64 SSD1306 screen shows live temp, humidity, light, fan & mode status.
Buzzer Alerts
Audible alarm triggers when temperature exceeds safe threshold.
AUTO / MANUAL Modes
Toggle between sensor-driven automation and full manual web control.
How the System Works
The ESP32 connects to WiFi and spins up a web server. Sensors are polled every 2 seconds — in AUTO mode, the firmware makes all decisions; in MANUAL mode, you're in charge via the web panel.
⚡ AUTO Mode
- Motion detected → Light ON
- No motion → Light OFF
- Temp > 28°C → Fan ON + Buzzer
- Temp ≤ 26°C → Fan OFF
🕹️ MANUAL Mode
- Toggle Light via web
- Toggle Fan via web
- Switch modes anytime
- Monitor sensor data live
📌 Pin Configuration
All connections for the ESP32 DevKit V1. Use these with the diagram.json below in Wokwi.
| Component | GPIO Pin | Notes |
|---|---|---|
| DHT22 Temp/Humidity | GPIO 15 | Data pin (SDA) |
| PIR Motion Sensor | GPIO 14 | Digital input (OUT) |
| Light LED | GPIO 26 | Yellow LED + 220Ω resistor |
| Fan LED | GPIO 27 | Blue LED + 220Ω resistor |
| Buzzer | GPIO 25 | Passive buzzer |
| OLED SDA | GPIO 21 | I2C Data (0x3C) |
| OLED SCL | GPIO 22 | I2C Clock |
🚀 Step-by-Step Instructions
Follow these steps to get the project running in Wokwi in under 5 minutes.
Open Wokwi Simulator
Go to wokwi.com/projects/new/esp32 and create a new ESP32 project.
Paste the Arduino Code
Copy the full .ino code from the section below and paste it into the Wokwi code editor (replacing the default sketch).
Replace diagram.json
Click the diagram.json tab in Wokwi, clear its contents, and paste the full diagram JSON from below to automatically place all components and wires.
Install Required Libraries
Click the ≡ menu → Library Manager and install: DHT sensor library, Adafruit GFX Library, and Adafruit SSD1306.
Start Simulation
Click the green ▶ Start Simulation button. Wait for the OLED to show "Smart Home" and the Serial Monitor to print the IP address.
Open the Web Control Panel
Open the Serial Monitor, copy the printed IP address, and paste it in the Wokwi browser tool to access the live control panel. 🎉
Interact with Sensors
Click the PIR sensor in the simulator to trigger motion. Drag the DHT22 temperature slider above 28°C to trigger the fan and buzzer automatically.
Wokwi-GUEST as the SSID (no password). This works automatically in the Wokwi simulator. For real hardware, replace with your own credentials.
💻 Full Arduino Code (.ino)
Complete, commented code ready to paste into Wokwi or Arduino IDE.
/* * ESP32 Smart Home Automation System * MakeMindz.com * Features: DHT22, PIR, LED Light, Fan LED, OLED, Web Server */ #include <WiFi.h> #include <WebServer.h> #include <DHT.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // WiFi Credentials (for Wokwi simulation) const char* ssid = "Wokwi-GUEST"; const char* password = ""; // Pin Definitions #define DHT_PIN 15 #define PIR_PIN 14 #define LIGHT_PIN 26 #define FAN_PIN 27 #define BUZZER_PIN 25 #define DHT_TYPE DHT22 DHT dht(DHT_PIN, DHT_TYPE); // OLED Setup (128x64 SSD1306 via I2C) #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); WebServer server(80); // State variables float temperature = 0; float humidity = 0; bool lightStatus = false; bool fanStatus = false; bool motionDetected = false; bool autoMode = true; unsigned long lastSensorRead = 0; const long sensorInterval = 2000; void setup() { Serial.begin(115200); pinMode(PIR_PIN, INPUT); pinMode(LIGHT_PIN, OUTPUT); pinMode(FAN_PIN, OUTPUT); pinMode(BUZZER_PIN, OUTPUT); dht.begin(); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for(;;); } display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println("Smart Home"); display.println("Initializing..."); display.display(); delay(2000); WiFi.begin(ssid, password); Serial.print("Connecting to WiFi"); display.clearDisplay(); display.setCursor(0, 0); display.println("Connecting WiFi..."); display.display(); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); server.on("/", handleRoot); server.on("/light/on", handleLightOn); server.on("/light/off", handleLightOff); server.on("/fan/on", handleFanOn); server.on("/fan/off", handleFanOff); server.on("/mode/auto", handleAutoMode); server.on("/mode/manual", handleManualMode); server.on("/status", handleStatus); server.begin(); Serial.println("HTTP server started"); updateDisplay(); } void loop() { server.handleClient(); unsigned long now = millis(); if (now - lastSensorRead >= sensorInterval) { lastSensorRead = now; readSensors(); if (autoMode) autoControl(); updateDisplay(); } } void readSensors() { temperature = dht.readTemperature(); humidity = dht.readHumidity(); motionDetected = digitalRead(PIR_PIN); if (isnan(temperature) || isnan(humidity)) { temperature = 0; humidity = 0; } } void autoControl() { // Light: motion-based if (motionDetected && !lightStatus) { lightStatus = true; digitalWrite(LIGHT_PIN, HIGH); } else if (!motionDetected && lightStatus) { lightStatus = false; digitalWrite(LIGHT_PIN, LOW); } // Fan: temperature-based if (temperature > 28 && !fanStatus) { fanStatus = true; digitalWrite(FAN_PIN, HIGH); tone(BUZZER_PIN, 1000, 200); // alert beep } else if (temperature <= 26 && fanStatus) { fanStatus = false; digitalWrite(FAN_PIN, LOW); } } void updateDisplay() { display.clearDisplay(); display.setCursor(0, 0); display.setTextSize(1); display.println("SMART HOME"); display.drawLine(0, 10, 128, 10, SSD1306_WHITE); display.setCursor(0, 14); display.print("Temp: "); display.print(temperature, 1); display.println(" C"); display.setCursor(0, 24); display.print("Humid: "); display.print(humidity, 1); display.println(" %"); display.setCursor(0, 34); display.print("Light: "); display.println(lightStatus ? "ON" : "OFF"); display.setCursor(0, 44); display.print("Fan: "); display.println(fanStatus ? "ON" : "OFF"); display.setCursor(0, 54); display.print("Mode: "); display.println(autoMode ? "AUTO" : "MANUAL"); display.display(); } /* -------- Web Handlers -------- */ void handleRoot() { String html = "<!DOCTYPE html><html><head>"; html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>"; html += "<style>body{font-family:Arial;text-align:center;background:#f0f0f0;padding:20px}"; html += ".container{max-width:500px;margin:0 auto;background:white;padding:20px;border-radius:10px}"; html += ".sensor{background:#e3f2fd;padding:15px;margin:10px 0;border-radius:5px}"; html += ".button{display:inline-block;padding:15px 30px;margin:5px;font-size:16px;cursor:pointer;"; html += "border:none;border-radius:5px;color:white;text-decoration:none}"; html += ".on{background:#4CAF50}.off{background:#f44336}.mode{background:#2196F3}</style>"; html += "</head><body><div class='container'><h1>🏠 Smart Home Control</h1>"; html += "<div class='sensor'><h3>📊 Sensors</h3>"; html += "<p>🌡️ Temp: <b>" + String(temperature,1) + " °C</b></p>"; html += "<p>💧 Humidity: <b>" + String(humidity,1) + " %</b></p>"; html += "<p>🚶 Motion: <b>" + String(motionDetected?"Detected":"None") + "</b></p></div>"; html += "<div class='sensor'><h3>💡 Light — " + String(lightStatus?"ON":"OFF") + "</h3>"; html += "<a href='/light/on' class='button on'>Turn ON</a>"; html += "<a href='/light/off' class='button off'>Turn OFF</a></div>"; html += "<div class='sensor'><h3>🌀 Fan — " + String(fanStatus?"ON":"OFF") + "</h3>"; html += "<a href='/fan/on' class='button on'>Turn ON</a>"; html += "<a href='/fan/off' class='button off'>Turn OFF</a></div>"; html += "<div class='sensor'><h3>⚙️ Mode — " + String(autoMode?"AUTO":"MANUAL") + "</h3>"; html += "<a href='/mode/auto' class='button mode'>AUTO</a>"; html += "<a href='/mode/manual' class='button mode'>MANUAL</a></div>"; html += "<p style='font-size:12px;color:#999'>IP: " + WiFi.localIP().toString() + "</p>"; html += "</div></body></html>"; server.send(200, "text/html", html); } void handleLightOn() { lightStatus=true; digitalWrite(LIGHT_PIN,HIGH); server.sendHeader("Location","/"); server.send(303); } void handleLightOff() { lightStatus=false; digitalWrite(LIGHT_PIN,LOW); server.sendHeader("Location","/"); server.send(303); } void handleFanOn() { fanStatus=true; digitalWrite(FAN_PIN,HIGH); server.sendHeader("Location","/"); server.send(303); } void handleFanOff() { fanStatus=false; digitalWrite(FAN_PIN,LOW); server.sendHeader("Location","/"); server.send(303); } void handleAutoMode() { autoMode=true; server.sendHeader("Location","/"); server.send(303); } void handleManualMode() { autoMode=false; server.sendHeader("Location","/"); server.send(303); } void handleStatus() { String json = "{"; json += "\"temperature\":" + String(temperature,1) + ","; json += "\"humidity\":" + String(humidity,1) + ","; json += "\"motion\":" + String(motionDetected?"true":"false") + ","; json += "\"light\":" + String(lightStatus?"true":"false") + ","; json += "\"fan\":" + String(fanStatus?"true":"false") + ","; json += "\"mode\":\"" + String(autoMode?"auto":"manual") + "\""; json += "}"; server.send(200, "application/json", json); }
📐 diagram.json
Paste this into the diagram.json tab in Wokwi to auto-wire all components — ESP32, DHT22, PIR, LEDs, buzzer, and OLED.
{
"version": 1,
"author": "ESP32 Smart Home Automation — MakeMindz.com",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-esp32-devkit-v1", "id": "esp", "top": 0, "left": 0, "attrs": {} },
{ "type": "wokwi-dht22", "id": "dht1", "top": -67.2, "left": 105.6, "attrs": { "temperature": "8.7", "humidity": "62.5" } },
{ "type": "wokwi-pir-motion-sensor","id": "pir1","top": -105.49,"left": 230.11, "attrs": {} },
{ "type": "wokwi-led", "id": "led1", "top": -180, "left": 340, "attrs": { "color": "yellow", "lightColor": "yellow" } },
{ "type": "wokwi-resistor", "id": "r1", "top": -120, "left": 345, "rotate": 90, "attrs": { "value": "220" } },
{ "type": "wokwi-led", "id": "led2", "top": -205.2, "left": 378.2, "attrs": { "color": "blue", "lightColor": "blue" } },
{ "type": "wokwi-resistor", "id": "r2", "top": -120, "left": 405, "rotate": 90, "attrs": { "value": "220" } },
{ "type": "wokwi-buzzer", "id": "bz1", "top": -120, "left": 480, "attrs": { "volume": "0.5" } },
{ "type": "wokwi-ssd1306", "id": "oled1","top": 121.9, "left": 241.9, "attrs": { "i2cAddress": "0x3C" } }
],
"connections": [
[ "esp:TX0", "$serialMonitor:RX", "", [] ],
[ "esp:RX0", "$serialMonitor:TX", "", [] ],
[ "dht1:VCC", "esp:3V3", "red", ["v0"] ],
[ "dht1:GND", "esp:GND.1", "black", ["v0"] ],
[ "dht1:SDA", "esp:D15", "green", ["v0"] ],
[ "pir1:VCC", "esp:3V3", "red", ["v0"] ],
[ "pir1:GND", "esp:GND.1", "black", ["v0"] ],
[ "pir1:OUT", "esp:D14", "orange", ["v0"] ],
[ "led1:A", "esp:D26", "yellow", ["v-9.6","h-48"] ],
[ "led1:C", "r1:1", "yellow", ["v0"] ],
[ "r1:2", "esp:GND.2", "black", ["h0"] ],
[ "led2:A", "esp:D27", "blue", ["v-9.6","h-96"] ],
[ "led2:C", "r2:1", "blue", ["v0"] ],
[ "r2:2", "esp:GND.2", "black", ["h0"] ],
[ "bz1:1", "esp:D25", "green", ["v0"] ],
[ "bz1:2", "esp:GND.2", "black", ["v0"] ],
[ "oled1:VCC", "esp:3V3", "red", ["h0"] ],
[ "oled1:GND", "esp:GND.2", "black", ["h0"] ],
[ "oled1:SDA", "esp:D21", "blue", ["h0"] ],
[ "oled1:SCL", "esp:D22", "yellow", ["h0"] ]
],
"dependencies": {}
}
▶ Try It Now in Wokwi
No hardware? No problem. Simulate the full project in your browser — interact with sensors, open the web panel, and see the OLED update live.
🚀 Launch Wokwi Simulator📚 What You'll Learn
This project is a complete IoT curriculum in a single sketch. By building it, you'll gain hands-on experience with:
🛠️ Advanced Improvements to Try
Once you've got the base project running, extend it with these ideas to level up your skills:
🔗 More ESP32 Projects on MakeMindz
IoT Weather Station with Cloud Integration
Log sensor data to the cloud in real time.
ESP32 Web Server for Remote Device Control
Control any GPIO pin from your browser.
MQTT-Based Temperature & Humidity Monitor
Publish sensor data with the MQTT protocol.
ESP32-CAM Security Camera with Motion Detection
Stream live video from your ESP32 camera module.
Smart Irrigation System with Soil Moisture Sensor
Automate plant watering based on soil moisture.
OLED Display Beginner Guide
How to connect and display text on OLED with ESP32.
Comments
Post a Comment