#include <DHT.h>
// Pin definitions
#define DHTPIN 15 // DHT22 data pin (D15 in Wokwi)
#define DHTTYPE DHT22
#define RED_LED 4 // Red LED pin (D4 in Wokwi)
#define GREEN_LED 16 // Green LED pin (D16 in Wokwi)
#define YELLOW_LED 2 // Yellow LED (D2 in Wokwi)
// Timing for blinking
unsigned long lastBlinkTime = 0;
bool blinkState = false;
// States
enum State { IDLE, HEATING, STABILIZING, TARGET_REACHED, OVERHEAT };
State currentState = IDLE;
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
Serial.println("System Initialized");
}
void updateState(float temperature) {
if (temperature > 56 && temperature <= 80 ) {
currentState = OVERHEAT;
} else if (temperature > 32 && temperature <= 56 ) {
currentState = TARGET_REACHED;
} else if (temperature > 8 && temperature <= 32 ) {
currentState = STABILIZING;
} else if (temperature > -16 && temperature <= 8 ) {
currentState = HEATING;
} else if(temperature >= -40 && temperature <= -16 ){
currentState = IDLE;
}
}//These thresholds are according to the Wokwi simulator
void applyState() {
switch (currentState) {
case IDLE:
analogWrite(RED_LED, 0);
digitalWrite(GREEN_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
Serial.println("[IDLE] Heater OFF");
break;
case HEATING:
analogWrite(RED_LED, 60);
digitalWrite(GREEN_LED, HIGH);
digitalWrite(YELLOW_LED, LOW);
Serial.println("[HEATING] Heater ON, 60% power");
break;
case STABILIZING:
analogWrite(RED_LED, 120);
digitalWrite(GREEN_LED, HIGH);
digitalWrite(YELLOW_LED, LOW);
Serial.println("[STABILIZING] Heater ON, 80% power");
break;
case TARGET_REACHED:
analogWrite(RED_LED, 180);
digitalWrite(GREEN_LED, HIGH);
digitalWrite(YELLOW_LED, LOW);
Serial.println("[TARGET_REACHED] Heater ON, 100% power");
break;
case OVERHEAT:
analogWrite(RED_LED, 255); // keep red LED at full
digitalWrite(GREEN_LED, LOW); // heater OFF
Serial.println("[OVERHEAT] Heater OFF, Buzzer ON, Blinking");
break;
}
}
void handleBlinking() {
if (currentState == OVERHEAT) {
unsigned long currentMillis = millis();
if (currentMillis - lastBlinkTime >= 500) { // toggle every 500ms
blinkState = !blinkState;
digitalWrite(YELLOW_LED, blinkState);
lastBlinkTime = currentMillis;
}
} else {
digitalWrite(YELLOW_LED, LOW); // no blink outside overheat
}
}
void loop() {
float temp = dht.readTemperature();
if (isnan(temp)) {
Serial.println("Failed to read temperature from DHT22!");
delay(2000);
return;
}
Serial.print("Temperature: ");
Serial.println(temp);
updateState(temp);
applyState();
handleBlinking(); // run blinking separately
delay(1000); // read every second
}