#include <Arduino.h>
#include <DHT.h>
#define DHT_PIN 4 // DHT Sensor Pin
#define LED_R 16 // Red LED Pin
#define LED_G 17 // Green LED Pin
#define LED_B 18 // Blue LED Pin
#define BUZZER 19 // Buzzer Pin
#define SWITCH 21 // Slide Switch Pin
DHT dht(DHT_PIN, DHT22);
// Struct to hold sensor data
struct SensorData {
float temperature;
float humidity;
};
bool isAsleep = false; // State to track sleep mode
unsigned long lastSwitchTime = 0; // To debounce switch press
const unsigned long debounceDelay = 200; // Debounce time (ms)
// RTC variable to track sleep state across wakeups
RTC_DATA_ATTR bool wakeUpFlag = false;
// Function Prototypes
SensorData readDHTData();
void updateLED(SensorData data);
void handleBuzzer(SensorData data);
void setColor(int red, int green, int blue);
void IRAM_ATTR handleSleepWakeup(); // Interrupt function
void goToSleep(); // Deep sleep function
void wakeUp(); // Wakeup function
void checkWakeupCause(); // Check wakeup cause
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(LED_R, OUTPUT);
pinMode(LED_G, OUTPUT);
pinMode(LED_B, OUTPUT);
pinMode(BUZZER, OUTPUT);
pinMode(SWITCH, INPUT_PULLUP);
// Check for wakeup cause
checkWakeupCause();
// Check if the system woke up from deep sleep
if (wakeUpFlag) {
Serial.println("System Woke Up from Deep Sleep.");
wakeUpFlag = false; // Reset the flag after waking up
} else {
Serial.println("System Initialized.");
}
attachInterrupt(digitalPinToInterrupt(SWITCH), handleSleepWakeup, FALLING); // Trigger on switch press
}
void loop() {
// If system is asleep, do not continue further
if (isAsleep) {
Serial.println("Entering Deep Sleep Mode...");
setColor(0, 0, 0); // Turn off RGB LEDs before sleep
delay(1000); // Brief delay to allow message printing
goToSleep(); // Call the goToSleep function to put the ESP32 in deep sleep
} else {
// Read sensor data every 2 seconds when awake
unsigned long currentMillis = millis();
static unsigned long previousMillis = 0;
const long interval = 2000; // 2 seconds
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
SensorData data = readDHTData(); // Read sensor data into struct
if (isnan(data.humidity) || isnan(data.temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Serial.print("Humidity: ");
Serial.print(data.humidity);
Serial.print("% Temperature: ");
Serial.print(data.temperature);
Serial.println("°C");
updateLED(data);
handleBuzzer(data);
}
}
}
void IRAM_ATTR handleSleepWakeup() {
unsigned long currentMillis = millis();
// Only process the switch toggle if debounce delay has passed
if (currentMillis - lastSwitchTime > debounceDelay) {
lastSwitchTime = currentMillis;
isAsleep = !isAsleep; // Toggle the sleep state
if (isAsleep) {
wakeUpFlag = true; // Set wakeup flag to true before deep sleep
} else {
wakeUp(); // Call the wakeUp function when switching back from sleep
}
}
}
SensorData readDHTData() {
SensorData data;
data.humidity = dht.readHumidity();
data.temperature = dht.readTemperature();
return data;
}
void updateLED(SensorData data) {
// Only update LED if the system is awake
if (isAsleep) return; // Skip if in deep sleep mode
if (data.humidity < 40) {
setColor(0, 0, 255); // Blue
Serial.println("Blue LED ON - Humidity < 40%");
} else if (data.humidity >= 40 && data.humidity <= 60) {
setColor(0, 255, 0); // Green
Serial.println("Green LED ON - Humidity 40-60%");
} else if (data.humidity > 60 && data.humidity <= 70) {
setColor(255, 0, 0); // Red
Serial.println("Red LED ON - Humidity > 60%");
} else if (data.humidity > 70) {
setColor(255, 0, 0); // Red
Serial.println("Red LED ON - Humidity > 70% - Critical");
}
}
void handleBuzzer(SensorData data) {
if (data.humidity > 60) {
digitalWrite(BUZZER, HIGH); // Short beep
Serial.println("Buzzer ON - High Humidity");
} else if (data.humidity > 70) {
digitalWrite(BUZZER, HIGH); // Continuous beep
Serial.println("Buzzer ON - Critical Humidity");
} else {
digitalWrite(BUZZER, LOW);
}
if (data.temperature > 30.0) {
digitalWrite(BUZZER, HIGH); // Short beep
Serial.println("Buzzer ON - High Temperature");
}
}
void setColor(int red, int green, int blue) {
digitalWrite(LED_R, red);
digitalWrite(LED_G, green);
digitalWrite(LED_B, blue);
}
// Function to put ESP32 into deep sleep
void goToSleep() {
// Disable any automatic wakeup timers and use GPIO wakeup
Serial.println("Disabling automatic wakeup timers");
// Set the wakeup source to be the SWITCH pin (GPIO 21 is for the switch)
esp_sleep_enable_ext0_wakeup(GPIO_NUM_21, 0); // Pin 21 is the switch (active low)
Serial.println("Entering deep sleep...");
esp_deep_sleep_start(); // Enter deep sleep mode
}
// Function to handle wakeup after deep sleep
void wakeUp() {
// ESP32 wakes up automatically and resumes from where it left off
Serial.println("ESP32 woke up from deep sleep");
}
// Function to check wakeup cause
void checkWakeupCause() {
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
switch (cause) {
case ESP_SLEEP_WAKEUP_EXT0:
Serial.println("Woke up due to GPIO external interrupt");
break;
case ESP_SLEEP_WAKEUP_EXT1:
Serial.println("Woke up due to GPIO external interrupt (EXT1)");
break;
case ESP_SLEEP_WAKEUP_TIMER:
Serial.println("Woke up due to timer");
break;
default:
Serial.println("Woke up due to unknown cause");
break;
}
}