vielen Dank an Meyenfelder für die Idee und die Infos dazu! Ich habe das nun an meiner Huawei-Anlage (SUN2000-4.6KTL-L1) auch umgesetzt. Zusätzlich hab ich noch einen Batteriespeicher (LG RESU 10H) der leider keine Ladezustandsanzeige besitzt, der hängt am gleichen Bus (Adr15). Leider gibts vom LG Resu dazu keine Doku, daher hab ich das Protokoll mitgeschrieben und analysiert, die beiden für mich wichtigen Werte (Ladezustand und Ladeleistung) hab ich gefunden, siehe Code. Im Programm warte ich bis beide Geräte vom Master abgefragt wurden (passiert ca 1x/sek), werte die entsprechenden Register aus und stelle dann alle Werte an einem Nextion-Display dar. Ich verwende einen Arduino Pro Mini mit einer 2€ RS485-Adapterplatine. Die RS485-Platine darf nur empfangen, also sind die Pins !RE und DE beide auf GND. Der RO-Pin geht auf Arduino RX. Den Arduino-TX-Pin verwende ich zum Senden der Daten an das Nextion-Display. hier mein Arduino-Code, vielleicht hilft das dem einen oder anderen als Basis: (Falls jemand das Nextion-File auch haben will, gerne per PN) Code: const int BUFFER_SIZE = 160; char buf[BUFFER_SIZE]; float Wirkleistung; int Ladeleistung_raw; //Teiler1000 int Ladezustand_raw; //Teiler2 float Ladeleistung; float Ladezustand; unsigned long lastread_zaehler; unsigned long lastread_akku; unsigned long lesetimeout; byte recbuf; boolean gelesen_zaehler=false; boolean gelesen_akku=false; void setup() { Serial.begin(9600); } void loop() { bytelesen(); if (recbuf == 0x0B) { //Adr 11=Stromzähler DTSU666-H bytelesen(); if (recbuf == 0x03) { //03=Kommando Register lesen bytelesen(); if (recbuf == 0xA0) { //0xA0=160 Bytes Daten Serial.readBytes(buf, 160); ((byte*)&Wirkleistung)[3]=buf[48]; //ab 25. Register Wirkleistung % (float) ((byte*)&Wirkleistung)[2]=buf[49]; ((byte*)&Wirkleistung)[1]=buf[50]; ((byte*)&Wirkleistung)[0]=buf[51]; Wirkleistung=Wirkleistung/1000.0; //in kW lastread_zaehler=millis(); gelesen_zaehler=true; } } } if (recbuf== 0x0F) { //Adr 15=LG Resu bytelesen(); if (recbuf == 0x03) { //03=Kommando Register lesen bytelesen(); if (recbuf == 0x38) { //0x38=56 Bytes Daten Serial.readBytes(buf, 56); ((byte*)&Ladeleistung_raw)[1]=buf[4]; //3. Register Ladeleistung_raw W (kw Teiler1000) ((byte*)&Ladeleistung_raw)[0]=buf[5]; ((byte*)&Ladezustand_raw)[1]=buf[40]; //21. Register Ladezustand_raw % (Teiler2) ((byte*)&Ladezustand_raw)[0]=buf[41]; Ladeleistung=Ladeleistung_raw/1000.0; Ladezustand=Ladezustand_raw/2.0; lastread_akku=millis(); gelesen_akku=true; } } } if(gelesen_zaehler&&gelesen_akku){ digitalWrite(13,HIGH); nextion(); while(Serial.available()){ //Puffer löschen bevor neuer Leseversuch recbuf=Serial.read(); } //Serial.end(); //Serial.begin(9600); gelesen_zaehler=false; gelesen_akku=false; digitalWrite(13,LOW); } if(millis()>lastread_zaehler+10000){ Wirkleistung=0.0; nextion(); lastread_zaehler=millis(); } if(millis()>lastread_akku+10000){ Ladeleistung=0.0; Ladezustand=0.0; nextion(); lastread_akku=millis(); } } void bytelesen(){ //warten auf nächstes Byte und lesen, max 1s warten (nicht blockierend) lesetimeout=millis(); while(!Serial.available() && (millis()<lesetimeout+1000)){} recbuf=Serial.read(); } void nextion(){ //alle Werte aufs Display schreiben Serial.print("t2.txt="); Serial.write(0x22); Serial.print(Ladezustand,1); Serial.print("%"); Serial.write(0x22); Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("j0.val="); Serial.print(Ladezustand,0); Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("j0.pco="); if(Ladezustand>60){ Serial.print("2016"); //gn } else if (Ladezustand>30){ Serial.print("64512"); //or } else { Serial.print("63488"); //rt } Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("t1.txt="); Serial.write(0x22); Serial.print(Ladeleistung,2); Serial.print("kW"); Serial.write(0x22); Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("t0.txt="); Serial.write(0x22); Serial.print(Wirkleistung,2); Serial.print("kW"); Serial.write(0x22); Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("g0.dir="); if(Ladeleistung>=0){ Serial.print("1"); //nach links } else { Serial.print("0"); //nach rechts } Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("g2.dir="); if(Ladeleistung>=0){ Serial.print("2"); //nach unten } else { Serial.print("3"); //nach oben } Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("g1.dir="); if(Wirkleistung<0){ Serial.print("0"); //nach rechts } else { Serial.print("1"); //nach links } Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); }
const int BUFFER_SIZE = 160; char buf[BUFFER_SIZE]; float Wirkleistung; int Ladeleistung_raw; //Teiler1000 int Ladezustand_raw; //Teiler2 float Ladeleistung; float Ladezustand; unsigned long lastread_zaehler; unsigned long lastread_akku; unsigned long lesetimeout; byte recbuf; boolean gelesen_zaehler=false; boolean gelesen_akku=false; void setup() { Serial.begin(9600); } void loop() { bytelesen(); if (recbuf == 0x0B) { //Adr 11=Stromzähler DTSU666-H bytelesen(); if (recbuf == 0x03) { //03=Kommando Register lesen bytelesen(); if (recbuf == 0xA0) { //0xA0=160 Bytes Daten Serial.readBytes(buf, 160); ((byte*)&Wirkleistung)[3]=buf[48]; //ab 25. Register Wirkleistung % (float) ((byte*)&Wirkleistung)[2]=buf[49]; ((byte*)&Wirkleistung)[1]=buf[50]; ((byte*)&Wirkleistung)[0]=buf[51]; Wirkleistung=Wirkleistung/1000.0; //in kW lastread_zaehler=millis(); gelesen_zaehler=true; } } } if (recbuf== 0x0F) { //Adr 15=LG Resu bytelesen(); if (recbuf == 0x03) { //03=Kommando Register lesen bytelesen(); if (recbuf == 0x38) { //0x38=56 Bytes Daten Serial.readBytes(buf, 56); ((byte*)&Ladeleistung_raw)[1]=buf[4]; //3. Register Ladeleistung_raw W (kw Teiler1000) ((byte*)&Ladeleistung_raw)[0]=buf[5]; ((byte*)&Ladezustand_raw)[1]=buf[40]; //21. Register Ladezustand_raw % (Teiler2) ((byte*)&Ladezustand_raw)[0]=buf[41]; Ladeleistung=Ladeleistung_raw/1000.0; Ladezustand=Ladezustand_raw/2.0; lastread_akku=millis(); gelesen_akku=true; } } } if(gelesen_zaehler&&gelesen_akku){ digitalWrite(13,HIGH); nextion(); while(Serial.available()){ //Puffer löschen bevor neuer Leseversuch recbuf=Serial.read(); } //Serial.end(); //Serial.begin(9600); gelesen_zaehler=false; gelesen_akku=false; digitalWrite(13,LOW); } if(millis()>lastread_zaehler+10000){ Wirkleistung=0.0; nextion(); lastread_zaehler=millis(); } if(millis()>lastread_akku+10000){ Ladeleistung=0.0; Ladezustand=0.0; nextion(); lastread_akku=millis(); } } void bytelesen(){ //warten auf nächstes Byte und lesen, max 1s warten (nicht blockierend) lesetimeout=millis(); while(!Serial.available() && (millis()<lesetimeout+1000)){} recbuf=Serial.read(); } void nextion(){ //alle Werte aufs Display schreiben Serial.print("t2.txt="); Serial.write(0x22); Serial.print(Ladezustand,1); Serial.print("%"); Serial.write(0x22); Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("j0.val="); Serial.print(Ladezustand,0); Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("j0.pco="); if(Ladezustand>60){ Serial.print("2016"); //gn } else if (Ladezustand>30){ Serial.print("64512"); //or } else { Serial.print("63488"); //rt } Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("t1.txt="); Serial.write(0x22); Serial.print(Ladeleistung,2); Serial.print("kW"); Serial.write(0x22); Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("t0.txt="); Serial.write(0x22); Serial.print(Wirkleistung,2); Serial.print("kW"); Serial.write(0x22); Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("g0.dir="); if(Ladeleistung>=0){ Serial.print("1"); //nach links } else { Serial.print("0"); //nach rechts } Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("g2.dir="); if(Ladeleistung>=0){ Serial.print("2"); //nach unten } else { Serial.print("3"); //nach oben } Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); Serial.print("g1.dir="); if(Wirkleistung<0){ Serial.print("0"); //nach rechts } else { Serial.print("1"); //nach links } Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); }
Hallo, ich bin gerade auf der Suche nach dieser Lösung und habe diesen Forumseintrag gefunden. Ich möchte mit einem Arduino Mega die Kommunikation zwischen Sun2000-10KTL-M1 und dem SmartMeter mitloggen und die "Active Power" weiterverwenden. Ich habe mir folgenden Pegelwandler bei Amazon besorgt https://www.amazon.de/ANGEEK-MAX485-...s%2C130&sr=8-8 Ist diese Anschlussbelegung richtig? MAX485 Module GND GND Arduino VCC 5V Arduino A RS485 A B RS485 B DI Pin 9 Arduino DE Pin 7 Arduino RE Pin 7 Arduino RO Pin 9 Arduino Ich hoffe ihr seid noch aktiv im Forum und könnt mir damit weiterhelfen. mfg Hannes
Sorry bin neu hier im Roboternetz, die Formatierung mit mehreren Leerzeichen hat nicht funktioniert. Hier nochmal als Code: Code: Anforderung vom WR an Zähler: 0B03 Teilnehmer Adresse 0B->11 Kommando Register Lesen 03 0836 Adresse 0836 hex -> 2102 dez 0050 50 hex -> 80 dez es werden 80 Register a 2 Byte, 160 Byte angefordert A732 CRC Antwort vom Zähler an WR: 0B Teilnehmer Adresse 0B -> 11 ist Adresse des DTSU666-H am Modbus 03 Kommando Register Lesen 03 A0 A0 hex -> 160 dez Byte die gesendet werden 2102 2104 2106 2108 2110 2112 2114 2116 4094 DD2F 4094 FDF4 40AA 5E35 4366 E666 4367 6666 4365 999A 4367 CCCD 43C7 F333 32 Bytes 2118 2120 2122 2124 2126 2128 2130 2132 ab Adresse 2126, 49. - 52. Byte sind C551 899A = -3352,6 Watt 43C7 999A 43C7 C000 43C8 8CCD 4247 E148 C551 899A C484 CCCD C484 ACCD C499 9666 Aktuelle Leistung in Watt, negativ = Export #### #### 2134 2136 C317 E666 C2B8 CCCD C205 999A C1D0 CCCD 4552 4B33 4485 A000 4485 1CCD 4499 D333 2150 2158 BF7E F9DB BF7E 353F BF7E F9DB BF7F 7CEE C502 C28F C430 FC29 C435 4A3D C424 BF5C 2166 2170 2174 4153 851F 41B0 51EC 4133 851F 42A3 051F 4503 9614 4436 7EB8 4438 1852 4439 2000 0CF1 CRC Bei https://forum.huawei.com/enterprise/...mypfk1cl6f.png gibt es die Registerliste des DTSU666-H, bei Bedarf kann man da auch Spannungen, Ströme, Exportierte und Importierte Arbeit aus dem Datensatz rauslesen. Hoffentlich jetzt besser verständlich Meyenfelder
Anforderung vom WR an Zähler: 0B03 Teilnehmer Adresse 0B->11 Kommando Register Lesen 03 0836 Adresse 0836 hex -> 2102 dez 0050 50 hex -> 80 dez es werden 80 Register a 2 Byte, 160 Byte angefordert A732 CRC Antwort vom Zähler an WR: 0B Teilnehmer Adresse 0B -> 11 ist Adresse des DTSU666-H am Modbus 03 Kommando Register Lesen 03 A0 A0 hex -> 160 dez Byte die gesendet werden 2102 2104 2106 2108 2110 2112 2114 2116 4094 DD2F 4094 FDF4 40AA 5E35 4366 E666 4367 6666 4365 999A 4367 CCCD 43C7 F333 32 Bytes 2118 2120 2122 2124 2126 2128 2130 2132 ab Adresse 2126, 49. - 52. Byte sind C551 899A = -3352,6 Watt 43C7 999A 43C7 C000 43C8 8CCD 4247 E148 C551 899A C484 CCCD C484 ACCD C499 9666 Aktuelle Leistung in Watt, negativ = Export #### #### 2134 2136 C317 E666 C2B8 CCCD C205 999A C1D0 CCCD 4552 4B33 4485 A000 4485 1CCD 4499 D333 2150 2158 BF7E F9DB BF7E 353F BF7E F9DB BF7F 7CEE C502 C28F C430 FC29 C435 4A3D C424 BF5C 2166 2170 2174 4153 851F 41B0 51EC 4133 851F 42A3 051F 4503 9614 4436 7EB8 4438 1852 4439 2000 0CF1 CRC
Hallo hoerbi1, hatte das gleiche Problem und habe jetzt eine Lösung gefunden: Zum Auslesen der Smartmeterwerte genügt es die Kommunikation zwischen WR SUN 2000 und Smartmeter SM DTSU666-H einfach mitzulesen. WR fragt den SM mehrmals pro Sekunde ab. Habe den Verkehr mitgeschnitten und nach einigem Suchen die richtigen Stellen im Datensatz gefunden. Wichtig ist auch einen entsprechenden Peglewandler von RS485 auf TTL (0-5 Volt) zu verwenden. Habe das Modul von Pollin LC-TTL-MAX485 für 2 Euro benutzt. Komunikation läuft mit 9600 Bd, 8n1. Hier ein Auszug aus dem Datensatz: Anforderung vom WR an Zähler: 0B03 Teilnehmer Adresse 0B->11 Kommando Register Lesen 03 0836 Adresse 0836 hex -> 2102 dez 0050 50 hex -> 80 dez es werden 80 Register a 2 Byte, 160 Byte angefordert A732 CRC Antwort vom Zähler an WR: 0B Teilnehmer Adresse 0B -> 11 ist Adresse des DTSU666-H am Modbus 03 Kommando Register Lesen 03 A0 A0 hex -> 160 dez Byte die gesendet werden 2102 2104 2106 2108 2110 2112 2114 2116 4094 DD2F 4094 FDF4 40AA 5E35 4366 E666 4367 6666 4365 999A 4367 CCCD 43C7 F333 32 Bytes 2118 2120 2122 2124 2126 2128 2130 2132 ab Adresse 2126, 49. - 52. Byte sind C551 899A = -3352,6 Watt 43C7 999A 43C7 C000 43C8 8CCD 4247 E148 C551 899A C484 CCCD C484 ACCD C499 9666 Aktuelle Leistung in Watt, negativ = Export #### #### 2134 2136 C317 E666 C2B8 CCCD C205 999A C1D0 CCCD 4552 4B33 4485 A000 4485 1CCD 4499 D333 2150 2158 BF7E F9DB BF7E 353F BF7E F9DB BF7F 7CEE C502 C28F C430 FC29 C435 4A3D C424 BF5C 2166 2170 2174 4153 851F 41B0 51EC 4133 851F 42A3 051F 4503 9614 4436 7EB8 4438 1852 4439 2000 0CF1 CRC Auswertung funktioniert dann so: Auf Zeichenfolge 0B 03 A0 Hex warten, dann 48 Byte verwerfen, die Bytes 49 - 52 sind die Leistung als Fliesskommazahl. Falls Du noch Probleme hast, bitte hier melden. Gruß Meyenfelder