#include <OneWire.h>
#include <DallasTemperature.h>
//Aufloesung der Sensoren
#define RESOLUTION 9
//Pins, an welchen die Relais
//fuer den Temperatursensorbus, den Mischer,
//das Zonenventil und die Pumpe angeschlossen sind
#define ONE_WIRE_BUS 8
#define MISCHER_OPEN 9
#define MISCHER_CLOSE 10
#define ZONENVENTIL 11
#define PUMPE 12
//Abweichung von der DESIRED_TEMP, bei der der Mischer anfaengt zu mischen
#define MISCHERTEMPERATURE_VARIANCE 2
// Verzoegerung in ms, die das Programm wartet, um Temperatur von Sensoren auszulesen
// Herstellervorgabe: 700 ms bei 12 Bit
#define CONVERSION_DELAY 8000
//Angestrebte Temperatur in der Ruecklaufanhebung
//muss mindestens 55 Grad warm sein, damit der Waermetauscher keinen Glanzruss ansetzt
#define DESIRED_TEMP 55
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//Pufferspeicher Oben
DeviceAddress sensor0 = { 0x28, 0xF8, 0x1F, 0xD0, 0x5, 0x0, 0x0, 0xEA };
//Pufferspeicher Mitte
DeviceAddress sensor1 = { 0x28, 0x6B, 0x8E, 0xCF, 0x5, 0x0, 0x0, 0xDA };
//Pufferspeicher Unten
DeviceAddress sensor2 = { 0x28, 0xEF, 0xC4, 0xCF, 0x5, 0x0, 0x0, 0xB8 };
//Gemeinsamer Ruecklauf
DeviceAddress sensor3 = { 0x28, 0xD3, 0xC8, 0xE4, 0x5, 0x0, 0x0, 0xED };
//Ruecklaufanhebung
DeviceAddress sensor4 = { 0x28, 0xEE, 0xC7, 0xE4, 0x5, 0x0, 0x0, 0x25 };
//Ofen
DeviceAddress sensor5 = { 0x28, 0x27, 0x2, 0xD0, 0x5, 0x0, 0x0, 0x9A};
float tempPSOben;
float tempPSMitte;
float tempPSUnten;
float tempGemeinsamerRuecklauf;
float tempRuecklaufanhebung;
float tempOfen;
unsigned long lastTempRequest;
boolean allowTempRequest = true;
unsigned long lastIteration = 0;
boolean currentlyMoving = false;
unsigned long startTime;
unsigned long timeToMove;
void setup(void)
{
pinMode(MISCHER_OPEN, OUTPUT);
pinMode(MISCHER_CLOSE, OUTPUT);
pinMode(ZONENVENTIL, OUTPUT);
pinMode(PUMPE, OUTPUT);
digitalWrite(MISCHER_OPEN, LOW);
digitalWrite(MISCHER_CLOSE, LOW);
digitalWrite(ZONENVENTIL, LOW);
digitalWrite(PUMPE, LOW);
//Serial.begin(9600);
sensors.begin();
int numberOfDevices = sensors.getDeviceCount();
Serial.print(numberOfDevices, DEC);
Serial.println(" Devices gefunden.");
Serial.print("Parasite power ist ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
sensors.setResolution(sensor0, RESOLUTION);
sensors.setResolution(sensor1, RESOLUTION);
sensors.setResolution(sensor2, RESOLUTION);
sensors.setResolution(sensor3, RESOLUTION);
sensors.setResolution(sensor4, RESOLUTION);
sensors.setResolution(sensor5, RESOLUTION);
sensors.setWaitForConversion(false);
}
//Falls die Temperatur des Pufferspeichers 3° groesser als die des Ruecklaufs wird das Zonenventil geoeffnet
//wenn es nur noch 1° groesser ist wieder geschlossen
void zonenventilSchalten(void)
{
Serial.print("Pufferspeicher oben - Gemeinsamer Ruecklauf: ");
Serial.println(tempPSOben - tempGemeinsamerRuecklauf);
if((tempPSOben - tempGemeinsamerRuecklauf) >= 6)
{
digitalWrite(ZONENVENTIL, HIGH);
Serial.println("Oeffne Zonenventil.");
}
if ((tempPSOben - tempGemeinsamerRuecklauf) <= 3)
{
digitalWrite(ZONENVENTIL, LOW);
Serial.println("Schliesse Zonenventil.");
}
}
//Mischer faehrt auf, wenn Temperatur in der Ruecklaufanhebung groesser als die angestrebte Temperatur ist.
//Mischer faehrt zu, wenn Temperatur in der Ruecklaufanhebung kleiner als die angestrebte Temperatur ist.
//Mischer braucht 140 Sekunden, um von komplett geschlossen auf komplett geoeffnet zu fahren.
//Je groesser der Unterschied zwischen aktueller und angestrebter Temperatur ist,
//desto laenger faehrt der Mischer.
void mischerSchalten(void)
{
if(!currentlyMoving && tempRuecklaufanhebung > (DESIRED_TEMP + MISCHERTEMPERATURE_VARIANCE))
{
startTime = millis();
timeToMove = (tempRuecklaufanhebung - DESIRED_TEMP) * 500;
Serial.print("Mischer faehrt fuer ");
Serial.print(timeToMove);
Serial.println(" Millisekunden auf.");
currentlyMoving = true;
digitalWrite(MISCHER_OPEN, HIGH);
}
if(!currentlyMoving && tempRuecklaufanhebung < (DESIRED_TEMP - MISCHERTEMPERATURE_VARIANCE))
{
startTime = millis();
timeToMove = (DESIRED_TEMP - tempRuecklaufanhebung) * 500;
Serial.print("Mischer faehrt fuer ");
Serial.print(timeToMove);
Serial.println(" Millisekunden zu.");
currentlyMoving = true;
digitalWrite(MISCHER_CLOSE, HIGH);
}
}
void loop(void)
{
//Testet so oft wie moeglich (sinnvoll bspw. fuer Alarmtemperatur)
if (allowTempRequest)
{
sensors.requestTemperatures();
allowTempRequest = false;
lastTempRequest = millis();
}
//Wenn genug Zeit vergangen ist um die Temperatur der Sensoren auszulesen
if (millis() - lastTempRequest >= CONVERSION_DELAY)
{
tempPSOben = sensors.getTempC(sensor0);
tempPSMitte = sensors.getTempC(sensor1);
tempPSUnten = sensors.getTempC(sensor2);
tempGemeinsamerRuecklauf = sensors.getTempC(sensor3);
tempRuecklaufanhebung = sensors.getTempC(sensor4);
tempOfen = sensors.getTempC(sensor5);
allowTempRequest = true;
}
//Alle 10 Sekunden
if(millis() - lastIteration > 10000)
{
Serial.print("Temperatur Pufferspeicher oben: ");
Serial.println(tempPSOben);
Serial.print("Temperatur gemeinsamer Ruecklauf ist: ");
Serial.println(tempGemeinsamerRuecklauf);
Serial.print("Temperatur Ruecklaufanhebung ist: ");
Serial.println(tempRuecklaufanhebung);
Serial.print("Temperatur Ofen ist: ");
Serial.println(tempOfen);
if(tempOfen > 45)
{
digitalWrite(PUMPE, HIGH);
mischerSchalten();
Serial.println("Pumpe an");
}
else
{
digitalWrite(PUMPE, LOW);
Serial.println("Pumpe aus");
}
zonenventilSchalten();
lastIteration = millis();
//Falls der Mischer lange genug geoeffnet bzw. geschlossen wurde wieder ausschalten
if(currentlyMoving && (millis() - startTime > timeToMove))
{
digitalWrite(MISCHER_OPEN, LOW);
digitalWrite(MISCHER_CLOSE, LOW);
Serial.println("Mischer stoppt.");
currentlyMoving = false;
}
}
}