// Solar Warmwasserboiler Regent 1500W Stufen 240W / 360W / 480W #include #include // A4=SDA, A5=SCL https://arduinogetstarted.com/tutorials/arduino-lcd-i2c LiquidCrystal_I2C lcd(0x27, 16, 2); //Brabander I2C address 0x27, 16 column and 2 rows int resetoutpin = 7; unsigned long startreset; unsigned long tagezaehler; int netzpin = 8; bool netzeingang; unsigned long netzeingangist; unsigned long netzeingangstart; unsigned long netzentprellt; // Insel int inselpin = 9; bool inselbetrieb; // Multivibrator / Taktgeber unsigned long mvstart; unsigned long mvist; unsigned long mvinterval = 5000; // alle 5Sek. ein Takt bool mv; bool mvvorher; bool mvpuls; // Messeingänge int phasedpin = A0; int phaseapin = A1; int phasebpin = A2; int phasecpin = A3; int phaselpin = A6; int phaseipin = A7; int werta; int wertb; int wertc; int wertd; int werti; int wertl; int wertp; int pa; // rechtes Solar-Panel int pb; // mittleres Solar-Panel int pc; // linkes Solar-Panel int pd; // Eigenverbrauch Netzbetrieb int pi; // Eigenverbtauch Inselbetrieb int pl; // Belastung int p; // Leistung allgemein int pges; // Leistung aller Solar-Panele zusammen int plast; // berechneter maximalwert für die Last int ertrag; int stufe; // eingestellte Leistung des Heizgerätes int richtwertniedrig = 240; int richtwertmittel = 360; int richtwerthoch = 480; int niedrig; int mittel; int hoch; // Relais bool last; bool relz; // hohe Last bool relzvorher; bool rely; // mittlere Last bool relyvorher; bool relx; // Freigabe für Last allgemein, kleine Last bool relxvorher; bool umschalten; int relzpin = 4; int relypin = 3; int relxpin = 2; bool wartenyz; bool wartenyzvorher; unsigned long startwyz; unsigned long istwyz; bool wartenx; unsigned long startwx; unsigned long istwx; int testpinniedrig = 10; int testpinmittel = 11; int testpinhoch = 12; // hanfun für FritzT Dect int zahl; int hanfun; // Testausgang int boardledpin = 13; void setup() { Serial.begin(9600); lcd.begin(16, 2); lcd.init(); lcd.backlight(); // Beleuchtung an lcd.setCursor(0, 0); // Stelle, Zeile lcd.print("L M R "); // Solarpanel Links, Mitte, Rechts lcd.setCursor(0, 1); // Stelle, Zeile lcd.print(" "); plast = 0; pinMode(resetoutpin,OUTPUT); digitalWrite(resetoutpin,HIGH); pinMode(relxpin,OUTPUT); digitalWrite(relxpin,LOW); pinMode(relypin,OUTPUT); pinMode(relzpin,OUTPUT); pinMode(boardledpin,OUTPUT); niedrig = richtwertniedrig; mittel = richtwertmittel; hoch = richtwerthoch; pinMode(inselpin,INPUT_PULLUP); pinMode(testpinniedrig,INPUT_PULLUP); pinMode(testpinmittel,INPUT_PULLUP); pinMode(testpinhoch,INPUT_PULLUP); pinMode(netzpin,INPUT_PULLUP); } void loop() { // Reset alle 24h. Eine Sekunde vorher fällt Relais X ab. // Reset für arduino, nachts aktivieren. if(millis() > 86400000) { relx = LOW; } if(millis() > 86401000) { digitalWrite(resetoutpin,LOW); } // Reset Ende // Netz Frequenzmessung und Abwurf bei 51,5Hz netzeingang = digitalRead(netzpin); //Netzentprellung aktiv low if(netzeingang == HIGH) { netzeingangist =micros(); if(netzeingangist - netzeingangstart > 1000) { netzentprellt = LOW; } } else { netzeingangstart = micros(); netzentprellt = HIGH; } // Inselbetrieb inselbetrieb = !digitalRead(inselpin); // Multivibrator mvist = millis(); // Multivibrator if(mvist - mvstart >= mvinterval){ mvstart = mvist; if(mv == LOW){ mv = HIGH; } else { mv = LOW; } } // Multivibrator Ende if(mv != mvvorher){ // Multivibratorflanken mvpuls = HIGH; strommessen(); leistung(); displaybeschreiben(); } else{ mvpuls = LOW; } mvvorher = mv; if(mvpuls == HIGH){ strommessen(); leistung(); displaybeschreiben(); } // Umschalten der Last auf fritz-dect-hanfun if((last && mvpuls) == HIGH) { // Zählen der Taktimpulse zahl = (zahl + 1); } if(last == LOW) { zahl = 0; } if((zahl > 2) && (pl < 100 )) { hanfun = HIGH; } else { hanfun = LOW; } // Relaissteuerung // Relais X fällt ab während die Relais Y und Z umschalten. if((relx != relxvorher) || (rely != relyvorher) || (relz != relzvorher)) { umschalten = HIGH; } else { umschalten = LOW; } relxvorher = relx; relyvorher = rely; relzvorher = relz; if(umschalten == LOW) { istwyz = millis(); if(istwyz - startwyz > 200) { wartenyz = LOW; } } else { startwyz = millis(); wartenyz = HIGH; } if(umschalten == LOW) { istwx = millis(); if(istwx - startwx > 400) { wartenx = LOW; } } else { startwx = millis(); wartenx = HIGH; } digitalWrite(relxpin,(relx && !wartenx)); if((wartenyz != wartenyzvorher) && (wartenyzvorher == HIGH)) { digitalWrite(relypin,rely); digitalWrite(relzpin,relz); } wartenyzvorher = wartenyz; // Testpin 13 boardled if(inselbetrieb == LOW) { digitalWrite(boardledpin,netzentprellt); } else { digitalWrite(boardledpin,LOW); } } void strommessen() { werta = analogRead(phaseapin); wertb = analogRead(phasebpin); wertc = analogRead(phasecpin); wertd = analogRead(phasedpin); werti = analogRead(phaseipin); wertl = analogRead(phaselpin); } void leistung() { // für R=3K3 // 0,5A 0,47V // 0,5A*230V=115W // (0,47/5V)*1023=94 // 2,5A 4,20V // 2,5A*230V=575W // (4,20V/5V)*1023=859 if(werta >= 96 && werta <= 859){ pa = map(werta, 96, 859, 115, 575); } else { wertp = werta; listep(); pa = p; } if(wertb >= 96 && wertb <= 859) { pb = map(wertb, 96, 859, 115, 575); } else { wertp = wertb; listep(); pb = p; } if(wertc >= 96 && wertc <= 859) { pc = map(wertc, 96, 859, 115, 575); } else { wertp = wertc; listep(); pc = p; } if(wertd >= 96 && wertd <= 859) { pd = map(wertd, 96, 859, 115, 575); } else { wertp = wertd; listep(); pd = p; } if(wertl >= 96 && wertl <= 859){ pl = map(wertl, 96, 859, 115, 575); } else { wertp = wertl; listep(); pl = p; } if(werti >= 96 && werti <= 859){ pi = map(werti, 96, 859, 115, 575); } else { wertp = werti; listep(); pi = p; } // Anpassung der Stufen an die gemessenen Werte if((stufe == niedrig) && (pl >= 190) && (pl < 300)) { niedrig = pl; } else { niedrig = richtwertniedrig; } if((stufe == mittel) && (pl >= 300) && (pl < 420)) { mittel = pl; } else { mittel = richtwertmittel; } if((stufe == hoch) && (pl >= 420) && (pl < 700)) { hoch = pl; } else { hoch = richtwerthoch; } pges = pa + pb + pc; // Gesamtscheinleistung der Solarpanele if(inselbetrieb == LOW){ ertrag = pges - pd; } else { ertrag = pges - pi; } if(digitalRead(testpinniedrig) == LOW) { relx = HIGH; rely = LOW; relz = LOW; stufe = niedrig; } else if(digitalRead(testpinmittel) == LOW) { relx = HIGH; rely = HIGH; relz = LOW; stufe = mittel; } else if(digitalRead(testpinhoch) == LOW) { relx = HIGH; rely = LOW; relz = HIGH; stufe = hoch; } else if(pd >= 700){ // schaltet nei großen Verbrauchern ab ertrag = 0; relx = LOW; rely = LOW; relz = LOW; stufe = 0; } else if(ertrag > niedrig && ertrag <= mittel) { relx = HIGH; rely = LOW; relz = LOW; stufe = niedrig; } else if(ertrag > mittel && ertrag <= hoch) { relx = HIGH; rely = HIGH; relz = LOW; stufe = mittel; } else if(ertrag > hoch) { relx = HIGH; rely = LOW; relz = HIGH; stufe = hoch; } else if(ertrag <= 0){ ertrag = 0; relx = LOW; rely = LOW; relz = LOW; stufe = 0; } else { relx = LOW; rely = LOW; relz = LOW; stufe = 0; } last = relx; } void displaybeschreiben() { // erste Zeile beschreiben lcd.setCursor(1, 0); // Stelle, Zeile lcd.print(" "); lcd.setCursor(1, 0); // Stelle, Zeile lcd.print(pc); // Links lcd.setCursor(6, 0); // Stelle, Zeile lcd.print(" "); lcd.setCursor(6, 0); // Stelle, Zeile lcd.print(pb); // Mitte lcd.setCursor(11, 0); // Stelle, Zeile lcd.print(" "); lcd.setCursor(11, 0); // Stelle, Zeile lcd.print(pa); // Rechts // zweite Zeile beschreiben if(inselbetrieb == LOW) { lcd.setCursor(0, 1); // Stelle, Zeile if(pd >= 700){ lcd.print("d> "); } else { lcd.print("d= "); } lcd.setCursor(2, 1); // Stelle, Zeile lcd.print(pd); } else { lcd.setCursor(0, 1); // Stelle, Zeile lcd.print("i= "); lcd.setCursor(2, 1); // Stelle, Zeile lcd.print(pi); } lcd.setCursor(6, 1); // Stelle, Zeile lcd.print(" "); lcd.setCursor(6, 1); // Stelle, Zeile if(relx && !rely && !relz) { lcd.print("n "); } else if(relx && rely && !relz) { lcd.print("m "); } else if(relx && !rely && relz) { lcd.print("h "); } else { lcd.print(" "); } lcd.setCursor(7, 1); // Stelle, Zeile if(hanfun == LOW) { lcd.print(stufe); // Leistung Regent Boiler } else { lcd.print(pl); } lcd.setCursor(11, 1); // Stelle, Zeile lcd.print(" "); lcd.setCursor(11, 1); // Stelle, Zeile lcd.print(pges); if(pges > 0){ lcd.backlight(); } else { lcd. noBacklight(); } } void listep() { if(wertp > 1022) { p = 700; } else if(wertp > 1013 && wertp < 1023) { p = 690; } else if(wertp > 999 && wertp < 1014) { p = 680; } else if(wertp > 985 && wertp < 1000) { p = 670; } else if(wertp > 972 && wertp < 986) { p = 660; } else if(wertp > 957 && wertp < 973) { p = 650; } else if(wertp > 942 && wertp < 958) { p = 640; } else if(wertp > 930 && wertp < 943) { p = 630; } else if(wertp > 915 && wertp < 931) { p = 620; } else if(wertp > 900 && wertp < 916) { p = 610; } else if(wertp > 892 && wertp < 901) { p = 600; } else if(wertp > 885 && wertp < 893) { p = 595; } else if(wertp > 874 && wertp < 886) { p = 590; } else if(wertp > 866 && wertp < 875) { p = 585; } else if(wertp > 859 && wertp < 867) { p = 580; } else if(wertp > 83 && wertp < 96) { p = 110; } else if(wertp > 75 && wertp < 84) { p = 105; } else if(wertp > 67 && wertp < 76) { p = 100; } else if(wertp > 59 && wertp < 68) { p = 95; } else if(wertp > 51 && wertp < 60) { p = 90; } else if(wertp > 44 && wertp < 52) { p = 85; } else if(wertp > 36 && wertp < 45) { p = 80; } else if(wertp > 29 && wertp < 37) { p = 75; } else if(wertp > 22 && wertp < 30) { p = 70; } else if(wertp > 16 && wertp < 23) { p = 65; } else if(wertp > 11 && wertp < 17) { p = 60; } else if(wertp > 6 && wertp < 12) { p = 55; } else if(wertp > 3 && wertp < 7) { p = 50; } else if(wertp > 1 && wertp < 4) { p = 45; } else{ p = 0; } }