/* Liest die Kippschalter aus */ void GetKippSchalter() { static int old_kipp1 = 0x11; static int old_kipp2 = 0x22; static int old_kipp3 = 0x33; int temp; pinMode(KIPP_NETZBETRIEB, INPUT_PULLUP); pinMode(KIPP_AUTOMATIC, INPUT_PULLUP); pinMode(KIPP_MICRO_ONLY_NETZ, INPUT_PULLUP); /* Kippschalter aus lesen */ temp = digitalRead(KIPP_NETZBETRIEB); if (temp != old_kipp1) { Flags.Kipp_BatterieON = !temp; Flags.Kipp_Switched_BatterieON = true; old_kipp1 = temp; } temp = digitalRead(KIPP_MICRO_ONLY_NETZ); if (temp != old_kipp2) { Flags.Kipp_Inverter = !temp; Flags.Kipp_Switched_Inverter = true; old_kipp2 = temp; } /* Automatik kann nicht geblocked werden */ temp = digitalRead(KIPP_AUTOMATIC); if (temp != old_kipp3) { Flags.Kipp_Automatic = !temp; Flags.Kipp_Switched_Automatic = true; old_kipp3 = temp; } } void KippManager() { /* ---------------------------------------------- */ /* Unzulässig: Batterie und Inverter zusammen */ if (Flags.Kipp_BatterieON && Flags.Kipp_Inverter) { Piepser(500); return; } /* Unzulässig: Automatic und Inverter zusammen */ if (Flags.Kipp_Automatic && Flags.Kipp_Inverter) { Piepser(500); return; } /* Automatik */ if (Flags.Kipp_Switched_Automatic) { Piepser(100); Flags.BatteryCharged = false; tim[0].val = 0; Flags.Kipp_Switched_Automatic = false; if (Flags.Kipp_Automatic) { /* Kipp Automatik in AKTIV Stellung */ debugln("Kippmanager: Automatic Mode ON"); Flags.IsAutomaticMode = true; return; } else { /* Kipp Automatik zurück in Ruhestellung */ debugln("Kippmanager: Automatic Mode OFF"); Flags.IsAutomaticMode = false; /* Schalter simulieren */ Flags.Kipp_Switched_BatterieON = true; Flags.Kipp_Switched_Inverter = true; return; } } /* Batteriebetrieb und Netz Betrieb Wandler */ if (Flags.Kipp_Switched_BatterieON) { Piepser(100); Flags.Kipp_Switched_BatterieON = false; if (Flags.Kipp_BatterieON) { Switch_NetzBatt(BATTERIEBETRIEB); } else { Switch_NetzBatt(NETZBETRIEB); } return; } /* Inverter Kippschalter auswerten */ if (Flags.Kipp_Switched_Inverter) { Flags.Kipp_Switched_Inverter = false; if (Flags.Kipp_Inverter) { if (Data.UBatt >= BATT_LOAD_LIMIT) { EnableMikroInverter(ON); } else { Piepser(1000); } } else { EnableMikroInverter(OFF); } return; } } /* Setze die Uhrzeit nach NTP */ void SetRTC(struct tm *zeit) { rtc.setClockMode(false); rtc.setYear(zeit->tm_year + 1900 - 2000); rtc.setMonth(zeit->tm_mon); rtc.setDate(zeit->tm_mday); rtc.setDoW(zeit->tm_wday); rtc.setHour(zeit->tm_hour); rtc.setMinute(zeit->tm_min); rtc.setSecond(zeit->tm_sec); } void Piepser(uint16_t dauer) { digitalWrite(PIEPSER, 1); delay(dauer); digitalWrite(PIEPSER, 0); } void SetLEDs() { /* LEDS setzen */ uint8_t gr, ge, rt; ledcWrite(LED_CHANNEL_GRUEN, 0); ledcWrite(LED_CHANNEL_GELB, 0); ledcWrite(LED_CHANNEL_ROT, 0); /* LEDS nachts dimmen */ if (IsTageslicht()) { gr = 7; ge = 8; rt = 12; } else { gr = 3; ge = 4; rt = 6; } if (Data.PSolar > 50) { ledcWrite(LED_CHANNEL_GRUEN, gr); ledcWrite(LED_CHANNEL_ROT, 0); } else { ledcWrite(LED_CHANNEL_GRUEN, 0); ledcWrite(LED_CHANNEL_ROT, rt); } if (Flags.IsBatterieBetrieb) { ledcWrite(LED_CHANNEL_GELB, ge); } else ledcWrite(LED_CHANNEL_GELB, 0); } /* Mikroinverter ein/aus Wenn eingeschaltet trennt er den MPPT vom Solarstrom ab */ void EnableMikroInverter(int zustand) { static int nowstate = 0x99; if (nowstate != zustand) { nowstate = zustand; if (zustand == ON) { /* Nur einschalten wenn Batterie über 2/3 voll ist */ debugln("EnableMikroInverter: ON"); digitalWrite(REL_SUNTOINVT, 1); /* Solarstrom auf Inverter schalten */ RelStat.Rel_SUNTOINVT_Shadow = 1; Flags.IsMikroinverterMode = true; } if (zustand == OFF) { debugln("EnableMikroInverter: OFF"); digitalWrite(REL_SUNTOINVT, 0); /* Strom auf MPPT Regler schalten */ RelStat.Rel_SUNTOINVT_Shadow = 0; Flags.IsMikroinverterMode = false; } } } /* Umschalter Netzbetrieb / Batteriebetrieb Es werden 2 relais umgeschaltet: Stromweiche und 12V Inverter Ruhezustand: Strompfad Relais auf 12V Inverter 12V Inverter ist eingeschaltet */ void Switch_NetzBatt(int zustand) { static int nowstate = 0x55; if (nowstate != zustand) { nowstate = zustand; if (zustand == NETZBETRIEB) { debugln("Switch_NetzBatt: NETZBETRIEB"); digitalWrite(REL_NETZBATT, 0); // Auf Netzbetrieb umschalten RelStat.Rel_NETZBATT_Shadow = 0; delay(50); digitalWrite(REL_INVERTER_12V, 0); // Inverter ausschalten RelStat.Rel_INVERTER_12V_Shadow = 0; Flags.IsNetzBetrieb = true; Flags.IsBatterieBetrieb = false; } if (zustand == BATTERIEBETRIEB) { debugln("Switch_NetzBatt: BATTERIEBETRIEB"); digitalWrite(REL_INVERTER_12V, 1); // 12V Inverter einschalten RelStat.Rel_NETZBATT_Shadow = 1; delay(4000); digitalWrite(REL_NETZBATT, 1); // Auf Inverterstrom umschalten RelStat.Rel_INVERTER_12V_Shadow = 1; Flags.IsNetzBetrieb = false; Flags.IsBatterieBetrieb = true; } } } /* Schaltet den 12V Wechselrichtr ON / OFF Ruhezustand: Wechselrichter ist ausgeschaltet */ void WR12V_Enable(int zustand) { pinMode(REL_INVERTER_12V, OUTPUT); if (zustand == ON) { digitalWrite(REL_INVERTER_12V, 1); RelStat.Rel_INVERTER_12V_Shadow = 1; } if (zustand == OFF) { digitalWrite(REL_INVERTER_12V, 0); RelStat.Rel_INVERTER_12V_Shadow = 0; } } /* -------------------------------------------------------------- */ /* ---------------- Daten ins EEPROM wegschreiben -------------- */ /* -------------------------------------------------------------- */ /* Mehr Infos hier* https://deepbluembedded.com/esp32-eeprom-library-tutorial-arduino/ */ /* Schreibe Daten ins ESP32 Flash */ void SaveDataToFlash(void *data, size_t anzahl) { EEPROM.writeBytes(0, (uint8_t *)data, anzahl); EEPROM.commit(); } void ReadDataFromFlash(void *target, size_t anzahl) { EEPROM.readBytes(0, (uint8_t *)target, anzahl); } /* -------------------------------------------------------------- */ /* ---------------- Daten ins EEPROM wegschreiben -------------- */ /* -------------------------------------------------------------- */ /* ------------- Helpers ----------------- */ void PrintTime() { debug(String(Zeit.tm_mday) + "." + String(Zeit.tm_mon) + "." + String(Zeit.tm_year) + " "); debug(String(Zeit.tm_hour) + ":"); if (Zeit.tm_min < 10) debug("0"); debug(String(Zeit.tm_min) + ":"); if (Zeit.tm_sec < 10) debug("0"); debug(Zeit.tm_sec); debugln(" Uhr"); }