/*
* VOICE-CONTROLLED HOME ASSISTANT - ESP32
*
* Features:
* - Voice command recognition via serial (simulated)
* - Control multiple home devices (lights, fan, AC, door)
* - Temperature and humidity monitoring (DHT11)
* - LCD display for status
* - RGB LED for visual feedback
* - Buzzer for audio feedback
* - Real-time voice command processing
*
* Voice Commands:
* - "turn on light" / "turn off light"
* - "turn on fan" / "turn off fan"
* - "turn on ac" / "turn off ac"
* - "open door" / "close door"
* - "show temperature"
* - "show humidity"
* - "turn on all" / "turn off all"
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
// Pin Definitions
#define DHT_PIN 15
#define DHT_TYPE DHT22
#define LIGHT_PIN 13
#define FAN_PIN 12
#define AC_PIN 14
#define DOOR_SERVO_PIN 27
#define RGB_RED 25
#define RGB_GREEN 26
#define RGB_BLUE 33
#define BUZZER_PIN 32
#define MIC_PIN 34 // Analog pin for microphone simulation
// I2C LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(DHT_PIN, DHT_TYPE);
// Device States
bool lightState = false;
bool fanState = false;
bool acState = false;
bool doorState = false; // false = closed, true = open
float temperature = 0;
float humidity = 0;
// Voice command buffer
String voiceCommand = "";
unsigned long lastCommandTime = 0;
// Function prototypes
void processVoiceCommand(String command);
void controlLight(bool state);
void controlFan(bool state);
void controlAC(bool state);
void controlDoor(bool state);
void readSensors();
void updateLCD();
void setRGB(int r, int g, int b);
void playConfirmationBeep();
void playErrorBeep();
void printStatus();
void setup() {
Serial.begin(115200);
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Voice Home");
lcd.setCursor(0, 1);
lcd.print("Assistant");
// Initialize DHT sensor
dht.begin();
// Initialize pins
pinMode(LIGHT_PIN, OUTPUT);
pinMode(FAN_PIN, OUTPUT);
pinMode(AC_PIN, OUTPUT);
pinMode(DOOR_SERVO_PIN, OUTPUT);
pinMode(RGB_RED, OUTPUT);
pinMode(RGB_GREEN, OUTPUT);
pinMode(RGB_BLUE, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(MIC_PIN, INPUT);
// Initial states
digitalWrite(LIGHT_PIN, LOW);
digitalWrite(FAN_PIN, LOW);
digitalWrite(AC_PIN, LOW);
digitalWrite(DOOR_SERVO_PIN, LOW);
setRGB(0, 0, 255); // Blue - Ready
playConfirmationBeep();
delay(2000);
Serial.println("\n╔═══════════════════════════════════════╗");
Serial.println("║ VOICE-CONTROLLED HOME ASSISTANT ║");
Serial.println("╚═══════════════════════════════════════╝\n");
Serial.println("System Ready! Listening for commands...");
Serial.println("\nAvailable Commands:");
Serial.println(" - turn on/off light");
Serial.println(" - turn on/off fan");
Serial.println(" - turn on/off ac");
Serial.println(" - open/close door");
Serial.println(" - show temperature");
Serial.println(" - show humidity");
Serial.println(" - turn on/off all");
Serial.println(" - status\n");
lcd.clear();
lcd.print("Ready!");
setRGB(0, 255, 0); // Green - Ready
}
void loop() {
// Read sensors periodically
static unsigned long lastSensorRead = 0;
if (millis() - lastSensorRead > 2000) {
readSensors();
lastSensorRead = millis();
}
// Check for voice commands via Serial
if (Serial.available() > 0) {
char c = Serial.read();
if (c == '\n' || c == '\r') {
if (voiceCommand.length() > 0) {
voiceCommand.toLowerCase();
voiceCommand.trim();
Serial.println("\n🎤 Voice Command: " + voiceCommand);
setRGB(255, 255, 0); // Yellow - Processing
processVoiceCommand(voiceCommand);
voiceCommand = "";
delay(500);
setRGB(0, 255, 0); // Green - Ready
}
} else {
voiceCommand += c;
}
}
// Update LCD with current status
static unsigned long lastLCDUpdate = 0;
if (millis() - lastLCDUpdate > 3000) {
updateLCD();
lastLCDUpdate = millis();
}
delay(50);
}
void processVoiceCommand(String command) {
bool commandRecognized = true;
// Light commands
if (command.indexOf("turn on light") >= 0 || command.indexOf("light on") >= 0) {
controlLight(true);
lcd.clear();
lcd.print("Light: ON");
}
else if (command.indexOf("turn off light") >= 0 || command.indexOf("light off") >= 0) {
controlLight(false);
lcd.clear();
lcd.print("Light: OFF");
}
// Fan commands
else if (command.indexOf("turn on fan") >= 0 || command.indexOf("fan on") >= 0) {
controlFan(true);
lcd.clear();
lcd.print("Fan: ON");
}
else if (command.indexOf("turn off fan") >= 0 || command.indexOf("fan off") >= 0) {
controlFan(false);
lcd.clear();
lcd.print("Fan: OFF");
}
// AC commands
else if (command.indexOf("turn on ac") >= 0 || command.indexOf("ac on") >= 0 ||
command.indexOf("turn on air") >= 0) {
controlAC(true);
lcd.clear();
lcd.print("AC: ON");
}
else if (command.indexOf("turn off ac") >= 0 || command.indexOf("ac off") >= 0 ||
command.indexOf("turn off air") >= 0) {
controlAC(false);
lcd.clear();
lcd.print("AC: OFF");
}
// Door commands
else if (command.indexOf("open door") >= 0 || command.indexOf("door open") >= 0) {
controlDoor(true);
lcd.clear();
lcd.print("Door: OPEN");
}
else if (command.indexOf("close door") >= 0 || command.indexOf("door close") >= 0) {
controlDoor(false);
lcd.clear();
lcd.print("Door: CLOSED");
}
// Sensor queries
else if (command.indexOf("temperature") >= 0 || command.indexOf("temp") >= 0) {
lcd.clear();
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print("C");
Serial.println("Temperature: " + String(temperature) + "°C");
playConfirmationBeep();
}
else if (command.indexOf("humidity") >= 0) {
lcd.clear();
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print("%");
Serial.println("Humidity: " + String(humidity) + "%");
playConfirmationBeep();
}
// All devices control
else if (command.indexOf("turn on all") >= 0 || command.indexOf("all on") >= 0) {
controlLight(true);
controlFan(true);
controlAC(true);
lcd.clear();
lcd.print("All Devices: ON");
}
else if (command.indexOf("turn off all") >= 0 || command.indexOf("all off") >= 0) {
controlLight(false);
controlFan(false);
controlAC(false);
lcd.clear();
lcd.print("All Devices: OFF");
}
// Status query
else if (command.indexOf("status") >= 0) {
printStatus();
commandRecognized = true;
}
else {
commandRecognized = false;
Serial.println("❌ Command not recognized!");
lcd.clear();
lcd.print("Unknown Cmd");
playErrorBeep();
}
if (commandRecognized && command.indexOf("temperature") < 0 &&
command.indexOf("humidity") < 0 && command.indexOf("status") < 0) {
playConfirmationBeep();
Serial.println("✅ Command executed!");
}
delay(2000);
}
void controlLight(bool state) {
lightState = state;
digitalWrite(LIGHT_PIN, state ? HIGH : LOW);
Serial.println("💡 Light: " + String(state ? "ON" : "OFF"));
}
void controlFan(bool state) {
fanState = state;
digitalWrite(FAN_PIN, state ? HIGH : LOW);
Serial.println("🌀 Fan: " + String(state ? "ON" : "OFF"));
}
void controlAC(bool state) {
acState = state;
digitalWrite(AC_PIN, state ? HIGH : LOW);
Serial.println("❄️ AC: " + String(state ? "ON" : "OFF"));
}
void controlDoor(bool state) {
doorState = state;
// Simulate servo movement
if (state) {
// Open door (90 degrees)
for (int i = 0; i <= 90; i += 5) {
analogWrite(DOOR_SERVO_PIN, map(i, 0, 180, 0, 255));
delay(15);
}
} else {
// Close door (0 degrees)
for (int i = 90; i >= 0; i -= 5) {
analogWrite(DOOR_SERVO_PIN, map(i, 0, 180, 0, 255));
delay(15);
}
}
Serial.println("🚪 Door: " + String(state ? "OPEN" : "CLOSED"));
}
void readSensors() {
humidity = dht.readHumidity();
temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("⚠️ Failed to read from DHT sensor!");
// Use simulated values for Wokwi
temperature = 25.0 + random(-5, 5);
humidity = 60.0 + random(-10, 10);
}
}
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temperature, 1);
lcd.print("C H:");
lcd.print(humidity, 0);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("L:");
lcd.print(lightState ? "1" : "0");
lcd.print(" F:");
lcd.print(fanState ? "1" : "0");
lcd.print(" A:");
lcd.print(acState ? "1" : "0");
lcd.print(" D:");
lcd.print(doorState ? "O" : "C");
}
void setRGB(int r, int g, int b) {
analogWrite(RGB_RED, r);
analogWrite(RGB_GREEN, g);
analogWrite(RGB_BLUE, b);
}
void playConfirmationBeep() {
tone(BUZZER_PIN, 1000, 100);
delay(150);
tone(BUZZER_PIN, 1500, 100);
}
void playErrorBeep() {
for (int i = 0; i < 3; i++) {
tone(BUZZER_PIN, 500, 100);
delay(150);
}
}
void printStatus() {
Serial.println("\n╔════════════ SYSTEM STATUS ════════════╗");
Serial.println("║ Light: " + String(lightState ? "ON " : "OFF") + " ║");
Serial.println("║ Fan: " + String(fanState ? "ON " : "OFF") + " ║");
Serial.println("║ AC: " + String(acState ? "ON " : "OFF") + " ║");
Serial.println("║ Door: " + String(doorState ? "OPEN " : "CLOSED") + " ║");
Serial.println("║ ║");
Serial.println("║ Temperature: " + String(temperature) + "°C ║");
Serial.println("║ Humidity: " + String(humidity) + "% ║");
Serial.println("╚═══════════════════════════════════════╝\n");
lcd.clear();
lcd.print("Status Shown");
playConfirmationBeep();
}