// Home Automation System - ESP32 on Wokwi (compatible with Arduino-ESP32 core 3.0+)
// Features:
// - Automatic Street Light: LDR darkness → LED ON
// - Smart Fan/AC: Temp > 30°C → Relay ON + Fan spins (servo via LEDC PWM)
// Pins match your diagram.json
#define LDR_PIN 34 // Analog (AO from photoresistor)
#define DHT_PIN 4 // Data from DHT22
#define LED_PIN 2 // Street light LED
#define RELAY_PIN 5 // Relay IN (active LOW)
#define SERVO_PIN 18 // Servo PWM signal
#define TEMP_THRESHOLD 30.0f // °C to turn fan on
#define LDR_DARK_THRESHOLD 1800 // Tune: higher = activates in darker conditions (0-4095)
#include <DHTesp.h> // Install via Wokwi Library Manager: "DHT sensor library for ESPx"
DHTesp dht;
const uint32_t PWM_FREQ = 50; // Servo standard: 50 Hz
const uint8_t PWM_RESOLUTION = 16; // 16-bit → good precision for pulse timing
bool fanIsOn = false;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\nHome Automation System started (LDR + DHT22 + LEDC PWM Servo - core 3.0+)");
// Outputs
pinMode(LED_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
digitalWrite(RELAY_PIN, HIGH); // Relay OFF (active LOW)
// DHT22 init
dht.setup(DHT_PIN, DHTesp::DHT22);
// LEDC PWM setup for servo (new API in core 3.0+)
// ledcAttach(pin, frequency, resolution) → auto channel assignment
ledcAttach(SERVO_PIN, PWM_FREQ, PWM_RESOLUTION);
setServoAngle(0); // Start stopped (0°)
delay(2000); // Stabilize sensors
}
void loop() {
// ────────────── Street Light (LDR) ──────────────
int ldrValue = analogRead(LDR_PIN); // ~0 bright sunlight, ~4095 very dark
bool isDark = (ldrValue > LDR_DARK_THRESHOLD);
digitalWrite(LED_PIN, isDark ? HIGH : LOW);
// ────────────── Temperature & Fan Control ──────────────
TempAndHumidity newData = dht.getTempAndHumidity();
if (dht.getStatus() == 0) { // 0 = ERROR_NONE
float temp = newData.temperature;
Serial.printf("Temp: %.1f °C | LDR: %d | Light: %s | Fan: %s\n",
temp, ldrValue,
isDark ? "ON" : "OFF",
fanIsOn ? "ON" : "OFF");
// Fan logic: relay powers servo + PWM moves it
if (temp > TEMP_THRESHOLD && !fanIsOn) {
Serial.println("→ High temp → Fan ON");
digitalWrite(RELAY_PIN, LOW); // Relay ON → 5V to servo
fanIsOn = true;
setServoAngle(90); // "Spin" (mid-speed simulation; adjust to 60-120)
}
else if (temp <= TEMP_THRESHOLD && fanIsOn) {
Serial.println("→ Temp OK → Fan OFF");
setServoAngle(0); // Stop
digitalWrite(RELAY_PIN, HIGH); // Relay OFF → no power to servo
fanIsOn = false;
}
} else {
Serial.println("DHT22 error: " + String(dht.getStatusString()));
}
delay(2000); // Refresh every 2s
}
// Helper: Set servo position 0–180°
// Maps angle to pulse: ~544µs (0°) to ~2400µs (180°) — typical for SG90
void setServoAngle(int angle) {
if (angle < 0) angle = 0;
if (angle > 180) angle = 180;
// Pulse width in µs
int pulse_us = map(angle, 0, 180, 544, 2400);
// Duty cycle for 16-bit resolution @ 50 Hz (20 ms period = 20000 µs)
uint32_t duty = (pulse_us * (1UL << PWM_RESOLUTION)) / 20000UL;
// New API: ledcWrite now uses pin (not channel)
ledcWrite(SERVO_PIN, duty);
}