Beim Aufräumen seiner Garage fiel dem Autor ein altes Solarpanel in die Hände, dem er kurzentschlossen mit einem Raspberry Pi per Modbus auf den Zahn fühlte.
Sie kennen das sicher: Man findet ein Bauteil und fängt direkt an, sich ein passendes Projekt zu überlegen. Als eine Aufräumaktion in der Garage ein altes Solarmodul zutage förderte, schossen mir voller Begeisterung einige Fragen durch den Kopf: “Was kann ich damit machen? Wie viel Watt wird es nach der langen Zeit noch bringen? Wie kann ich einen Laderegler mit Messeinrichtung bauen? Welche Teile brauche ich dafür?” Nach einer halben Stunde googeln, setzte zum Glück wieder das normale Denken ein, und es stellte sich schnell heraus, dass sich problemlos alles selbst bauen lässt. Allerdings gibt es schon für kleines Geld einen fertigen Laderegler mit integrierter Datenschnittstelle. Da lohnt es sich nicht, den Lötkolben anzuheizen, um das Paneel zu testen, ganz abgesehen vom zeitlichen Aufwand für einen Eigenbau.
Das Ziel des Projekts bestand darin, das gefundene Solarpanel zu testen und nach Möglichkeit wieder einzusetzen, etwa für das Licht in der Garage oder um den Akkuschrauber zu laden. Nach einer kurzen Suche stieß ich bei Amazon auf einen Solar-Laderegler [1], dessen Kennwerte zu dem Paneel passten. Der Regler kostet 60 Euro und verfügt über eine Datenschnittstelle, die mithilfe des Modbus-Protokolls die Werte ausgibt. Eine Dokumentation [2] der einzelnen Register im Regler findet sich im Internet. Der Regler liefert überraschend viele Messwerte und lässt sich vollständig über die Datenschnittstelle konfigurieren. Die Lektüre der Anleitung [3] zum Regler vermittelt einen genaueren Eindruck davon, welche Werte die einzelnen Register enthalten und was sie steuern.
Damit ich mir die Messwerte nicht nur auf der Konsole ansehen muss, setze ich einen Raspberry Pi zum Speichern und Visualisieren der Werte ein. Aus der Gewohnheit heraus verwende ich zur Datenspeicherung MariaDB und zum Visualisieren der Messwerte Grafana. Um die Messwerte aus dem Regler in den Raspberry Pi zu bekommen, benötige ich zusätzlich eine passende USB/RS-485-Datenleitung [4]. Sie schlägt bei Amazon mit 13 Euro zu Buche.
Was hinter Modbus steckt
Ursprünglich dazu entwickelt, die Kommunikation zwischen Industriesteuerungen (SPS) zu ermöglichen, hat sich das Modbus-Protokoll über die Jahre hinweg zu einem Quasi-Kommunikationsstandard für unzählige unterschiedliche Anlagen gemausert. Das nach dem Client-Server-Prinzip arbeitende Modbus-Protokoll existiert grundsätzlich in drei Varianten: Bei Modbus/TCP werden die Informationen über TCP/IP übertragen, bei Modbus/RTU fließen sie binär über eine serielle RS-485-Schnittstelle. Hinter Modbus/ASCII verbirgt sich eine Klartextvariante von Modbus/RTU. Das sorgt zwar für eine Lesbarkeit für den Menschen, doch leidet die Datenübertragungsrate darunter.
Die Kommunikation zwischen dem Laderegler und dem Raspberry Pi findet über Modbus/RTU statt. Dabei werden die Signale mit Spannungspegeln von ±1,5 bis ±6 Volt im Gegentakt übermittelt. Dementsprechend liegt auf einer Datenleitung ein nicht invertiertes Signal an und auf einer zweiten das invertierte. Üblicherweise sind die Leitungen mit A und B gekennzeichnet. Das Übertragungsverfahren hat den enormen Vorteil, kaum anfällig gegen Störungen von außen zu sein.
Die modernere Bezeichnung für die RS-485-Schnittstelle lautet EIA-485. Das Interface können Sie nicht nur zum Herstellen von Punkt-zu-Punkt-Verbindungen verwenden, sondern darüber auch komplette RS-485-Bussysteme aufbauen. Die Anzahl der Busteilnehmer hängt vom Eingangswiderstand der angeschlossenen Geräte ab und kann bis zu 255 betragen. Auf Distanzen bis zu 12 Metern lassen sich Daten mit bis zu 10 Mbit/s übertragen. Mit steigender Leitungslänge sinkt allerdings die Übertragungsrate, die maximale Leitungslänge beläuft sich auf 1200 Meter. Meistens betreibt man die RS-485-Schnittstelle im Halbduplexmodus über ein Adernpaar. Spendieren Sie ein zusätzliches Adernpaar, funktioniert auch der Vollduplexmodus. Allerdings unterstützen ihn nur wenige Modbus-Geräte.
Jeder Teilnehmer bei Modbus/RTU verfügt über eine eindeutige Adresse, über die er sich ansprechen lässt. Das Protokoll nutzt ein Byte zum Übertragen der Adresse, was Adressen zwischen 0 und 255 ermöglicht. Über die Adresse 0 senden Sie einen Broadcast an alle Geräte am Bus. Ein Busmaster steuert die Kommunikation und benötigt eine eigene Adresse. Zur Integritätsprüfung der übertragenen Daten dient der Cyclic Redundancy Check (CRC). Da das Modbus-Protokoll ursprünglich dazu gedacht war, Informationen zwischen Industriesteuerungen auszutauschen, kennt es nur vier spezielle Datentypen (siehe Tabelle “Modbus-Datentypen”).
|
Typ |
Bezeichnung |
Daten |
Funktionscode |
|---|---|---|---|
|
Einzelner Ein-/Ausgang |
Coil |
1 Bit |
01/05/15 |
|
Einzelner Eingang |
Discrete Input |
1 Bit |
02 |
|
Analoge Ein-/Ausgänge |
Holding Register |
16 Bit |
04 |
|
Analoge Eingänge |
Input Register |
16 Bit |
03/06/16 |
Funktionscodes bestimmen dabei, ob Daten gelesen oder geschrieben werden sollen. Außerdem lassen sich damit Sonderfunktionen aufrufen. Zudem geben die Codes vor, um welchen Datentyp es sich handelt. Falls Sie sich intensiver mit Modbus auseinandersetzen möchten, bildet die dazugehörige Homepage [5] einen guten Einstiegspunkt.
Den RasPi installieren
Das Einbinden eines Raspberry Pi läuft relativ entspannt ab. Als Betriebssystem kommt Pi OS Lite in der 64-Bit-Variante zum Einsatz, das für den geplanten Zweck vollkommen genügt. Im ersten Schritt schreiben Sie das Image mit dem Raspberry Pi Imager auf eine SD-Karte (Abbildung 1). Nachdem Sie den RasPi von der SD-Karte gebootet haben, führen Sie die Kommandos aus Listing 1 nacheinander aus, um die nötigen Programme und Bibliotheken zu installieren. Vor dem Integrieren von Grafana ist es sinnvoll, einen Blick auf dessen Webseite [6] zu werfen und zu klären, ob es eine neuere Version gibt.
Listing 1
RasPi einrichten
$ sudo apt update $ sudo apt upgrade $ sudo apt install mariadb-server libmariadb3 libmariadb-dev $ sudo apt-get install musl $ wget https://dl.grafana.com/oss/release/grafana_10.2.3_arm64.deb $ sudo dpkg -i grafana_10.2.3_arm64.deb $ sudo apt install pip $ mkdir solar $ python -m venv solar $ source ./solar/bin/activate $ cd solar/ $ pip install minimalmodbus $ pip install mariadb
Für das Python-Programm bereiten Sie ein virtuelles Environment (Zeile 9) vor. Darin installieren Sie die Minimal-Modbus-Bibliothek (Zeile 12) für Python sowie MariaDB (Zeile 13). Eine ausführliche Dokumentation zur Minimal-Modbus-Bibliothek bietet die Homepage [7] des Projekts.
Grafana ist nach der Installation noch nicht sofort aktiv. Das Installationsskript verrät Ihnen aber freundlicherweise, mit welchen Kommandos Sie den Server starten und ihn als Dienst in das System einbinden (Listing 2). Setzen Sie mit dem Tool raspi-config Ihr System auf die richtige Zeitzone und starten Sie den RasPi dann neu. Das gewährleistet, dass alle Dienste mit der richtigen Uhrzeit arbeiten.
Listing 2
Grafana verwalten
### Für Grafana einen automatischen Start per Systemd einrichten $ sudo /bin/systemctl daemon-reload $ sudo /bin/systemctl enable grafana-server ### Grafana manuell starten $ sudo /bin/systemctl start grafana-server
Datenbank
Zum Speichern der Messwerte dient in diesem Projekt MariaDB [8]. Bevor Sie allerdings vorschnell eine Datenbank aufsetzen, sollten Sie sich zunächst im Klaren darüber sein, was Sie überhaupt speichern und auswerten möchten. Für eine aussagekräftige Auswertung genügen hier die Spannungen und Ströme der Batterie, des Solarmoduls und des Ausgangs des Ladereglers. Daneben spielen noch der Ladezustand der Batterie und die Temperatur des Reglers eine wichtige Rolle.
Eine Übersicht der interessanten Werte samt den dazugehörigen Registern zeigt die Tabelle “Übersicht der ausgelesenen Register”. Hier gilt es zu beachten, dass der Wert für den Ladestrom der Batterie sich auf zwei Register aufteilt. Sämtliche in der Tabelle aufgeführten Register lassen sich mit dem Funktionscode 04 lesen. Die Kommandos aus Listing 3 erstellen für die Messwerte eine Datenbank mit zugehörigem User. Innerhalb der Datenbank legen Sie eine Tabelle an, die die Messwerte aufnimmt.
|
Bezeichnung |
Register |
Einheit |
|---|---|---|
|
PV Array Input Voltage |
|
Volt |
|
PV Array Input Current |
|
Ampere |
|
Load Voltage |
|
Volt |
|
Load Current |
|
Ampere |
|
Battery SOC |
|
Prozent |
|
Battery Voltage |
|
Volt |
|
Battery Current L |
|
Ampere |
|
Battery Current H |
|
Ampere |
|
Device Temperature |
|
Grad Celsius |
Listing 3
Datenbank und DB-User anlegen
$ sudo mariadb MariaDB [(none)]> CREATE DATABASE solar; Query OK, 1 row affected (0.002 sec) MariaDB [(none)]> GRANT ALL ON solar.* TO 'solar'@'localhost' IDENTIFIED BY 'solar'; Query OK, 0 rows affected (0.007 sec) MariaDB [(none)]> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.003 sec) MariaDB [(none)]> CONNECT solar; Connection id: 32 Current database: solar MariaDB [solar]> CREATE TABLE measurements(id INT auto_increment NOT NULL, PiT DATETIME NOT NULL, PV_Voltage FLOAT NULL, PV_Current FLOAT NULL, Load_Voltage FLOAT NULL, Load_Current FLOAT NULL, Battery_SOC FLOAT NULL, Battery_Voltage FLOAT NULL, Battery_Current FLOAT NULL, Temperature FLOAT NULL, CONSTRAINT solar_PK PRIMARY KEY (id)); Query OK, 0 rows affected, 1 warning (0.435 sec) MariaDB [solar]> exit
Programm
Wenn es schnell gehen soll, ist die Programmiersprache Python häufig das Mittel der Wahl. Listing 4 zeigt das Programm, mit dessen Hilfe Sie die Messwerte aus dem Laderegler auslesen und in der Datenbank ablegen. Es besteht aus vier Bereichen.
In den ersten vier Zeilen importieren Sie die nötigen Bibliotheken. Der zweite Codeblock von Zeile 6 bis 13 konfiguriert die Modbus-Schnittstelle. Im dritten Bereich ab Zeile 15 lesen Sie die Messwerte über die Schnittstelle aus und legen sie in Variablen ab. Den Batteriestrom lesen Sie aus zwei Registern und bauen die Einzelwerte dann zusammen (Zeile 24). Der restliche Code überträgt die gemessenen Werte in die Datenbank.
Listing 4
Regler auslesen (solar.py)
import minimalmodbus
import serial
import struct
import mariadb
instrument = minimalmodbus.Instrument( '/dev/ttyACM0', 1, debug=False )
instrument.serial.baudrate = 115200
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout = 0.05
instrument.mode = minimalmodbus.MODE_RTU
instrument.clear_buffers_before_each_transaction = True
PV_Voltage=instrument.read_register( 0x3100, 2, 4 )
PV_Current=instrument.read_register( 0x3101, 2, 4 )
Load_Voltage=instrument.read_register( 0x310C, 2, 4 )
Load_Current=instrument.read_register( 0x310D, 2, 4 )
Battery_SOC=instrument.read_register( 0x311A, 0, 4 )
Battery_Voltage=instrument.read_register( 0x331A, 2, 4 )
Battery_Current_L=instrument.read_register( 0x331B, 0, 4 )
Battery_Current_H=instrument.read_register( 0x331C, 0, 4 )
Temperature=instrument.read_register( 0x3111, 2, 4 )
Battery_Current=( struct.unpack( '>l', struct.pack( '>2H', Battery_Current_H, Battery_Current_L ) ) [0] ) / 100
try:
con = mariadb.connect( user="solar",password="solar", host = "localhost", port=3306,database="solar" )
cur = con.cursor()
sql = "INSERT INTO solar.measurements "
sql = sql + "(PiT, PV_Voltage, PV_Current, Load_Voltage, Load_Current, Battery_SOC, Battery_Voltage, Battery_Current, Temperature)"
sql = sql + " VALUES(now()," + str(PV_Voltage) + "," + str(PV_Current)+"," + str(Load_Voltage) + "," + str(Load_Current)+ ","
sql = sql + str(Battery_SOC) + "," + str(Battery_Voltage) + "," + str(Battery_Current) + "," + str(Temperature) + ");"
cur.execute(sql)
con.commit()
con.close()
except mariadb.Error as e:
print( f"Error connecting to Database: {e}" )
sys.exit(1)
Speichern Sie das Programm als solar.py unter /home/pi/solar/. Um es alle fünf Minuten auszuführen, greifen Sie auf den Cron-Daemon von Pi OS zurück. Dessen Steuerungsdatei editieren Sie über das Kommando crontab -e und lassen mit der Zeile aus Listing 5 das Programm zyklisch ausführen.
Listing 5
Python-Skript zyklisch ausführen
*/5 * * * * /home/pi/solar/bin/python /home/pi/solar/solar.py
Grafana
Es würde den Rahmen des Artikels sprengen, auf die Grundlagen von Grafana einzugehen. Deswegen belasse ich es bei der kurzen Information, dass Sie mit Grafana ohne viel Aufwand beliebige Messwerte übersichtlich abbilden können. Um mehr über Grafana zu erfahren, werfen Sie bitte einen Blick in einen meiner früheren Artikel [9].
Mit dem SQL-Statement aus Listing 6 suchen Sie die Daten der letzten zwei Tage (576 Werte) aus der Tabelle heraus. Dabei gilt es, die Werte für die Anzeige der Leistung von Paneel, Batterie und Verbraucher aus den jeweiligen Messpunkten für Spannung und Strom zu errechnen. Da ich immer noch mit Zeitzonen in Grafana auf Kriegsfuß stehe, passe ich die Uhrzeit in SQL noch einmal manuell an.
Listing 6
Datenextraktion per SQL
SELECT date_add(PiT, interval -1 Hour), (PV_Voltage * PV_Current) as PV_Power, (Load_Voltage * Load_Current) as Load_Power, (Battery_Voltage * Battery_Current) as Battery_Power, Temperature FROM solar.measurements ORDER BY id DESC LIMIT 576
Abbildung 2 zeigt die grafische Darstellung der Messwerte des Paneels. Offensichtlich liefert es mit etwa 13 Watt eine noch recht gute Leistung, obwohl es Paneel einfach nur flach auf dem Garagendach liegt. Beim Darstellen der Messwerte nutzt Grafana die absoluten Werte zum Skalieren der Grafik. Deswegen sollten Sie hier etwas aufpassen, welche Werte Sie zusammen in einem Graphen abbilden möchten.
Beträgt beispielsweise die Spannung des Paneels 17 Volt und der Strom liegt bei 0,2 Ampere, ließe sich der Strom als Einzelwert im Grafen kaum erkennen. Dementsprechend verwende ich zur Anzeige auch die Leistung. Manchmal ergibt es schlicht Sinn, nicht alle Messwerte in eine Grafik zu packen.

