/*
Humidity and Temperature Monitor with RGB Feedback
Hardware: ESP32, DHT22, RGB LED, Slide Switch, Buzzer and resistors
Based on Assignment 1's feedback
Key Features:
- Non-blocking sensor reading and override handling
- Proper ISR implementation with hardware debouncing
- Clear error handling and state management
- Verified color transitions and buzzer control
*/
// Libraries used
#include <Arduino.h>
#include <DHT.h>
// Sensor & Actuator Configuration
#define DHTPIN 15
#define DHTTYPE DHT22
#define BUZZER_PIN 14
#define RIGHT_SWITCH 5
#define LEFT_SWITCH 4
// RGB LED Configuration (Common Cathode)
#define RED_PIN 16
#define GREEN_PIN 17
#define BLUE_PIN 18
// Timing Constants
#define DEBOUNCE_MS 250
#define COLOR_DURATION 2000
#define SENSOR_INTERVAL 2000
DHT dht(DHTPIN, DHTTYPE); // Initializing DHT sensor
// Global Flags for Interrupt Handling
volatile bool rightFlag = false;
volatile bool leftFlag = false;
volatile unsigned long lastInterrupt = 0;
// Interrupt System Variables
bool isInterruptActive = false;
unsigned long interruptStartTime = 0;
uint8_t activateR, activateG, activateB;
// Sensor Reading Variables
unsigned long lastUpdate = 0;
float lastValidHumidity = 0;
float lastValidTemperature = 0;
/*
Interrupt Service Routines (ISRs)
- Ensures minimal execution time to avoid blocking the system.
- Uses hardware debouncing to prevent false triggers.
*/
void IRAM_ATTR handleRight() {
if (millis() - lastInterrupt > DEBOUNCE_MS) {
rightFlag = true;
lastInterrupt = millis();
}
}
void IRAM_ATTR handleLeft() {
if (millis() - lastInterrupt > DEBOUNCE_MS) {
leftFlag = true;
lastInterrupt = millis();
}
}
/*
RGB LED Control
- Uses software PWM to control color intensity.
- Implements a common cathode configuration (LOW = OFF, HIGH = ON).
*/
void setColor(uint8_t r, uint8_t g, uint8_t b) {
analogWrite(RED_PIN, r);
analogWrite(GREEN_PIN, g);
analogWrite(BLUE_PIN, b);
}
/*
Initialization
- Configures all pins and initializes the DHT22 sensor.
- Enables interrupts for slide switches.
*/
void setup() {
Serial.begin(115200);
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
pinMode(RIGHT_SWITCH,INPUT_PULLUP);
pinMode(LEFT_SWITCH,INPUT_PULLUP);
attachInterrupt(RIGHT_SWITCH, handleRight, FALLING);
attachInterrupt(LEFT_SWITCH, handleLeft, FALLING);
dht.begin();
pinMode(BUZZER_PIN, OUTPUT);
Serial.println("System Initialized - Ready for Operation");
}
/*
Switch Handler
- Checks if an interrupt is triggered by slide switches.
- If an interrupt is active, normal operation is suspended.
- Clears ISR flags after handling.
*/
void handleSwitches() {
if (!isInterruptActive) {
if (rightFlag) {
rightFlag = false;
isInterruptActive = true;
activateR = 0;
activateG = 255;
activateB = 255;
interruptStartTime = millis();
noTone(BUZZER_PIN);
Serial.println("RIGHT SWITCH INTERRUPT ACTIVATED: RGB is now Showing Cyan");
} else if (leftFlag) {
leftFlag = false;
isInterruptActive = true;
activateR = 255;
activateG = 0;
activateB = 255;
interruptStartTime = millis();
noTone(BUZZER_PIN);
Serial.println("LEFT SWITCH INTERRUPT ACTIVATED: RGB is now Showing Pink");
}
}
}
/*
Normal Operation Mode
- Reads temperature & humidity from DHT22 sensor.
- Updates RGB LED based on humidity thresholds.
- Activates buzzer when humidity exceeds 80%.
*/
void normalOperation() {
if (millis() - lastUpdate < SENSOR_INTERVAL) return;
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("DHT22 Error: Invalid Readings - Using last valid values");
h = lastValidHumidity;
t = lastValidTemperature;
} else {
lastValidHumidity = h;
lastValidTemperature = t;
}
Serial.print(t);
Serial.print("°C | ");
Serial.print(h);
Serial.println("%");
if (h >= 80) tone(BUZZER_PIN, 1000); // Trigger at 80% or higher
else noTone(BUZZER_PIN);
if (h >= 90) setColor(128, 0, 128);
else if (h >= 80) setColor(255, 0, 0);
else if (h >= 70) setColor(255, 127, 0);
else if (h >= 60) setColor(255, 255, 0);
else if (h >= 50) setColor(0, 255, 0);
else if (h >= 40) setColor(0, 0, 255);
else if (h >= 30) setColor(255, 255, 255);
else setColor(0, 0, 0);
lastUpdate = millis();
}
/*
Main Loop
- Implements a state machine for handling normal operation and interrupts.
- Ensures non-blocking execution and smooth transitions.
*/
void loop() {
handleSwitches();
if (isInterruptActive) {
if (millis() - interruptStartTime >= COLOR_DURATION) {
isInterruptActive = false;
lastUpdate = 0;
Serial.println("Interrupt Service Routine is over - Resuming normal operation");
} else {
setColor(activateR, activateG, activateB);
}
} else {
normalOperation();
}
}