#include <DHT.h>
// Pin Definitions
const uint8_t PIN_DHT = 4;
const uint8_t PIN_BTN_MUTE = 2;
const uint8_t PIN_BTN_TEST = 3;
const uint8_t PIN_BUZZER = 10;
const uint8_t PIN_LED_GREEN = 11;
const uint8_t PIN_LED_RED = 12;
const uint8_t PIN_LED_YELLOW = 13;
// Sensor Configuration
#define DHTTYPE DHT22
DHT dht(PIN_DHT, DHTTYPE);
// Temperature Thresholds (Celsius)
const float TEMP_WARNING_THRESHOLD = 35.0;
const float TEMP_DANGER_THRESHOLD = 50.0;
// Timing Configurations (ms)
const unsigned long DHT_READ_INTERVAL = 2000; // Minimal interval sampling DHT22
const unsigned long BUZZER_TOGGLE_DANGER = 150;
const unsigned long BUZZER_TOGGLE_TEST = 300;
// System States
enum TempSystemState {
STATE_NORMAL,
STATE_WARNING,
STATE_OVERHEAT,
STATE_TEST_MODE
};
// Global Variables
TempSystemState currentState = STATE_NORMAL;
float currentTemperature = 0.0;
float currentHumidity = 0.0;
unsigned long lastDhtReadTime = 0;
unsigned long lastBuzzerToggle = 0;
bool buzzerState = false;
bool alarmMuted = false;
bool testRequested = false;
// Function Declarations
void readInputs();
void updateOutputs();
void setLeds(uint8_t red, uint8_t yellow, uint8_t green);
void setup() {
Serial.begin(9600);
dht.begin();
pinMode(PIN_LED_RED, OUTPUT);
pinMode(PIN_LED_YELLOW, OUTPUT);
pinMode(PIN_LED_GREEN, OUTPUT);
pinMode(PIN_BUZZER, OUTPUT);
pinMode(PIN_BTN_MUTE, INPUT_PULLUP);
pinMode(PIN_BTN_TEST, INPUT_PULLUP);
Serial.println(F("--- DHT22 Temperature & Humidity Alarm System ---"));
}
void loop() {
unsigned long currentMillis = millis();
// 1. Asynchronous Input Handling
readInputs();
// 2. Non-blocking Sensor Sampling (Every 2 Seconds)
if (currentMillis - lastDhtReadTime >= DHT_READ_INTERVAL) {
lastDhtReadTime = currentMillis;
float tempRead = dht.readTemperature();
float humRead = dht.readHumidity();
if (!isnan(tempRead) && !isnan(humRead)) {
currentTemperature = tempRead;
currentHumidity = humRead;
Serial.print(F("Temp: "));
Serial.print(currentTemperature, 1);
Serial.print(F(" C | Humidity: "));
Serial.print(currentHumidity, 1);
Serial.println(F(" %"));
} else {
Serial.println(F("[ERROR] Failed to read from DHT22 sensor!"));
}
}
// 3. State Determination Logic
if (testRequested) {
currentState = STATE_TEST_MODE;
} else if (currentTemperature >= TEMP_DANGER_THRESHOLD) {
currentState = STATE_OVERHEAT;
} else if (currentTemperature >= TEMP_WARNING_THRESHOLD) {
currentState = STATE_WARNING;
alarmMuted = false;
} else {
currentState = STATE_NORMAL;
alarmMuted = false;
}
// 4. State Machine Execution
updateOutputs();
}
// Input Reading Routine
void readInputs() {
if (digitalRead(PIN_BTN_MUTE) == LOW) {
if (currentState == STATE_OVERHEAT) {
alarmMuted = true;
}
}
if (digitalRead(PIN_BTN_TEST) == LOW) {
testRequested = true;
} else {
testRequested = false;
}
}
// Output State Executor
void updateOutputs() {
unsigned long currentMillis = millis();
switch (currentState) {
case STATE_NORMAL:
setLeds(LOW, LOW, HIGH);
noTone(PIN_BUZZER);
break;
case STATE_WARNING:
setLeds(LOW, HIGH, LOW);
noTone(PIN_BUZZER);
break;
case STATE_OVERHEAT:
setLeds(HIGH, LOW, LOW);
if (!alarmMuted) {
if (currentMillis - lastBuzzerToggle >= BUZZER_TOGGLE_DANGER) {
lastBuzzerToggle = currentMillis;
buzzerState = !buzzerState;
if (buzzerState) tone(PIN_BUZZER, 2000);
else noTone(PIN_BUZZER);
}
} else {
noTone(PIN_BUZZER);
}
break;
case STATE_TEST_MODE:
if (currentMillis - lastBuzzerToggle >= BUZZER_TOGGLE_TEST) {
lastBuzzerToggle = currentMillis;
buzzerState = !buzzerState;
digitalWrite(PIN_LED_RED, buzzerState ? HIGH : LOW);
digitalWrite(PIN_LED_YELLOW, buzzerState ? HIGH : LOW);
digitalWrite(PIN_LED_GREEN, buzzerState ? HIGH : LOW);
if (buzzerState) tone(PIN_BUZZER, 1000);
else noTone(PIN_BUZZER);
}
break;
}
}
// Helper: Set LED states
void setLeds(uint8_t red, uint8_t yellow, uint8_t green) {
digitalWrite(PIN_LED_RED, red);
digitalWrite(PIN_LED_YELLOW, yellow);
digitalWrite(PIN_LED_GREEN, green);
}