Abbildung 2: Mithilfe von Grafana lassen sich die Messwerte des Paneels grafisch übersichtlich darstellen.
Fazit
Mit diesem Projekt wollte ich herausfinden, ob die alte Solarzelle noch zu gebrauchen ist – das kann ich jetzt definitiv bejahen. Zusätzlich gelangte ich zu der Erkenntnis, dass es mitunter sinnvoll ist, auf fertige Komponenten zurückzugreifen, statt alles selbst zu bauen. Außerdem entwickelt sich schon meine nächste Projektidee: Ich könnte die Ausbeute des Solarmoduls wohl erheblich steigern, wenn ich es kontinuierlich der Sonne nachführe. Zum Schluss wünsche ich Ihnen viel Spaß bei Ihrer nächsten eigenen Aufräumaktion und den potenziell daraus resultierenden Projekten! (csi)
Der Autor
Martin Mohr hat die komplette Entwicklung der modernen Computertechnik live miterlebt. Nach dem Studium entwickelte er überwiegend Java-Applikationen. Mit dem Raspberry Pi erwachte seine alte Liebe zur Elektronik wieder.
Infos
-
Solarladeregler: https://www.amazon.de/dp/B07VS4RDH6?ref=ppx_yo2ov_dt_b_product_details&th=1
-
Modbus-Register des Reglers: https://files.i4wifi.cz/inc/_doc/attach/StoItem/7068/MODBUS-Protocol-v25.pdf
-
Anleitung zum Regler: https://www.epever.com/wp-content/uploads/2021/05/Tracer-AN-Manual-EN-V2.6.pdf
-
USB/RS-485-Datenleitung: https://www.amazon.de/dp/B07CYYB43L?psc=1&ref=ppx_yo2ov_dt_b_product_details
-
Modbus: https://modbus.org
-
Grafana herunterladen: https://grafana.com/grafana/download?pg=get&plcmt=selfmanaged-box1-cta1&edition=oss
-
Modbus-Bibliothek: https://minimalmodbus.readthedocs.io/en/stable/apiminimalmodbus.html
-
MariaDB: https://mariadb.org
-
Grafana: Martin Mohr, “Summ, summ”, RPG 07/2023, S. 12, https://www.raspi-geek.de/49084






