// Home Automation for ESP32 (Wokwi Compatible)
// PWM via analogWrite for simulation, LCD 16x2 I2C
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#define DHT_TYPE DHT22
// Pin mapping
const int relayPinR1 = 19;
const int relayPinR2 = 18;
const int relayPinR3 = 17;
const int relayPinR4 = 16;
const int pirPin = 33;
const int ldrPin = 32;
const int dhtPin = 4;
const int sw1Pin = 35;
const int sw2Pin = 34;
const int motorPwmPin = 25;
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(dhtPin, DHT_TYPE);
// States
bool relayStateR1 = false, relayStateR2 = false, relayStateR3 = false, relayStateR4 = false;
float currentTemp = NAN, currentHumi = NAN;
int ldrValue = 0;
bool pirState = false;
// Motor PWM
enum MotorMode { MOTOR_OFF = 0, MOTOR_LOW, MOTOR_MEDIUM, MOTOR_HIGH };
int motorPwmValues[] = {0, 85, 170, 255};
MotorMode currentMotorMode = MOTOR_OFF;
const int lightThreshold = 2000;
const bool relayActiveHigh = true;
static bool sw1Prev = LOW;
static bool sw2Prev = LOW;
void setup() {
Serial.begin(115200);
pinMode(relayPinR1, OUTPUT);
pinMode(relayPinR2, OUTPUT);
pinMode(relayPinR3, OUTPUT);
pinMode(relayPinR4, OUTPUT);
pinMode(pirPin, INPUT);
pinMode(ldrPin, INPUT);
pinMode(sw1Pin, INPUT);
pinMode(sw2Pin, INPUT);
pinMode(motorPwmPin, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Home Automation");
lcd.setCursor(0, 1);
lcd.print("Welcome...");
delay(1000);
dht.begin();
currentTemp = dht.readTemperature();
currentHumi = dht.readHumidity();
analogWrite(motorPwmPin, motorPwmValues[MOTOR_OFF]);
}
void loop() {
// --- Read Sensors ---
ldrValue = analogRead(ldrPin);
bool pirReading = digitalRead(pirPin);
bool sw1Reading = digitalRead(sw1Pin);
bool sw2Reading = digitalRead(sw2Pin);
float tempReading = dht.readTemperature();
float humiReading = dht.readHumidity();
if (!isnan(tempReading)) currentTemp = tempReading;
if (!isnan(humiReading)) currentHumi = humiReading;
// --- Outdoor Light Automation ---
if (ldrValue >= lightThreshold) {
relayStateR1 = false;
digitalWrite(relayPinR1, LOW);
}
else{
relayStateR1 = true;
digitalWrite(relayPinR1, HIGH);
}
// --- Washroom PIR Automation (counter-free, toggle) ---
if (pirReading && !pirState) {
pirState = true;
relayStateR2 = true;
digitalWrite(relayPinR2, relayActiveHigh ? HIGH : LOW);
} else if (!pirReading) {
pirState = false;
relayStateR2 = false;
digitalWrite(relayPinR2, relayActiveHigh ? LOW : HIGH);
}
// --- Hall/Bedroom Manual Switches for Slide Switches ---
// Serial.print("sw1Reading:"); Serial.print(sw1Reading);
relayStateR3 = sw1Reading; // relay mirrors switch 1
digitalWrite(relayPinR3, sw1Reading);
// Serial.print("sw2Reading:"); Serial.print(sw2Reading);
relayStateR4 = sw2Reading; // relay mirrors switch 2
digitalWrite(relayPinR4, sw2Reading);
// --- Temperature Alerts ---
if (!isnan(currentTemp) && currentTemp > 40.0) {
Serial.println("ALERT: Temperature exceeds 40C!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("!!! TEMP ALERT !!!");
lcd.setCursor(0, 1);
lcd.print("T:"); lcd.print(currentTemp, 1); lcd.print("C");
delay(1200);
}
// --- Fan / Motor Control ---
if (!isnan(currentTemp) && currentTemp > 30 && currentMotorMode == MOTOR_OFF) {
currentMotorMode = MOTOR_MEDIUM;
analogWrite(motorPwmPin, motorPwmValues[currentMotorMode]);
}
// --- Display on LCD ---
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("L1"); lcd.print(relayStateR1 ? "* " : "- ");
lcd.print("L2"); lcd.print(relayStateR2 ? "* " : "- ");
lcd.print("L3"); lcd.print(relayStateR3 ? "* " : "- ");
lcd.print("L4"); lcd.print(relayStateR4 ? "* " : "-");
lcd.setCursor(0, 1);
lcd.print("T:"); lcd.print(currentTemp, 0);
lcd.print("C L:"); lcd.print(ldrValue >= lightThreshold ? "LIT" : "DRK");
// --- Print Serial Status ---
Serial.print("LDR:"); Serial.print(ldrValue);
Serial.print(" | PIR:"); Serial.print(pirReading);
Serial.print(" | DHT T:"); Serial.print(currentTemp);
Serial.print("C H:"); Serial.print(currentHumi);
Serial.print(" | sw1:"); Serial.print(sw1Reading);
Serial.print(" sw2:"); Serial.print(sw2Reading);
Serial.print(" | Relay R1:"); Serial.print(relayStateR1 ? "ON" : "OFF");
Serial.print(" R2:"); Serial.print(relayStateR2 ? "ON" : "OFF");
Serial.print(" R3:"); Serial.print(relayStateR3 ? "ON" : "OFF");
Serial.print(" R4:"); Serial.println(relayStateR4 ? "ON" : "OFF");
delay(200); // keep loop stable
}