Zirkulationspumpen Steuerung
Verfasst: Sa 16. Jul 2022, 14:17
Mein erstes Projekt war vor Jahren diese Zirkulationspumpen Steuerung. Ich hatte damals eine sehr alte Pumpe für die Warmwasser Zirkulation. Die konnte nur alle 30 Min. ein/aus geschalten werden. Als ich für diese Steuerung mal geplant habe, was ich brauche, habe ich festgestellt, dass die Pumpe ofter als alle 30 Min. laufen muss um die Wassertemp. zu halten, aber nur 2-3 Minuten lang laufen muss, bis die Rücklauftemperatur der Vorlauftemperatur angeglichen ist. Das ist natürlich eine sehr schöne Ersparnis, und warmes Wasser wirklich immer dann, wenn man es braucht.
Dieses Gerät kontrolliert die Warmwasser Zirkulations-Leitung. Ein Thermostat hängt an der Warmwasserleitung, direkt über dem Warmwasser Kessel Also am “Vorlauf”. Der zweite Thermostat hängt an der Warmwasser Rückleitung kurz vor der Heizung. Also am Rücklauf.
Das Gerät kontrolliert in der Zeit von 06:00 Uhr bis Abends um 23:00 Uhr immer Vorlauf und Rücklauf. Es vergleicht die beiden Temperaturen und wenn sie mehr als 7 Grad auseinander sind wird die Zirkulationspumpe eingeschalten. Wenn der Abstand nur noch drei Grad beträgt, wir diese wieder ausgeschalten. Ein zweiter Grund, warum diese Pumpe eingeschalten wird ist dann gegeben, wenn die Temperatur im Rücklauf nur noch 32 Grad beträgt. Ausgeschalten wird wieder bei 45 Grad. Das Display lässt sich mit dem Taster ein- und auschalten,
Die Winter-, Sommerzeit wird mit dem Schalter ausgewählt.
Ich habe jetzt mal schnell die Schaltung gezeichnet, und alles hier reingestellt. ich hoffe, dass ich nichts vergessen habe. Es ist wohl so 5 Jahre her, wo ich dieses Projekt gemacht habe. Damals habe ich noch keine Unterlagen dazu erstellt. Die Anlage habe ich schon gar nicht mehr, die ist im Haus geblieben, das wir verkauft haben.
Aber es dürfte schon passen. Die Anschlusspins am Arduino habe ich aus dem Programm entnommen, das sollte also auch passen.
Ich würde heute kein solches Relais mehr verwenden, sondern ein SSR. Hier ein Link dazu. Man muss dazu eine Kleinigkeit im Programm ändern, aber das ist nichts tragisches. Im Stand jetzt wird das Relais eingeschalten indem der Ausgang am Arduino auf LOW geschalten wird. Wird das Relais ausgeschalten, geht der Ausgang zum Relais auf HIGH. Also etwas gewöhnungsbedürftig. Bei dem SSR ist es anders herum. Ein ist Ausgang auf HIGH, und aus ist Ausgang auf LOW. Also wie es üblicherweise ist.
Hier ist mal das Programm dazu:
Und hier die Schaltung:
. Noch ein Bild vom Gerät:
.
Dieses Gerät kontrolliert die Warmwasser Zirkulations-Leitung. Ein Thermostat hängt an der Warmwasserleitung, direkt über dem Warmwasser Kessel Also am “Vorlauf”. Der zweite Thermostat hängt an der Warmwasser Rückleitung kurz vor der Heizung. Also am Rücklauf.
Das Gerät kontrolliert in der Zeit von 06:00 Uhr bis Abends um 23:00 Uhr immer Vorlauf und Rücklauf. Es vergleicht die beiden Temperaturen und wenn sie mehr als 7 Grad auseinander sind wird die Zirkulationspumpe eingeschalten. Wenn der Abstand nur noch drei Grad beträgt, wir diese wieder ausgeschalten. Ein zweiter Grund, warum diese Pumpe eingeschalten wird ist dann gegeben, wenn die Temperatur im Rücklauf nur noch 32 Grad beträgt. Ausgeschalten wird wieder bei 45 Grad. Das Display lässt sich mit dem Taster ein- und auschalten,
Die Winter-, Sommerzeit wird mit dem Schalter ausgewählt.
Ich habe jetzt mal schnell die Schaltung gezeichnet, und alles hier reingestellt. ich hoffe, dass ich nichts vergessen habe. Es ist wohl so 5 Jahre her, wo ich dieses Projekt gemacht habe. Damals habe ich noch keine Unterlagen dazu erstellt. Die Anlage habe ich schon gar nicht mehr, die ist im Haus geblieben, das wir verkauft haben.

