This project demonstrates a comprehensive home automation system using ESP32 microcontroller that can control lighting, monitor security, track environmental conditions, and manage appliances remotely via a mobile app.
| Category | Cost Range (LKR) |
|---|---|
| Main Controller | 2,500 - 3,500 |
| Sensors | 1,730 - 2,500 |
| Output Devices | 1,800 - 3,300 |
| Additional Components | 1,800 - 3,600 |
| Total Project Cost | 7,830 - 12,900 |
Note: Prices may vary based on supplier and quality. Budget suitable for student projects.
PIR Motion Sensor:
- VCC → 3.3V
- GND → GND
- OUT → GPIO 13
DHT22 Temperature Sensor:
- VCC → 3.3V
- GND → GND
- DATA → GPIO 14
LDR (Light Sensor):
- One end → 3.3V
- Other end → GPIO 35 (ADC pin)
- 10kΩ resistor between GPIO 35 and GNDRelay Module:
- VCC → 5V
- GND → GND
- IN1 → GPIO 25 (Light Control)
- IN2 → GPIO 26 (Fan Control)
- IN3 → GPIO 27 (Heater Control)
- IN4 → GPIO 32 (Door Lock)
LED Strip:
- Connect through relay module for switching
- Ensure proper voltage rating
Servo Motor:
- VCC → 5V
- GND → GND
- Signal → GPIO 18
Buzzer:
- Positive → GPIO 19
- Negative → GNDhttps://dl.espressif.com/dl/package_esp32_index.jsonInstall these libraries via Library Manager:
#include <WiFi.h>
#include <WebServer.h>
#include <DHT.h>
#include <Servo.h>
#include <ArduinoJson.h>
// Network credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// Pin definitions
#define PIR_PIN 13
#define DHT_PIN 14
#define LDR_PIN 35
#define RELAY1_PIN 25 // Light
#define RELAY2_PIN 26 // Fan
#define RELAY3_PIN 27 // Heater
#define RELAY4_PIN 32 // Door Lock
#define SERVO_PIN 18
#define BUZZER_PIN 19
// Initialize components
DHT dht(DHT_PIN, DHT22);
Servo doorServo;
WebServer server(80);
// Global variables
bool lightState = false;
bool fanState = false;
bool heaterState = false;
bool doorLocked = true;
bool motionDetected = false;
float temperature = 0;
float humidity = 0;
int lightLevel = 0;
void setup() {
Serial.begin(115200);
// Initialize pins
pinMode(PIR_PIN, INPUT);
pinMode(LDR_PIN, INPUT);
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
pinMode(RELAY3_PIN, OUTPUT);
pinMode(RELAY4_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Initialize components
dht.begin();
doorServo.attach(SERVO_PIN);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("WiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Setup web server routes
setupServerRoutes();
server.begin();
}
void loop() {
server.handleClient();
// Read sensors
readSensors();
// Check for motion
checkMotion();
// Automatic light control based on ambient light
autoLightControl();
delay(1000);
}
void readSensors() {
temperature = dht.readTemperature();
humidity = dht.readHumidity();
lightLevel = analogRead(LDR_PIN);
motionDetected = digitalRead(PIR_PIN);
}
void checkMotion() {
if (motionDetected) {
Serial.println("Motion detected!");
// Trigger security alert
securityAlert();
}
}
void autoLightControl() {
if (lightLevel < 500 && !lightState) {
// Turn on light automatically in dark conditions
digitalWrite(RELAY1_PIN, HIGH);
lightState = true;
}
}
void securityAlert() {
// Sound buzzer
digitalWrite(BUZZER_PIN, HIGH);
delay(1000);
digitalWrite(BUZZER_PIN, LOW);
// Send notification (implement mobile app notification)
sendNotification("Motion detected in your home!");
}
void setupServerRoutes() {
// Main dashboard
server.on("/", handleRoot);
// API endpoints
server.on("/api/status", handleStatus);
server.on("/api/control", handleControl);
server.on("/api/sensors", handleSensors);
}
void handleRoot() {
String html = generateDashboard();
server.send(200, "text/html", html);
}
void handleStatus() {
StaticJsonDocument<200> doc;
doc["light"] = lightState;
doc["fan"] = fanState;
doc["heater"] = heaterState;
doc["door"] = doorLocked;
doc["motion"] = motionDetected;
String response;
serializeJson(doc, response);
server.send(200, "application/json", response);
}
void handleControl() {
if (server.hasArg("device") && server.hasArg("state")) {
String device = server.arg("device");
bool state = server.arg("state") == "true";
if (device == "light") {
digitalWrite(RELAY1_PIN, state ? HIGH : LOW);
lightState = state;
} else if (device == "fan") {
digitalWrite(RELAY2_PIN, state ? HIGH : LOW);
fanState = state;
} else if (device == "heater") {
digitalWrite(RELAY3_PIN, state ? HIGH : LOW);
heaterState = state;
} else if (device == "door") {
doorServo.write(state ? 0 : 90);
doorLocked = state;
}
server.send(200, "text/plain", "OK");
} else {
server.send(400, "text/plain", "Missing parameters");
}
}
void handleSensors() {
StaticJsonDocument<200> doc;
doc["temperature"] = temperature;
doc["humidity"] = humidity;
doc["light_level"] = lightLevel;
doc["motion"] = motionDetected;
String response;
serializeJson(doc, response);
server.send(200, "application/json", response);
}
String generateDashboard() {
String html = R"(
<!DOCTYPE html>
<html>
<head>
<title>Smart Home Dashboard</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: Arial, sans-serif; margin: 20px; background: #f0f0f0; }
.container { max-width: 800px; margin: 0 auto; }
.card { background: white; padding: 20px; margin: 10px 0; border-radius: 10px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
.sensor-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; }
.control-btn { padding: 10px 20px; margin: 5px; border: none; border-radius: 5px; cursor: pointer; }
.on { background: #4CAF50; color: white; }
.off { background: #f44336; color: white; }
.sensor-value { font-size: 24px; font-weight: bold; color: #333; }
.sensor-label { color: #666; margin-bottom: 5px; }
h1 { color: #333; text-align: center; }
h2 { color: #555; border-bottom: 2px solid #ddd; padding-bottom: 10px; }
</style>
</head>
<body>
<div class="container">
<h1>🏠 Smart Home Dashboard</h1>
<div class="card">
<h2>📊 Sensor Readings</h2>
<div class="sensor-grid">
<div>
<div class="sensor-label">Temperature</div>
<div class="sensor-value" id="temp">--°C</div>
</div>
<div>
<div class="sensor-label">Humidity</div>
<div class="sensor-value" id="humidity">--%</div>
</div>
<div>
<div class="sensor-label">Light Level</div>
<div class="sensor-value" id="light">--</div>
</div>
<div>
<div class="sensor-label">Motion</div>
<div class="sensor-value" id="motion">--</div>
</div>
</div>
</div>
<div class="card">
<h2>🎛️ Device Control</h2>
<button class="control-btn" id="lightBtn" onclick="toggleDevice('light')">💡 Light</button>
<button class="control-btn" id="fanBtn" onclick="toggleDevice('fan')">🌀 Fan</button>
<button class="control-btn" id="heaterBtn" onclick="toggleDevice('heater')">🔥 Heater</button>
<button class="control-btn" id="doorBtn" onclick="toggleDevice('door')">🚪 Door Lock</button>
</div>
</div>
<script>
function updateSensors() {
fetch('/api/sensors')
.then(response => response.json())
.then(data => {
document.getElementById('temp').textContent = data.temperature + '°C';
document.getElementById('humidity').textContent = data.humidity + '%';
document.getElementById('light').textContent = data.light_level;
document.getElementById('motion').textContent = data.motion ? 'Detected' : 'None';
});
}
function updateStatus() {
fetch('/api/status')
.then(response => response.json())
.then(data => {
updateButtonState('lightBtn', data.light);
updateButtonState('fanBtn', data.fan);
updateButtonState('heaterBtn', data.heater);
updateButtonState('doorBtn', data.door);
});
}
function updateButtonState(btnId, state) {
const btn = document.getElementById(btnId);
btn.className = 'control-btn ' + (state ? 'on' : 'off');
}
function toggleDevice(device) {
fetch('/api/status')
.then(response => response.json())
.then(data => {
const currentState = data[device];
const newState = !currentState;
fetch(`/api/control?device=${device}&state=${newState}`)
.then(() => updateStatus());
});
}
// Update data every 2 seconds
setInterval(() => {
updateSensors();
updateStatus();
}, 2000);
// Initial load
updateSensors();
updateStatus();
</script>
</body>
</html>
)";
return html;
}
void sendNotification(String message) {
// Implement notification system
// Can use Firebase, Pushover, or custom notification service
Serial.println("Notification: " + message);
}For custom mobile app development with professional features.
WiFi - Built-in
WebServer - Built-in
DHT sensor library - by Adafruit
Servo - Built-in
ArduinoJson - by Benoit Blanchon
PubSubClient - by Nick O'Leary
Blynk - by BlynkESP32 Pin Connections:
=====================
GPIO 13 ← PIR Motion Sensor (OUT)
GPIO 14 ← DHT22 Temperature Sensor (DATA)
GPIO 35 ← LDR Light Sensor (analog)
GPIO 25 → Relay 1 (Light Control)
GPIO 26 → Relay 2 (Fan Control)
GPIO 27 → Relay 3 (Heater Control)
GPIO 32 → Relay 4 (Door Lock)
GPIO 18 → Servo Motor (Signal)
GPIO 19 → Buzzer (Positive)
Power Connections:
=================
3.3V → PIR VCC, DHT22 VCC, LDR (one end)
5V → Relay VCC, Servo VCC
GND → All component groundsThis smart home automation prototype provides a comprehensive foundation for understanding IoT concepts, embedded programming, and mobile app development. The project is designed to be educational while producing a functional system that can be extended and improved.
The estimated budget of LKR 7,830 - 12,900 makes this project accessible to students while providing hands-on experience with real-world technologies. The modular design allows for incremental development and testing.
Key Learning Outcomes:
Project Deliverables:
This project serves as an excellent foundation for understanding modern IoT systems and can be expanded into more complex automation solutions.
Document Version: 1.0
Last Updated: July 2025
Target Audience: Engineering Students, Sri Lanka