====== Solar Akku Lader ======
Der Quellcode zum Projekt ist auf GitHub verfügbar https://github.com/mschubi72/ESP32_Laderegler
Derzeitiger Aufbau:
{{:elektronik:solar:img_4341.jpg?direct&600|}}
===== Vorgedanken =====
Seit Anfang 2022 habe ich eine Balkonsolaranlage. Leider wird relativ viel Energie eingespeist, deshalb muss ein Zwischenspeicher her.
Fertige Lösungen sind zu teuer, so dass mein Solarlader ein reines DIY Projekt wird.
Folgende Anforderungen:
* Keine direkte Aufladung durch Solarpanel
* standortunabhängig innerhalb der Wohnungsstromkreise (Keller?)
* nur die Energie, die eingespeist werden würde, zum Laden nehmen (leistungsgesteuerter Lader)
* über Nacht die Grundlast aus dem Akku bereitstellen
* 24V oder 48V System, um Ströme geringer zu halten
* über ESP32 und mein Homeassistant System gesteuert
==== Komponenten ====
* die Steuerung übernimmt ein ESP32
* Abfrage der eingespeisten Leistung via MQTT vom Homeassistant
* ein DPM8624 übernimmt die leistungsgeregelte Ladung des Akkus
* da max. 60V Eingangsspannung erlaubt sind, kommt noch ein Schaltreglernetzteil davor
* DPM gesteuert über RS485
* als Akku kommen LiFePo Zellen zum Einsatz, entweder 2 x 12V oder 1 x 24V
* die Umwandlung Akku->Netz übernimmt ein "billig" Solarinverter
* das Ein-/Ausschalten des Ladenetzteils oder des Einspeiseinverters übernehmen zwei Schukodosen, die per WLAN schaltbar sind
* Überbleibsel aus einem anderen Projekt, Eigenbau mit umgeflashtem Dual-Shelly
* die Spannung des Akkus wird mit einem ADS1115 gemessen
* die Messwerte des ADC vom ESP streuen mir zu sehr
* die Temperatur des Akkus wird mit DS18S20 gemessen
==== Funktionale Übersicht ====
{{:elektronik:solar:uebersicht_solarladereinspeiser.drawio.png?direct&700|}}
===== Umsetzung =====
Ich habe angefangen die Software zu schreiben. Da ich nicht der geborene C/C++ Entwickler bin, sicher etwas Kraut und Rüben, aber es soll ja einfach nur funktionieren. Den Softwarestand checke ich ab und zu mal bei GitHub ein (https://github.com/mschubi72/ESP32_Laderegler).
Auch bei der Hardwareanschaffung und Verkabelung hat sich was getan. Die Hauptkomponenten sind verdrahtet.
==== Software ====
=== Zustände Laderegler am Tag ===
Am Tag muss der Laderegler entscheiden, wann und wie viel geladen wird. Ich nehme hier einfach Übergänge von Zuständen an.
Faktoren sind die Solarstromerzeugung, Solarstromüberschuß (Einspeisung ins öffentliche Netz), Ladeleistung zum Akku.
Da der ganze Ladeprozess doch einige Verluste mit sich bringt, lege ich die Schwelle bei mehr als 20 Watt Überschuss an.
Unabhängig vom State wird bei voller Batterie der Ladevorgang abgeschaltet (separate Prüfung).
Daraus ergeben sich folgende Zustände (states):
^ State # ^ Solarstrom ^ Einspeisung ^ Ladeleistung ^ Bemerkung ^
| State-0 | 0 | <= 0 | 0 | Wenn kein Solarstrom, dann alles andere egal |
| State-1 | >0 | <= 0 | 0 | Keine Einspeisung, Keine Ladeleistung |
| State-2 | >0 | >0 & < 20W | 0 | es wird unterhalb Schwelle eingespeist, keine Ladeleistung |
| State-3 | >0 | >20W | 0 | Einspeisung oberhalb Schwelle, aber noch keine Ladung |
| State-4 | >0 | <= 0 | >0 | Keine Einspeisung, es wird aber noch geladen |
| State-5 | >0 | >0 & < 20W | >0 | Einspeisung unter Schwelle, wird geladen->Ideal Status |
| State-6 | >0 | >20W | >0 | Einspeisung oberhalb Schwelle, es wird geladen->Ladeleistung steigern |
Folgende Übergänge sind möglich:
^ State old ^ state new ^ Bemerkung ^ Action ^
| State-0 | State-0 | keine Änderung | |
| ::: | State-1 | Solarstrom, aber kein Überschuss->keine Ladeleistung | |
| ::: | State-2 | Solarstrom, Überschuss unter Schwelle->keine Ladeleistung | |
| ::: | State-3 | Solarstrom, Überschuss über Schwelle->beginn mit laden, aber Ladeleistung ist noch null, da gerade eingeschalten | Laden mit kleinster Leistung beginnen |
| State-1 | State-0 | | |
| ::: | State-1 | | |
| ::: | State-2 | | |
| ::: | State-3 | | Laden mit kleinster Leistung beginnen |
| State-2 | State-0 | | |
| ::: | State-1 | | |
| ::: | State-2 | | |
| ::: | State-3 | |Laden mit kleinster Leistung beginnen |
| State-3 | State-0 | | |
| ::: | State-1 | | |
| ::: | State-2 | | |
| ::: | State-3 | Wenn genug Überschuss, dann Laden einschalten, sonst Fehler | |
| ::: | State-4 | Laden wurde begonnen, gibt keine Einspeisung mehr| Laden abstellen |
| ::: | State-5 | Laden wurde begonnen, Einspeisung unter Schwelle-> Ladeleistung OK | |
| ::: | State-6 | Laden wurde begonnen, Einspeisung über Schwelle | Ladeleistung vergrößern |
| State-4 | State-4 | Es wird mit zu viel Power geladen | Ladeleistung verringern |
| ::: | State-5 | Laden OK | |
| ::: | State-6 | noch Überschuss | Ladeleistung erhöhen |
| ::: | State-0 bis 3 | Ladeleistung kann nicht weiter verringert werden | Laden beenden |
| State-5 | State-4 | Es wird mit zu viel Power geladen | Ladeleistung verringern |
| ::: | State-5 | Laden OK | |
| ::: | State-6 | Gibt zu viel Überschuss | Ladeleistung vergrößern |
| State-6 | State-4 | Es wird mit zu viel Power geladen | Ladeleistung verringern |
| ::: | State-5 | Laden OK | |
| ::: | State-6 | Ladeleistung erhöhen | Ladeleistung erhöhen |
Oder als mehr oder weniger sinnvolles Diagramm:
{{:elektronik:solar:statediagramm.drawio.png?direct&500|}}
=== Sonoff Dual R3 ===
Zum Erfassen der Ladeleistung und Einspeisleistung und dem entsprechenden Schaltvorgängen nutze ich einen Sonoff Dual R3, der mit ESPHome umgeflashed wurde. Der Webserver ist auch enabled. Somit Schalte ich die Ausgänge einfach per REST API POST Kommandos. Die Leistungsübermittlung etc. aber weiterhin über die ESP32 API direkt zum Homeassistant.
Wichtig ist die Leiterplattenversion. Ab Version 2.0 des Dual R3 (wie bei mir) wird der BL0939 Chip zum Erfassen von Strom/Spannung/Leistung genutzt. Vorherige Revisionen den CSE7761. (siehe https://esphome.io/devices/sonoff.html#sonoff-dual-r3-v1-x-v2-x)
Folgendes YAML File für ESPHome:
substitutions:
devicename: lader-power
long_devicename: Sonoff DualR3 Lader
#
# Dual r3 V2.0
#
esphome:
name: $devicename
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# level: VERY_VERBOSE
# Enable Home Assistant API
api:
ota:
password: "0a46d9b044d9acb408d44bf02d620ffb"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Lader-Power Fallback Hotspot"
password: "7jnCyGWRuDsb"
captive_portal:
web_server:
port: 80
uart:
tx_pin: GPIO25
rx_pin: GPIO26
baud_rate: 4800
parity: NONE
stop_bits: 2
sensor:
- platform: wifi_signal
name: "$long_devicename WiFi Signal"
update_interval: 60s
- platform: bl0939
update_interval: 5s
voltage:
name: "$devicename Voltage"
current_1:
name: "$devicename Current OUT"
current_2:
name: "$devicename Current IN"
active_power_1:
name: "$devicename Power OUT"
active_power_2:
name: "$devicename Power IN"
output:
- platform: gpio
pin: GPIO27
id: relay1
- platform: gpio
pin: GPIO14
id: relay2
switch:
- platform: output
name: "$devicename relay OUT"
output: relay1
id: sw1
- platform: output
name: "$devicename relay IN"
output: relay2
id: sw2
status_led:
pin:
number: GPIO13
inverted: yes
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: True
name: "$devicename button"
on_press:
- logger.log: "$devicename button"
- switch.toggle: sw2
- platform: gpio
pin:
number: GPIO32
mode: INPUT_PULLUP
inverted: True
name: "$devicename switch OUT"
on_press:
- logger.log: "$devicename switch OUT"
- switch.toggle: sw1
- platform: gpio
pin:
number: GPIO33
mode: INPUT_PULLUP
inverted: True
name: "$devicename switch IN"
on_press:
- logger.log: "$devicename switch IN"
- switch.toggle: sw2
Die Abfrage der zwei Relais erfolgt über REST API GET
http:///switch/lader-power_relay_in
Es wird einfach der Componenten Name genommen und alle Leerzeichen durch Unterstriche ersetzt werden. Deshalb "Lader-Power Relay In" zu "lade-power_relay_in".
Der JSON Returnwert sieht dann so aus:
{
"id": "switch-lader-power_relay_in",
"value": false,
"state": "OFF"
}
Geschaltet wird mit einem Postrequest:
http:///switch/lader-power_relay_in/turn_on
http:///switch/lader-power_relay_in/turn_off
http:///switch/lader-power_relay_in/toggle
==== Hardware ====
=== "Schaltkasten" ===
Derzeitige Ansicht:
{{:elektronik:solar:schaltkasten.jpg?direct&700|}}
Nicht wundern, dass die Akkus noch in Folie sind. Durch die Tüten lassen sie sich sehr gut rausheben. War übrigens selber über das Gewicht der LiPOFe positiv überrascht.
=== ESP32 ===
Meine ESP32 "Testumgebung" zum Entwickeln...
{{:elektronik:solar:esp32_raw.jpg?direct&700|}}
Links oben das Modul zur RS485 Kommunikation, in der Mitte oben der ADS1115 AD Wandler. Das Display ist noch "raw" - aktuell erzeugte Solarleistung, aktueller Verbrauch laut Zähler, Icon Ladezustand Akku, Spannung Akku (auf dem Foto eine Testfakewert), am Ende das Symbol, wenn geladen wird.