#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
// Variablen für die Timer
unsigned long fan_delay_timer = 10000;
unsigned long fan_cut_off_time = 10000;
unsigned long heater_on = 10000;
unsigned long heater_off = 30000;
// Adresse für den LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Pin für den DS18B20-Datenpin
#define ONE_WIRE_BUS 4
// OneWire-Objekt erstellen
OneWire oneWire(ONE_WIRE_BUS);
// DallasTemperature-Objekt erstellen
DallasTemperature sensors(&oneWire);
// Variablen für die Temperstur
float temp_sensor1 = 0;
// Belegung der Taster
const byte pin_start_button = 12;
const byte pin_setpoint_increase = 10;
const byte pin_setpoint_decrease = 11;
// Variablen für die Taster
// start_button
unsigned long button_millis = 0;
bool button_on = false;
bool button_read = false;
bool switch0 = false;
// Setpoint_taster
bool increase_read = false;
bool decrease_read = false;
// Variable für den Setpoint
unsigned long increase_millis = 0;
unsigned long decrease_millis = 0;
float setpoint = 20;
// Belegung der Status-LED
const byte pin_status_led = 9;
// Belegung für die Relais
const byte pin_relais_fan = 8;
const byte pin_relais_heater_stage_1 = 7;
const byte pin_relais_heater_stage_2 = 6;
const byte relais[3] = {pin_relais_fan, pin_relais_heater_stage_1, pin_relais_heater_stage_2};
// Setzen der State-Machine
enum current_operation_state {
system_off,
system_active,
full_heating,
half_heating,
standby,
fan_delay
};
current_operation_state operation_state = system_off;
// Vorabdeklaration der einzelnen Abschnitte
void update_serial_monitor();
void update_ds18b20();
void read_button();
void manage_setpoint();
void write_lcd();
void manage_states();
void manage_outputs();
// Abschnitt für die Timer
// Serial-Monitor
unsigned long serial_millis = 0;
// Sensoren
unsigned long temp_millis = 0;
// Operation_state_timer
unsigned long operation_state_millis = 0;
// Heiztimer
unsigned long heating_millis = 0;
// Timer für den LCD
unsigned long lcd_millis = 0;
// Fan-Timer
unsigned long fan_timeout_millis = 0;
//======================================================//
//======================================================//
void setup() {
for (byte i = 0; i < 3; i++) {
digitalWrite(relais[i], HIGH);
}
// Starten des Seriellen Monitors
Serial.begin(9600);
// Initialisierung des LCD
lcd.init();
// DallasTemperature-Sensoren initialisieren
sensors.begin();
Serial.println("DS18B20 Temperatur-Sensor Test");
// Setzen der Outputs für die Relais
for (byte i = 0; i < 3; i++) {
pinMode(relais[i], OUTPUT);
}
// Setzen des Ausgangs für die Status-LED
pinMode(pin_status_led, OUTPUT);
// Setzen der Eingänge für die Taster
pinMode(pin_start_button, INPUT_PULLUP);
pinMode(pin_setpoint_increase, INPUT_PULLUP);
pinMode(pin_setpoint_decrease, INPUT_PULLUP);
}
void loop() {
update_serial_monitor();
update_ds18b20();
read_button();
manage_setpoint();
write_lcd();
manage_states();
manage_outputs();
}
//============================================================//
//========================Abschnitte==========================//
//============================================================//
void update_serial_monitor() {
// Variablen für diesen Abschnitt
unsigned long serial_timer = millis() - serial_millis;
if (serial_timer > 200) {
Serial.print("OP = ");
Serial.print(operation_state);
Serial.print(" Start_B = ");
Serial.print(switch0);
Serial.print(" Temps = ");
Serial.print(temp_sensor1);
Serial.print(" Setpoint = ");
Serial.print(setpoint);
Serial.println(".");
serial_millis = millis();
}
}
//============================================================//
//========================Abschnitte==========================//
//============================================================//
void update_ds18b20() {
// Variablen für diesen Abschnitt
unsigned long temp_timer = millis() - temp_millis;
if (temp_timer > 1000) {
sensors.requestTemperatures();
temp_sensor1 = sensors.getTempCByIndex(0);
temp_millis = millis();
}
}
//============================================================//
//========================Abschnitte==========================//
//============================================================//
void read_button() {
// Variablen für diesen Abschnitt
unsigned long button_timer = millis() - button_millis;
button_read = digitalRead(pin_start_button);
if (button_read) {
button_millis = millis();
}
if (!button_read && !button_on && button_timer > 20) {
button_on = true;
}
if (button_read && button_on) {
button_on = false;
}
if (button_read) {
switch0 = false;
} else {
switch0 = true;
}
}
//============================================================//
//========================Abschnitte==========================//
//============================================================//
void manage_setpoint() {
// Variablen für diesen Abschnitt
unsigned long increase_timer = millis() - increase_millis;
unsigned long decrease_timer = millis() - decrease_millis;
increase_read = digitalRead(pin_setpoint_increase);
decrease_read = digitalRead(pin_setpoint_decrease);
if (!increase_read && increase_timer > 500) {
setpoint++;
increase_millis = millis();
}
if (!decrease_read && decrease_timer > 500) {
setpoint--;
decrease_millis = millis();
}
}
//============================================================//
//========================Abschnitte==========================//
//============================================================//
void write_lcd() {
// Variablen für diesen Abschnitt
unsigned long lcd_timer = millis() - lcd_millis;
if (operation_state == system_off) {
lcd.setCursor(6, 0);
lcd.print(temp_sensor1);
lcd.setCursor(11, 0);
lcd.write(223);
lcd.setCursor(12, 0);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print(" Heizung aus ");
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
lcd.noBacklight();
} else if (operation_state == full_heating) {
lcd.backlight();
lcd.setCursor(6, 0);
lcd.print(temp_sensor1);
lcd.setCursor(11, 0);
lcd.write(223);
lcd.setCursor(12, 0);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Volles Heizregister");
lcd.setCursor(0, 2);
lcd.print(" SetPoint ");
lcd.setCursor(6, 3);
lcd.print(setpoint);
lcd.setCursor(11, 3);
lcd.write(223);
lcd.setCursor(12, 3);
lcd.print("C");
} else if (operation_state == half_heating) {
lcd.backlight();
lcd.setCursor(6, 0);
lcd.print(temp_sensor1);
lcd.setCursor(11, 0);
lcd.write(223);
lcd.setCursor(12, 0);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Halbes Heizregister");
lcd.setCursor(0, 2);
lcd.print(" SetPoint ");
lcd.setCursor(6, 3);
lcd.print(setpoint);
lcd.setCursor(11, 3);
lcd.write(223);
lcd.setCursor(12, 3);
lcd.print("C");
} else if (operation_state == standby) {
lcd.backlight();
lcd.setCursor(6, 0);
lcd.print(temp_sensor1);
lcd.setCursor(11, 0);
lcd.write(223);
lcd.setCursor(12, 0);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Temperatur erreicht ");
lcd.setCursor(0, 2);
lcd.print(" SetPoint ");
lcd.setCursor(6, 3);
lcd.print(setpoint);
lcd.setCursor(11, 3);
lcd.write(223);
lcd.setCursor(12, 3);
lcd.print("C");
} else if (operation_state == fan_delay) {
lcd.backlight();
lcd.setCursor(6, 0);
lcd.print(temp_sensor1);
lcd.setCursor(11, 0);
lcd.write(223);
lcd.setCursor(12, 0);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print(" Kuehlung ");
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
}
}
//============================================================//
//========================Abschnitte==========================//
//============================================================//
void manage_states() {
// Variablen für diesen Abschnitt
unsigned long operation_state_timer = millis() - operation_state_millis;
switch(operation_state) {
case system_off:
if (switch0) {
operation_state = system_active;
operation_state_millis = millis();
temp_millis = millis();
heating_millis = millis();
fan_timeout_millis = millis();
increase_millis = millis();
decrease_millis = millis();
}
case system_active:
if (switch0 && temp_sensor1 < (setpoint - 2)) {
operation_state = full_heating;
operation_state_millis = millis();
} else if (switch0 && temp_sensor1 > (setpoint -2) && temp_sensor1 < setpoint) {
operation_state = half_heating;
operation_state_millis = millis();
} else if (switch0 && temp_sensor1 > setpoint) {
operation_state = standby;
operation_state_millis = millis();
}
break;
case full_heating:
if (switch0 && temp_sensor1 > (setpoint - 2) && temp_sensor1 < setpoint) {
operation_state = half_heating;
operation_state_millis = millis();
} else if (switch0 && temp_sensor1 > setpoint) {
operation_state = standby;
operation_state_millis = millis();
} else if (!switch0) {
operation_state = fan_delay;
operation_state_millis = millis();
}
break;
case half_heating:
if (switch0 && temp_sensor1 < (setpoint - 2)) {
operation_state = full_heating;
operation_state_millis = millis();
} else if (switch0 && temp_sensor1 > (setpoint + 1)) {
operation_state = standby;
operation_state_millis = millis();
} else if (!switch0) {
operation_state = fan_delay;
operation_state_millis = millis();
}
break;
case standby:
if (switch0 && temp_sensor1 < (setpoint - 2)) {
operation_state = full_heating;
operation_state_millis = millis();
} else if (switch0 && temp_sensor1 > (setpoint - 2) && temp_sensor1 < (setpoint - 1)) {
operation_state = half_heating;
operation_state_millis = millis();
} else if (!switch0) {
operation_state = fan_delay;
operation_state_millis = millis();
}
break;
case fan_delay:
if (operation_state_timer > fan_delay_timer) {
operation_state = system_off;
operation_state_millis = millis();
}
break;
default:
operation_state = system_off;
operation_state_millis = millis();
break;
}
}
//============================================================//
//==========================Abschnitte========================//
//============================================================//
void manage_outputs() {
// Timer für diesen Abschnitt
unsigned long heating_timer = millis() - heating_millis;
unsigned long fan_timeout = millis() - fan_timeout_millis;
switch(operation_state) {
case system_off:
digitalWrite(pin_status_led, !LOW);
digitalWrite(relais[0], !LOW);
digitalWrite(relais[1], !LOW);
digitalWrite(relais[2], !LOW);
fan_timeout_millis = millis();
heating_millis = millis();
break;
case system_active:
digitalWrite(pin_status_led, !HIGH);
digitalWrite(relais[0], !LOW);
digitalWrite(relais[1], !LOW);
digitalWrite(relais[2], !LOW);
fan_timeout_millis = millis();
heating_millis = millis();
break;
case full_heating:
digitalWrite(pin_status_led, !HIGH);
digitalWrite(relais[0], !HIGH);
digitalWrite(relais[1], !HIGH);
if (heating_timer < heater_on) {
digitalWrite(relais[2], !HIGH);
} else if (heating_timer > heater_on) {
digitalWrite(relais[2], !LOW);
}
if (heating_timer > heater_off) {
heating_millis = millis();
}
fan_timeout_millis = millis();
break;
case half_heating:
digitalWrite(pin_status_led, !HIGH);
digitalWrite(relais[0], !HIGH);
digitalWrite(relais[1], !HIGH);
digitalWrite(relais[2], !LOW);
fan_timeout_millis = millis();
heating_millis = millis();
break;
case standby:
digitalWrite(pin_status_led, !HIGH);
digitalWrite(relais[1], !LOW);
digitalWrite(relais[2], !LOW);
if (fan_timeout < fan_cut_off_time) {
digitalWrite(relais[0], !HIGH);
} else {
digitalWrite(relais[0], !LOW);
}
break;
case fan_delay:
digitalWrite(pin_status_led, !LOW);
digitalWrite(relais[0], !HIGH);
digitalWrite(relais[1], !LOW);
digitalWrite(relais[2], !LOW);
break;
}
}
//============================================================//
//==========================EMDE==============================//
//============================================================//