#include <DallasTemperature.h>
#include <OneWire.h>
// Pin definitions
#define ONE_WIRE_BUS 2 // DS18B20 data pin
#define HEATER_PIN 3 // Heater (simulated by LED)
#define INDICATOR_LED 4 // Indicator LED for visual feedback
// Temperature thresholds
#define TARGET_TEMP 25.0 // Target temperature in Celsius
#define HYSTERESIS 1.0 // Hysteresis to prevent rapid switching
#define OVERHEAT_TEMP 35.0 // Overheat threshold
// State enumeration
enum State { IDLE, HEATING, STABILIZING, TARGET_REACHED, OVERHEAT };
State currentState = IDLE;
// Setup OneWire and DallasTemperature libraries
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize pins
pinMode(HEATER_PIN, OUTPUT);
pinMode(INDICATOR_LED, OUTPUT);
digitalWrite(HEATER_PIN, LOW); // Heater off initially
digitalWrite(INDICATOR_LED, LOW); // Indicator off
// Initialize temperature sensor
sensors.begin();
}
void loop() {
// Read temperature
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
// Handle invalid temperature readings
if (temp == DEVICE_DISCONNECTED_C) {
Serial.println("Error: Temperature sensor disconnected");
return;
}
// State machine logic
switch (currentState) {
case IDLE:
if (temp < TARGET_TEMP - HYSTERESIS) {
currentState = HEATING;
digitalWrite(HEATER_PIN, HIGH);
digitalWrite(INDICATOR_LED, HIGH); // Turn on indicator
}
break;
case HEATING:
if (temp >= TARGET_TEMP) {
currentState = STABILIZING;
} else if (temp >= OVERHEAT_TEMP) {
currentState = OVERHEAT;
digitalWrite(HEATER_PIN, LOW);
digitalWrite(INDICATOR_LED, LOW);
}
break;
case STABILIZING:
if (temp >= TARGET_TEMP + HYSTERESIS) {
digitalWrite(HEATER_PIN, LOW);
digitalWrite(INDICATOR_LED, LOW);
currentState = TARGET_REACHED;
} else if (temp < TARGET_TEMP - HYSTERESIS) {
currentState = HEATING;
digitalWrite(HEATER_PIN, HIGH);
digitalWrite(INDICATOR_LED, HIGH);
} else if (temp >= OVERHEAT_TEMP) {
currentState = OVERHEAT;
digitalWrite(HEATER_PIN, LOW);
digitalWrite(INDICATOR_LED, LOW);
}
break;
case TARGET_REACHED:
if (temp < TARGET_TEMP - HYSTERESIS) {
currentState = HEATING;
digitalWrite(HEATER_PIN, HIGH);
digitalWrite(INDICATOR_LED, HIGH);
} else if (temp >= OVERHEAT_TEMP) {
currentState = OVERHEAT;
digitalWrite(HEATER_PIN, LOW);
digitalWrite(INDICATOR_LED, LOW);
}
break;
case OVERHEAT:
if (temp < OVERHEAT_TEMP - HYSTERESIS) {
currentState = STABILIZING;
}
break;
}
// Log temperature and state
Serial.print("Temperature: ");
Serial.print(temp);
Serial.print(" C, State: ");
switch (currentState) {
case IDLE: Serial.println("IDLE"); break;
case HEATING: Serial.println("HEATING"); break;
case STABILIZING: Serial.println("STABILIZING"); break;
case TARGET_REACHED: Serial.println("TARGET_REACHED"); break;
case OVERHEAT: Serial.println("OVERHEAT"); break;
}
// Delay for readability
delay(1000);
}