Ich würde heute kein solches Relais mehr verwenden, sondern ein SSR. Hier ein Link dazu. Man muss dazu eine Kleinigkeit im Programm ändern, aber das ist nichts tragisches. Im Stand jetzt wird das Relais eingeschalten indem der Ausgang am Arduino auf LOW geschalten wird. Wird das Relais ausgeschalten, geht der Ausgang zum Relais auf HIGH. Also etwas gewöhnungsbedürftig. Bei dem SSR ist es anders herum. Ein ist Ausgang auf HIGH, und aus ist Ausgang auf LOW. Also wie es üblicherweise ist.
Hier ist mal das Programm dazu:
Code: Alles auswählen
// Die Zeit muss auf Winterzeit eingestellt werden.
// Also eine Std. zurück für Winterzeit
// Und der Schalter macht die Sommerzeit, eine Std. plus
// Minus auf Pin 10 ist Sommerzeit
// Pin 9 ist Display ein - aus
// Pin 8 ist das Pumpenrelais. Minus ist Relais ein, Plus ist aus !!
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h> // LCD Display
#include "Wire.h"
#define DS3231_ADDRESSE 0x68
LiquidCrystal_I2C lcd(0x27, 20, 4);
const int delayTimeM1 = 1000; // Zeit zur Temperatur Auswertung
unsigned long AktuellMilles;
unsigned long VorherMillesM1 = 0;
unsigned long einesekunde3 = 300; // 300 Millis entprellen der Taste
unsigned long sekundenablauf3 = 0;
unsigned long pumpenstart = 0;
unsigned long pumpenstop = 0;
unsigned long pumpenlaufzeit = 0;
unsigned long summelaufzeit = 0; //Normal 0
unsigned long laufzeit = 0;
int laufzeitminuten = 0;
byte merkerpumpenlauf = 0;
int laufzaehler = -1; //Normal -1
const unsigned long Baud_Rate = 9600;
const unsigned char One_Wire_Bus = 2; // Sensoren auf Pin 2
OneWire oneWire(One_Wire_Bus);
DallasTemperature sensoren (&oneWire);
byte sekunde, minute, stunde, wochentag, tag, monat, jahr;
int Anzahl_Sensoren = 0;
int is = 0; // Zähler für die Sensoren
int ia = 0; // Zähler für die Adressstellen 0-7
int Sensor = 0;
float Vorlauf = 0;
float Ruecklauf = 0;
float differenz = 0;
char txtbuf[20];
int pumpenrelais = 8;
int taster1 = 9;
int schalter1 = 10;
byte merker1 = 1;
byte tasterStatus1 = 0;
byte sommerzeit = 0;
byte startzaehler = 0;
DeviceAddress tempDeviceAddress; // Für die Adressausgabe
int numberOfDevices; // Für die Adressausgabe
//---------------------------------------------------------------------------
void setup()
{
Wire.begin();
sensoren.begin();
Serial.begin(Baud_Rate);
lcd.begin();
lcd.backlight();
lcd.clear();
pinMode(pumpenrelais, OUTPUT);
digitalWrite(pumpenrelais, HIGH);
pinMode(taster1, INPUT_PULLUP); // Display Licht
pinMode(schalter1, INPUT_PULLUP); // Sommer-/Winterzeit
// Anzahl der Sesoren ermitteln
Anzahl_Sensoren = sensoren.getDeviceCount();
// Ermitteln der Sensor-Adressen
for (is = 0; is < Anzahl_Sensoren; is++)
{
if (sensoren.getAddress(tempDeviceAddress, is))
{
Serial.println ();
printAddress(tempDeviceAddress);
}
}
}
//---------------------------------------------------------------------------
// Ausgabe der Sensor-Adressen
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t ia = 0; ia < 8; ia++)
{
if (deviceAddress[ia] < 16)
{
Serial.print("0"); //ist die Hex Adresse kleiner 16 dann erste Stelle eine "0"
}
Serial.print(deviceAddress[ia], HEX);
}
}
//---------------------------------------------------------------------------
void loop() {
AktuellMilles = millis(); // Die aktuellen Millis übergeben
// ------Taster für backlight ein / aus, mit 300 millis Tastenentprellung----
if (AktuellMilles - sekundenablauf3 >= einesekunde3) {
tasterStatus1 = digitalRead(taster1);
if (tasterStatus1 == LOW) {
merker1 = !merker1;
sekundenablauf3 = millis();
}
if (merker1 == 1) {
lcd.backlight(); // LCD Beleuchtung
}
if (merker1 == 0) {
lcd.noBacklight(); // LCD Beleuchtung
}
}
//--------------------------------Pumpe aus am Abend 22:05 Uhr----------
if ((stunde == 22) && (minute == 3) && (merkerpumpenlauf > 0)) {
lcd.setCursor (16, 3);
lcd.print ("PU+0");
digitalWrite(pumpenrelais, HIGH);
merkerpumpenlauf = 0;
pumpenstop = millis();
pumpenlaufzeit = pumpenstop - pumpenstart;
laufzeit = pumpenlaufzeit / 1000;
summelaufzeit = summelaufzeit + laufzeit;
laufzeitminuten = summelaufzeit / 60;
lcd.setCursor (8, 3);
lcd.print (" ");
if (laufzeitminuten < 10) {
lcd.setCursor (10, 3);
lcd.print (laufzeitminuten);
}
if ((laufzeitminuten < 100) && (laufzeitminuten > 9)) {
lcd.setCursor (9, 3);
lcd.print (laufzeitminuten);
}
if (laufzeitminuten > 99) {
lcd.setCursor (8, 3);
lcd.print (laufzeitminuten);
}
laufzaehler ++;
lcd.setCursor (11, 3);
lcd.print ("/");
lcd.setCursor (12, 3);
lcd.print (laufzaehler);
}
// ------------------------------ Anlauf 6 Uhr am Morgen ---------------
if (stunde == 6) {
if ((minute == 1) && (merkerpumpenlauf < 3)) {
lcd.setCursor (16, 3);
merkerpumpenlauf = 3;
lcd.print ("PU+"); lcd.print(merkerpumpenlauf);
digitalWrite(pumpenrelais, LOW);
lcd.setCursor (0, 3);
lcd.print (" ");
lcd.setCursor (0, 3);
lcd.print (laufzeitminuten);
summelaufzeit = 0;
laufzeitminuten = 0;
summelaufzeit = 240;
lcd.print ("/");
lcd.print (laufzaehler);
laufzaehler = 1;
}
//--------------------------------Anlauf Ende bei minuten=5------------------------
if ((minute == 5) && (merkerpumpenlauf == 3)) {
lcd.setCursor (16, 3);
lcd.print (" ");
digitalWrite(pumpenrelais, HIGH);
merkerpumpenlauf = 0;
laufzeitminuten = summelaufzeit / 60;
lcd.setCursor (8, 3);
lcd.print (" ");
if (laufzeitminuten < 10) {
lcd.setCursor (10, 3);
lcd.print (laufzeitminuten);
}
if ((laufzeitminuten < 100) && (laufzeitminuten > 9)) {
lcd.setCursor (9, 3);
lcd.print (laufzeitminuten);
}
if (laufzeitminuten > 99) {
lcd.setCursor (8, 3);
lcd.print (laufzeitminuten);
}
lcd.setCursor (11, 3);
lcd.print ("/");
lcd.setCursor (12, 3);
lcd.print (laufzaehler);
}
}
// -------------------------Temperatur Auswertung---------------------------
if (AktuellMilles - VorherMillesM1 >= delayTimeM1) {
VorherMillesM1 = AktuellMilles;
zeigeZeit(); // Zeit ausgeben
//Temperaturen Aulesen
sensoren.requestTemperatures();
// Hier werden die Sensoren ausgelesen und aufs Display gebracht
if (Sensor < 2) {
Sensor ++;
float temperatur = sensoren.getTempCByIndex(Sensor - 1);
if (Sensor == 1) {
lcd.setCursor (0, 1);
lcd.print ("Vorlauf");
lcd.setCursor (10, 1);
Vorlauf = temperatur;
lcd.print (Vorlauf);
lcd.setCursor (16, 1);
lcd.print ("\337C");
}
if (Sensor == 2) {
lcd.setCursor (0, 2);
lcd.print ("Ruecklauf");
lcd.setCursor (10, 2);
Ruecklauf = temperatur;
lcd.print (Ruecklauf);
lcd.setCursor (16, 2);
lcd.print ("\337C");
}
if (Sensor == Anzahl_Sensoren) Sensor = 0;
}
if (Vorlauf >= Ruecklauf) {
differenz = Vorlauf - Ruecklauf;
}
//--------------------Pumpe ein, wenn Differenz 6 Grad---------------------
if ((stunde > 5) && (stunde < 23)) {
if ((Vorlauf > Ruecklauf) && (Ruecklauf > 0)) {
if ((differenz >= 6) && (merkerpumpenlauf == 0)) {
lcd.setCursor (16, 3);
merkerpumpenlauf = 1;
lcd.print ("PU+"); lcd.print(merkerpumpenlauf);
digitalWrite(pumpenrelais, LOW);
pumpenstart = millis();
}
}
}
// /* ======================================================================
//-----------Temperatur-Rücklauf Kontrolle unter 34 Grad einschalten--------
if ((stunde > 5) && (stunde < 23)) {
if ((Vorlauf > Ruecklauf) && (Ruecklauf > 0)) {
if ((Ruecklauf < 34) && (merkerpumpenlauf == 0)) {
lcd.setCursor (16, 3);
merkerpumpenlauf = 2;
lcd.print ("PU+"); lcd.print(merkerpumpenlauf);
digitalWrite(pumpenrelais, LOW);
pumpenstart = millis();
}
}
}
//----------Temperatur-Rücklauf Kontrolle über 37 Grad ausschalten----------
if ((Ruecklauf >= 37) && (merkerpumpenlauf == 2)) {
lcd.setCursor (16, 3);
lcd.print (" ");
digitalWrite(pumpenrelais, HIGH);
merkerpumpenlauf = 0;
pumpenstop = millis();
pumpenlaufzeit = pumpenstop - pumpenstart;
laufzeit = pumpenlaufzeit / 1000;
summelaufzeit = summelaufzeit + laufzeit;
laufzeitminuten = summelaufzeit / 60;
lcd.setCursor (8, 3);
lcd.print (" ");
if (laufzeitminuten < 10) {
lcd.setCursor (10, 3);
lcd.print (laufzeitminuten);
}
if ((laufzeitminuten < 100) && (laufzeitminuten > 9)) {
lcd.setCursor (9, 3);
lcd.print (laufzeitminuten);
}
if (laufzeitminuten > 99) {
lcd.setCursor (8, 3);
lcd.print (laufzeitminuten);
}
laufzaehler ++;
lcd.setCursor (11, 3);
lcd.print ("/");
lcd.setCursor (12, 3);
lcd.print (laufzaehler);
}
// */ ======================================================================
//--------------------Pumpe aus, wenn Differenz 4 Grad----------------------
if ((differenz <= 4) && (merkerpumpenlauf == 1)) {
lcd.setCursor (16, 3);
lcd.print (" ");
digitalWrite(pumpenrelais, HIGH);
merkerpumpenlauf = 0;
pumpenstop = millis();
pumpenlaufzeit = pumpenstop - pumpenstart;
laufzeit = pumpenlaufzeit / 1000;
summelaufzeit = summelaufzeit + laufzeit;
laufzeitminuten = summelaufzeit / 60;
lcd.setCursor (8, 3);
lcd.print (" ");
if (laufzeitminuten < 10) {
lcd.setCursor (10, 3);
lcd.print (laufzeitminuten);
}
if ((laufzeitminuten < 100) && (laufzeitminuten > 9)) {
lcd.setCursor (9, 3);
lcd.print (laufzeitminuten);
}
if (laufzeitminuten > 99) {
lcd.setCursor (8, 3);
lcd.print (laufzeitminuten);
}
laufzaehler ++;
lcd.setCursor (11, 3);
lcd.print ("/");
lcd.setCursor (12, 3);
lcd.print (laufzaehler);
}
if (Ruecklauf >= Vorlauf) {
differenz = Ruecklauf - Vorlauf;
}
}
sommerzeit = digitalRead(schalter1);
}
// ---------------------------------------------------LOOP Ende -------------------------------------
void leseDS3231zeit(byte * sekunde, byte * minute, byte * stunde, byte * wochentag, byte * tag, byte * monat, byte * jahr) {
Wire.beginTransmission(DS3231_ADDRESSE);
Wire.write(0); // DS3231 Register zu 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESSE, 7); // 7 Byte Daten vom DS3231 holen
*sekunde = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*stunde = bcdToDec(Wire.read() & 0x3f);
*wochentag = bcdToDec(Wire.read());
*tag = bcdToDec(Wire.read());
*monat = bcdToDec(Wire.read());
*jahr = bcdToDec(Wire.read());
}
void zeigeZeit() {
leseDS3231zeit(&sekunde, &minute, &stunde, &wochentag, &tag, &monat, &jahr); // Daten vom DS3231 holen
switch (wochentag) {
case 1:
lcd.setCursor(0, 0);
lcd.print("Mo ");
break;
case 2:
lcd.setCursor(0, 0);
lcd.print("Di ");
break;
case 3:
lcd.setCursor(0, 0);
lcd.print("Mi ");
break;
case 4:
lcd.setCursor(0, 0);
lcd.print("Do ");
break;
case 5:
lcd.setCursor(0, 0);
lcd.print("Fr ");
break;
case 6:
lcd.setCursor(0, 0);
lcd.print("Sa ");
break;
case 7:
lcd.setCursor(0, 0);
lcd.print("So ");
break;
default:
break;
}
if (sommerzeit == 1) {
stunde = stunde + 1;
}
// sprintf( txtbuf, "%02d.%02d / %02d:%02d:%02d", tag, monat, stunde, minute, sekunde ); // ausgeben T.M. / H:M:S
lcd.setCursor(4, 0);
if (tag < 10) {
lcd.print("0");
}
lcd.print(tag);
lcd.print(".");
if (monat < 10) {
lcd.print("0");
}
lcd.print(monat);
lcd.print(". ");
if (stunde < 10) {
lcd.print("0");
}
lcd.print(stunde);
lcd.print(":");
if (minute < 10) {
lcd.print("0");
}
lcd.print(minute);
lcd.print(":");
if (sekunde < 10) {
lcd.print("0");
}
lcd.print(sekunde);
}
byte decToBcd(byte val) {
// Dezimal Zahl zu binary coded decimal (BCD) umwandeln
return ((val / 10 * 16) + (val % 10));
}
byte bcdToDec(byte val) {
// BCD (binary coded decimal) in Dezimal Zahl umwandeln
return ((val / 16 * 10) + (val % 16));
}
. Noch ein Bild vom Gerät:
.