#include <PID_v1.h>
#include <Servo.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define CaseFan_PIN 9
#define Stop_Pump_Servo_PIN 10
#define SERVO_PIN 11
#define CircPump_PIN 12
#define Boiler_Flame_PIN 8
#define Boiler_PIN 13
#define ONE_WIRE_BUS 23
#define Boiler_Hys 5 //---------------------------------------------Hysteresis Boiler
#define CircPump_Set 20 //------------------------------------------CircPump Setpoint
#define CircPump_Hys 5 //-------------------------------------------Hysteresis CircPump
double FlowF_Set = 55; //-------------------------------------------will be overwritten later in map fuction
double FlowF_Temp, output;
double Kp = 2.0; //-------------------------------------------------proportional gain
double Ki = 5.0; //-------------------------------------------------integral gain
double Kd = 1.0; //-------------------------------------------------derivative gain
PID myPID(&FlowF_Temp, &output, &FlowF_Set, Kp, Ki, Kd, DIRECT);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
Servo servo;
float Boiler_Temp;
float Out_Temp_Sensor1, Out_Temp_Sensor2;
float average; //variable to store average temperature OutTemp_Sensor1, OutTemp_Sensor2
float Case_Temp;
//Driftstæller variabler
bool lastState_Boiler_Flame = false;
bool lastState_CircPump = false;
unsigned int timeBufferTimer_Boiler_Flame = 0;
unsigned int timeBufferTimer_CircPump = 0;
byte timeBufferMinutter_Boiler_Flame = 0;
byte timeBufferMinutter_CircPump = 0;
byte timeBufferSekunder_Boiler_Flame = 0;
byte timeBufferSekunder_CircPump = 0;
unsigned long timerStart_Boiler_Flame = 0;
unsigned long timerStart_CircPump= 0;
unsigned int CounterTurnOnTimes_Boiler_Flame = 0;
unsigned int CounterTurnOnTimes_CircPump = 0;
//Driftstæller printer
unsigned long lastPrintUpdate = 0;
unsigned long IntervalPrintUpdate = 1000;//Print besked hver 2s
//Til opstart af cirkulationspumpe ved lang stoptid
long lastTimeBeginOn = 0;
long lastTimeBeginOff = 0;
long lastTimeFinishedInterval = 0;
bool CirPumpOldState = 0;
long TimeToBeOn = 5000;//Time the pump will be on iff it has been off for too long(10m=600000 millis)
long MaxTimeOff = 10000;//Max time the pump can be off before turning the pump on(12t=43200000 millis)
void setup() {
Serial.begin(115200);
pinMode(CaseFan_PIN, OUTPUT);
pinMode(Stop_Pump_Servo_PIN, INPUT);
pinMode(CircPump_PIN, OUTPUT);
pinMode(Boiler_Flame_PIN, INPUT);
pinMode(Boiler_PIN, OUTPUT);
servo.attach(SERVO_PIN);
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(5, 85); //--------------------------------Max/Min output Shunt_Set(Servo)
sensors.begin();
}
void loop() {
sensors.requestTemperatures();
Boiler_Temp = sensors.getTempCByIndex(2);
FlowF_Temp = sensors.getTempCByIndex(1);
Out_Temp_Sensor1 = sensors.getTempCByIndex(0);
Out_Temp_Sensor2 = sensors.getTempCByIndex(3);
Case_Temp = sensors.getTempCByIndex(4);
float average_Out_Temp = (Out_Temp_Sensor1 + Out_Temp_Sensor2) / 2; //--calculate average Out_Temp_Sensor's
myPID.Compute();
if(digitalRead(Stop_Pump_Servo_PIN)){ //-------------------------Stop Pump/servo function
output = 10; //-----------------------------------------------Output what Shunt/servo close to
}
else{
myPID.Compute();
}
servo.write(output);
float Case_Set = map(Case_Temp, 20, 50, 0, 255); //------------Setpoint Case_Set map/remember limits!
float Boiler_Set = map(average_Out_Temp, -10, 20, 70, 56); //-----------Setpoint Boiler_Set map/remember limits!
FlowF_Set = map(average_Out_Temp, -10, 20, 60, 48); //------------------Setpoint Flow_Set map to PID/remember limits!
//--map to convert to show in percentage for TFT screen only-----
float Fan_Output_Percentage = map(Case_Set, 60, 255, 60, 100);
float Shunt_Output_Percentage = map(output, 10, 85, 0, 100);
//----------------------------------------------------------
if(Boiler_Set > 70){ //----------------------------------------Boiler_Set upper limit
Boiler_Set = 70;
}else if(Boiler_Set < 56){ //----------------------------------Boiler_Set lower limit
Boiler_Set = 56;
}
if(Boiler_Temp < (Boiler_Set - Boiler_Hys)){
digitalWrite(Boiler_PIN, HIGH);
}
else if(Boiler_Temp > (Boiler_Set)){
digitalWrite(Boiler_PIN, LOW);
}
if(FlowF_Set > 60){ //-------------------------------------------FlowF_Set upper limit
FlowF_Set = 60;
}else if(FlowF_Set < 48){ //-----------------------------------FlowF_Set lower limit
FlowF_Set = 48;
}
if(digitalRead(Stop_Pump_Servo_PIN)){//Bloker opstart af pumpe
//digitalWrite(CircPump_PIN, LOW);//Stop pumpe
//I stedet for at stoppe direkte skal der først tjekkes om der har været stoppet for lang tid
//Copy paste fra eksempel
// Maybe turn off CircPump_PIN if no flush cycle needed
if(millis() - lastTimeFinishedInterval > MaxTimeOff){
digitalWrite(CircPump_PIN, HIGH);
}else{
digitalWrite(CircPump_PIN, LOW);
}
}else{//Normal drift
if(average_Out_Temp < (CircPump_Set - CircPump_Hys)){
digitalWrite(CircPump_PIN, HIGH);
}
else if(average_Out_Temp > (CircPump_Set)){
//digitalWrite(CircPump_PIN, LOW);
//I stedet for at stoppe direkte skal der først tjekkes om der har været stoppet for lang tid
//Copy paste fra eksempel
// Maybe turn off CircPump_PIN if no flush cycle needed
if(millis() - lastTimeFinishedInterval > MaxTimeOff){
digitalWrite(CircPump_PIN, HIGH);
}else{
digitalWrite(CircPump_PIN, LOW);
}
}
}
//Koden til at detektere kørsel er det samme som mit eksempel
if(digitalRead(CircPump_PIN) != CirPumpOldState){//Detect when the pump changes state
if(digitalRead(CircPump_PIN)){
lastTimeBeginOn = millis();
}else{
lastTimeBeginOff = millis();
}
CirPumpOldState = digitalRead(CircPump_PIN);
}
if(digitalRead(CircPump_PIN)){//Detect if the pump is turned on
if(millis() - lastTimeBeginOn > TimeToBeOn){//The pump has been on for long enough
lastTimeFinishedInterval = millis();
}
}
analogWrite(CaseFan_PIN, Case_Set);
if(Case_Set > 255){ //-----------------------------------------CaseFan_Set upper limit(Fan_Speed)
Case_Set = 255;
}else if(Case_Set < 60){ //-------------------------------------CaseFan_Set lower limit(Fam_Speed)
Case_Set = 0;
}// if Case__Set output comes under 60 then Output goes to 0, to be sure fan starts up
//-----------------------------Start up counter Boiler_Flame-------------------------------------
if(digitalRead(Boiler_Flame_PIN) != lastState_Boiler_Flame){//LEDen har ændret tilstand
if(lastState_Boiler_Flame){//Den er gået fra tændt til slukket
timeBufferSekunder_Boiler_Flame += (millis() - timerStart_Boiler_Flame)/1000;//Lægger tiden som var gået siden sidste tænd, til bufferen
}else{//Den er gået fra slukket til tændt
timerStart_Boiler_Flame = millis();
CounterTurnOnTimes_Boiler_Flame++; //Læg 1 til. Samme som CounterTurnOnTimes_LED = CounterTurnOnTimes_LED + 1
}
lastState_Boiler_Flame = digitalRead(Boiler_Flame_PIN);
}
//------------------------------ Timeshift code Boiler_Flame.... s -> min -> timer ----------
if(millis() - timerStart_Boiler_Flame > 1000 && digitalRead(Boiler_Flame_PIN)){//Tæller ref har opnået over 1s opsparet tid. Overfør til buffer.
timeBufferSekunder_Boiler_Flame++;//Læg 1s til sekund buffer
timerStart_Boiler_Flame += 1000;//Skub timer start 1s frem.
if(timeBufferSekunder_Boiler_Flame > 59){//Sekundbuffer har opnået 60s. Overfør til minut tæller.
timeBufferSekunder_Boiler_Flame -= 60;//Trækker 60 fra
timeBufferMinutter_Boiler_Flame++;
if(timeBufferMinutter_Boiler_Flame > 59){//60min = 1 time
timeBufferMinutter_Boiler_Flame -= 60;
timeBufferTimer_Boiler_Flame++;
}
}
}//-----------------------------------------------------------------------------------------------------
//-----------------------------Start up counter Circ_Pump-------------------------------------
if(digitalRead(CircPump_PIN) != lastState_CircPump){//LEDen har ændret tilstand
if(lastState_CircPump){//Den er gået fra tændt til slukket
timeBufferSekunder_CircPump += (millis() - timerStart_CircPump)/1000;//Lægger tiden som var gået siden sidste tænd, til bufferen
}else{//Den er gået fra slukket til tændt
timerStart_CircPump = millis();
CounterTurnOnTimes_CircPump++; //Læg 1 til. Samme som CounterTurnOnTimes_LED = CounterTurnOnTimes_LED + 1
}
lastState_CircPump = digitalRead(CircPump_PIN);
}
//------------------------------ Timeshift code CircPump.... s -> min -> timer------------
if(millis() - timerStart_CircPump > 1000 && digitalRead(CircPump_PIN)){//Tæller ref har opnået over 1s opsparet tid. Overfør til buffer.
timeBufferSekunder_CircPump++;//Læg 1s til sekund buffer
timerStart_CircPump += 1000;//Skub timer start 1s frem.
if(timeBufferSekunder_CircPump > 59){//Sekundbuffer har opnået 60s. Overfør til minut tæller.
timeBufferSekunder_CircPump -= 60;//Trækker 60 fra
timeBufferMinutter_CircPump++;
if(timeBufferMinutter_CircPump > 59){//60min = 1 time
timeBufferMinutter_CircPump -= 60;
timeBufferTimer_CircPump++;
}
}
}//-----------------------------------------------------------------------------------------
if(millis() - lastPrintUpdate > IntervalPrintUpdate){
Serial.print("Boiler_Temp: ");
Serial.print(Boiler_Temp);
Serial.print(" / Boiler_Set: ");
Serial.print(Boiler_Set);
//Printer running time/start Boiler
Serial.print(" / Time_Boiler_Flame: ");
Serial.print(timeBufferTimer_Boiler_Flame);
Serial.print("h ");
Serial.print(timeBufferMinutter_Boiler_Flame);
Serial.print("m ");
Serial.print(timeBufferSekunder_Boiler_Flame);
Serial.print("s ");
Serial.print("/ Start_Up: ");
Serial.print(CounterTurnOnTimes_Boiler_Flame);
Serial.println(" times");
//-------------------------------------------
Serial.print("FlowF_Temp: ");
Serial.print(FlowF_Temp);
Serial.print(" / FlowF_Set: ");
Serial.print(FlowF_Set);
Serial.print(" / Shunt_Pos: ");
Serial.print(output);
Serial.print(" / % open");
Serial.println(Shunt_Output_Percentage);
//Printer running time/start CircPump
Serial.print("Running_Time_CircPump: ");
Serial.print(timeBufferTimer_CircPump); Serial.print("h ");
Serial.print(timeBufferMinutter_CircPump); Serial.print("m ");
Serial.print(timeBufferSekunder_CircPump); Serial.print("s ");
Serial.print("/ Start_Up: ");
Serial.print(CounterTurnOnTimes_CircPump); Serial.println(" times");
//------------------------------------------
Serial.print("Out_Temp_Sensor1: "); Serial.print(Out_Temp_Sensor1);
Serial.print(" / Out_Temp_Sensor2: "); Serial.print(Out_Temp_Sensor2);
Serial.print(" / Out_Temp: "); Serial.println(average_Out_Temp);
Serial.print("Case_Temp: "); Serial.print(Case_Temp);
Serial.print(" / fan_out: "); Serial.println(Case_Set);
Serial.print(" / Fan_Speed "); Serial.println(Fan_Output_Percentage);
lastPrintUpdate = millis();
}
}
Boiler_Temp
FlowF_Temp
Out_Temp_Sensor2
Out_Temp_Sensor1
Boiler_relay
Circ_Pump_relay
Shunt_Servo
Case_Temp
Stop_Pumpe_Shunt
Boiler_Flame