// Include neccessary libraries
#include <Arduino.h>
#include <EEPROM.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <Servo.h>
#include <PID_v1.h>
#include "Button2.h"
#include "ESPRotary.h"
// Include configuartion file.
#include "configuration.h"
#include "globals.h"
#include "MyTask.h"
#include "InitSetup.h"
#include "eeprom_speicher.h"
#include "draw_display.h"
#include "rotary_encoder.h"
#include "MySlowServo.h"
#include "status_abfrage.h"
#include "TempProblems.h"
Adafruit_SH1106G display =
Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Display Instanz erstellen
ESPRotary r; // Rotary Encoder Instanz erstellen
Button2 b; // Btn2 Instanz erstellen
LangsamerServo servo; // Servo Instanz erstellen
// Parameters of thermosensors
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance
DallasTemperature sensors(&oneWire); // Dallas Temperatur Sensor Instanz erstellen
// OneWire device addresses of the thermometers as configured in configuration.h
//DeviceAddress caseThermometer = {CASE_THERMOMETER_ADDRESS};
//DeviceAddress heaterThermometer = {HEATER_THERMOMETER_ADDRESS};
//int numberOfDevices; // Number of temperature devices found
// Hiemit wird die Device ID dem Sensor Zugeordnet, eine Serial Address ist dadurch nicht notwendig
// Kann durch Change im Setup gewechselt werden, damit die Sensorzuordnung wieder passt.
byte HeaterTempDeviceID = 1;
byte CaseTempDeviceID = 0;
byte TEMPERATURE_DELAY = 10; // Wert muss *10 genommen werden!!
DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address
/*-----------------------------------*/
/*ANFANG-----ABSCHNITT VARIABLEN-----*/
//uint32_t previousMillis;
unsigned long previousMillis;
// Werte für Übertemperaturlimits
byte CASE_TEMP_OVERTEMP_LIMIT = 70;
byte HEATER_TEMP_OVERTEMP_LIMIT = 80;
// Werte für die Position des Servos im geöffneten und geschlossenen Zustand.
byte SERVO_POS_OPEN = 10;
byte SERVO_POS_CLOSED = 90;
byte SERVO_SPEED = 15;
//int upperlimit;
//int lowerlimit;
int target = 35; // initial target temperature
byte diff_heater = 20; // Temperatur anhebung für Heater
byte min_heater_temp = 50; // Minimale Heater Temperatur
byte max_heater_temp = 80; // Maximale Heater Temperatur
byte maxtemp = 45; // target temperature limit
byte tolerance = 1; // set total tolerance for target temperature
float caseTemp = 0;
float heaterTemp = 0;
// Lüfterschwindigkeiten in %
byte fan_c_speed = 80;
byte fan_h_speed = 80;
byte eeprom_status = 1; // 0 = nur lesen // 1 = schreiben // erste INIT Daten schreiben
bool change_sensor_id = false;
// Zuweisen operatingMode as MODE_FAN as a little workaround, as it will get
// increased by 1 while starting the first time, so it will actually begin in
// MODE_IDLE.
byte operatingMode_state = MODE_IDLE;
bool changeOperatingMode = false;
byte heaterState = HEATER_STATE_OFF;
byte fan_h_State = FAN_HEATER_STATE_OFF;
byte fan_c_State = FAN_CASE_STATE_OFF;
byte servoState = SERVO_STATE_CLOSED;
// Zuweisen display modes
byte displayMode_state = DISPLAY_MODE_PREPARE;
// Zuweisen setup modes
byte setupMenue_state = SETUP_STATE_CASE_TEMP_OVERTEMP_LIMIT;
//Specify the links and initial tuning parameters
byte Kp=2;
byte Ki=5;
byte Kd=1;
// Werte fue Heater Pid
double Setpoint, Input, Output;
PID heater_PID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
/*ENDE-----ABSCHNITT VARIABLEN-----*/
/*---------------------------------*/
/*---------------------------------------------------*/
/*ANFANG-----ABSCHNITT VARIABLENTemperature Task-----*/
// Temperature Task
class Temp : public MyTask {
public:
void setup(unsigned long pausenZeit) {
pause = pausenZeit;
}
void loop() {
if (schritt == 0) {
sensors.requestTemperatures(); // Send the command to get temperatures
wait(pause * 20);
schritt = 1;
return;
}
if (schritt == 1) {
sensors.getAddress(tempDeviceAddress, 0); // DEVICE 0
wait(pause * 10);
schritt = 2;
return;
}
if (schritt == 2) {
float tempC = sensors.getTempC(tempDeviceAddress); // DEVICE 0
if (tempC == DEVICE_DISCONNECTED_C) return; //"Error: Could not read temperature data"
// Show current temp on display
if (CaseTempDeviceID == 0) {
caseTemp = tempC;
if (displayMode_state == DISPLAY_MODE_PREPARE) draw_update_temp_sensors(caseTemp, y_B); // draw_update_case_temp();
}
if (HeaterTempDeviceID == 0) {
heaterTemp = tempC;
if (displayMode_state == DISPLAY_MODE_PREPARE) draw_update_temp_sensors(heaterTemp, y_C); // draw_update_heater_temp();
}
wait(pause * 10);
schritt = 3;
return;
}
if (schritt == 3) {
sensors.getAddress(tempDeviceAddress, 1); // DEVICE 1
wait(pause * 10);
schritt = 4;
return;
}
if (schritt == 4) {
float tempC = sensors.getTempC(tempDeviceAddress); // DEVICE 1
if (tempC == DEVICE_DISCONNECTED_C) return; //"Error: Could not read temperature data"
// Show current temp on display
if (CaseTempDeviceID == 1) {
caseTemp = tempC;
if (displayMode_state == DISPLAY_MODE_PREPARE) draw_update_temp_sensors(caseTemp, y_B); // draw_update_case_temp();
}
if (HeaterTempDeviceID == 1) {
heaterTemp = tempC;
if (displayMode_state == DISPLAY_MODE_PREPARE) draw_update_temp_sensors(heaterTemp, y_C); // draw_update_heater_temp();
}
wait(pause * 10);
schritt = 0;
return;
}
}
private:
unsigned long pause;
};
// Temperatur Task Instanz erstellen
Temp temperature;
/*ENDE-----ABSCHNITT VARIABLENTemperature Task-----*/
/*-------------------------------------------------*/
void setup() {
//auskommentiert wegen speicher
//Stetze Serial Speed
setSerial();
//if (DEBUG == 1) setSerial();
// Set Pin MOde
setPinMode();
// Lese Info aus EEprom ob Setup Werte Gelesen werden können
eeprom_status = EEPROM.read(SETUP_STATE_EEPROM);
// INIT Dallas Temperatur Sensoren
initTempsensors();
sensors.getAddress(tempDeviceAddress, 0);
sensors.setResolution(tempDeviceAddress, 10);
sensors.getAddress(tempDeviceAddress, 1);
sensors.setResolution(tempDeviceAddress, 10);
// Initialisiere den Servo
initServo();
// Init Rotary Encoder
initRotaryEncoder();
// Init Rotary Button
initRotaryButton();
// Init Temperature Task
temperature.setup(TEMPERATURE_DELAY);
temperature.start();
// Init Display
initDisplay();
// Init PWM Pid
Setpoint = target + diff_heater;
Input = heaterTemp;
heater_PID.SetMode(MANUAL);
Output = 0;
}
void loop() {
//Rotary_Encoder
r.loop();
//Button2
b.loop();
if (!servo.amZiel()) servo.tic();
if (servo.status_change == true) {
servo.status_change = false;
byte currentServoPos = servo.read();
if (currentServoPos == SERVO_POS_CLOSED) {
servoState = SERVO_STATE_CLOSED;
} else if (currentServoPos == SERVO_POS_OPEN) {
servoState = SERVO_STATE_OPEN;
}
draw_update_state_vent();
servo.detach();
}
if (changeOperatingMode == true) {
changeOperatingMode = false;
aktiviere_operating_mode();
}
temperature.tic();
if (millis() - previousMillis >= TEMPERATURE_PROBLEMS_DELAY) {
previousMillis = millis();
checkForTempProblems(); // check if temperatures are in safe range
if (heaterState == HEATER_STATE_ON) setHeaterTemp(); // Ist in dieser Routine damit nicht zu oft abgefragt wird
}
Input = heaterTemp;
heater_PID.Compute();
if (heater_PID.GetMode() == true) analogWrite(HEATER_PIN, Output);
if (operatingMode_state == MODE_HEATING) {
if ( caseTemp <= target - tolerance ) {
if (heaterState == HEATER_STATE_OFF) control_heater(true);
}
else if ( caseTemp >= target + tolerance ) {
if (heaterState == HEATER_STATE_ON) control_heater(false);
}
if ( caseTemp >= target + (tolerance + 1) ) {
if (fan_c_State == FAN_CASE_STATE_OFF) control_fan_c(true);
if (servoState == SERVO_STATE_CLOSED) control_vent(true);
}
else if ( caseTemp <= target - (tolerance - 1) ) {
if (fan_c_State == FAN_CASE_STATE_ON) control_fan_c(false);
if (servoState == SERVO_STATE_OPEN) control_vent(false);
}
}
if (operatingMode_state == MODE_COOLING) {
if ( caseTemp <= target - tolerance ) {
if (fan_c_State == FAN_CASE_STATE_ON) control_fan_c(false);
if (servoState == SERVO_STATE_OPEN) control_vent(false);
}
else if ( caseTemp >= target + tolerance ) {
if (fan_c_State == FAN_CASE_STATE_OFF) control_fan_c(true);
if (servoState == SERVO_STATE_CLOSED) control_vent(true);
}
}
}