Das passt leider nicht... Bei 9000 x 0,1W Solarleistung habe ich einen Ladeleistung Wert 56276 x 0,1W. Da die nur die PV-Anlage den Akku lädt müssten die beiden Werte annähernd gleich sein. Beim Register ist noch der Hinweis -signed int 32- gegeben. Vielleicht ist das ja ein Weg zu Lösung ...
Ha...
Nicht das die Variable überläuft.
Ich habe nirgendwo Code geshen.
Schreib doch mal, was Du für eine Zahl erwartest und was Du für eine Zahl bekommst.
Wen Du eine int32_t übergeben bekommst und ein uint16_t/32_t die aufnehmen soll, kommt es zu eigenartigen Effekten.
Hi,
je nach Zahlentyp wirst du eine künstliche Null berechnen müssen Oder du verwendest etwas falsch. (signed und unsigned)
Auf dem Arduino Uno (und anderen ATmega-basierten Boards) speichert ein
int
einen 16-Bit-Wert (2 Byte). Dies ergibt einen Bereich von -32,768 bis 32,767 (Minimalwert -2^15 und Maximalwert (2^15) - 1).
Wenn du normal einen Wert erhälst liegt der also von 0 -...65000blablabla
Du erhältst damit natürlich keine negativen Zahlen.
Also musst du für die 0 die 32767 oder so nehmen.
So meine Theorie und noch nicht geprüftes Wissen.
-10 wären dann 32757
0 wären dann 32767
+10 wären dann 32777
Ich selber habe mit den Registern noch nicht gearbeitet
(signed int 32)
Positive:Battery Discharge Power;
Negative: Battery Charge Power;
in meinem Code verwende ich nur uint16_t und deshalb kann ich hier keine negativen Zahlen erwarten.
Wenn man das Beispiel aus meiner Frage nehmen würde, habe ich einen Wert von 56276. Der Wert der erwartet wird liegt dann bei ca. 9000...
Jo.
da kommt es zum Überlauf.
Der Wert 9000 steck in einer Variablen int16_t / int. Die muss aber int32_t / long sein.
Bei 56276 würde man 56276-37757 rechnen. Das wären dann 18519. Es müssten aber ca. 9000 sein.
Meinst du das?
void setup()
{
Serial.begin(115200);
Serial.println(F("Start..."));
Serial.println(int16_t (-56276));
}
void loop()
{
}
12:21:07.190 -> Start...
12:21:07.190 -> 9260
Wenn der Wechselrichter aber signed int 32 ausgibt und unser Arduino ESP-07 was verarbeiten kann?
Kann der 32Bit? das wäre ja -2,147,483,648 to 2,147,483,647
zeig doch mal den Code!
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <ModbusMaster.h>
#include <ESP8266WiFi.h>
#include <InfluxDbClient.h>
#include <ESP8266WebServer.h>
#include "setup.h"
#include "globals.h"
#include "index.h"WiFiClient growatt_wifi;
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_DB_NAME);
//LED
#define LED_GN 0 // GPIO0
#define LED_RT 2 // GPIO2
#define LED_BL 16 // GPIO16
#define BUTTON A0 // GPIO0 TasterPoint wechselrichter_Status("Status");
Point wechselrichter_System("System");
Point wechselrichter_BatterySOC("BatterySOC");
Point wechselrichter_BatteryVolt("BatteryVolt");
Point wechselrichter_InvTemp("InvTemp");
Point wechselrichter_DcDcTemp("DcDcTemp");
Point wechselrichter_Buck1Curr("Buck1Curr");
Point wechselrichter_Eac_chrToday("Eac_chrToday");
Point wechselrichter_Ebat_dischrTotal("Ebat_dischrTotal");
Point wechselrichter_Ebat_dischrToday("Ebat_dischrToday");
Point wechselrichter_Vpv1("Vpv1");
Point wechselrichter_Ppv1("Ppv1");
Point wechselrichter_Apv1("Apv1");
Point wechselrichter_OP_Curr("OP_Curr");
Point wechselrichter_Inv_Curr("Inv_Curr");
Point wechselrichter_OP_Watt("OP_Watt");
Point wechselrichter_Eac_chrTotal("Eac_chrTotal");
Point wechselrichter_Epv1_today("Epv1_today");
Point wechselrichter_Epv1_total("Epv1_total");
Point wechselrichter_AC_InWatt("AC_InWatt");
Point wechselrichter_Batt_Watt("Batt_Watt");String meldung_system;
int influxdb_Status;
int influxdb_System;
long influxdb_BatterySOC;
long influxdb_BatteryVolt;
int influxdb_Batt_Watt;
long influxdb_InvTemp;
long influxdb_DcDcTemp;
long influxdb_Buck1Curr;
long influxdb_Vpv1;
long influxdb_Ppv1;
long influxdb_Apv1;
long influxdb_OP_Curr;
long influxdb_Inv_Curr;
long influxdb_OP_Watt;
long influxdb_Eac_chrToday;
long influxdb_Eac_chrTotal;
long influxdb_Ebat_dischrTotal;
long influxdb_Ebat_dischrToday;
long influxdb_Epv1_today;
long influxdb_Epv1_total;
long influxdb_AC_InWatt;//Timer
unsigned long startTime;
unsigned long currentTime;
const unsigned long period = 500; //Daten aller x SecundenWiFiUDP ntpUDP;
const long utcOffsetInSeconds = 3600;
char daysOfTheWeek[7][12] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
NTPClient timeClient(ntpUDP, GATEWAY, utcOffsetInSeconds);ModbusMaster growatt;
uint8_t result_8;
//int32_t result_32;ESP8266WebServer webserver(80); //Server on port 80
void handleRoot() {
String s = MAIN_page; //Read HTML contents
webserver.send(200, "text/html", s); //Send web page
}void setup() {
Serial.begin(9600);
while (!Serial) {
; // warte
}//communicate with Modbus slave ID 1 over Serial (port 0)
growatt.begin(modbuss_adresse, Serial);wifi_reconnect();
pinMode(LED_GN, OUTPUT);
pinMode(LED_RT, OUTPUT);
pinMode(LED_BL, OUTPUT);
pinMode(BUTTON, INPUT);
digitalWrite(LED_GN, LOW);
digitalWrite(LED_RT, LOW);
digitalWrite(LED_BL, LOW);webserver.on("/", handleRoot); //Which routine to handle at root location
webserver.begin(); //Start server//influxdb
client.setConnectionParamsV1(INFLUXDB_URL, INFLUXDB_DB_NAME);wechselrichter_System.addTag("System", DEVICE);
wechselrichter_System.addField("System", influxdb_System);wechselrichter_BatterySOC.addTag("BatterySOC", DEVICE);
wechselrichter_BatterySOC.addField("BatterySOC", influxdb_BatterySOC);wechselrichter_BatteryVolt.addTag("BatteryVolt", DEVICE);
wechselrichter_BatteryVolt.addField("BatteryVolt", influxdb_BatteryVolt);
wechselrichter_InvTemp.addTag("InvTemp", DEVICE);
wechselrichter_InvTemp.addField("InvTemp", influxdb_InvTemp);
wechselrichter_Buck1Curr.addTag("Buck1Curr", DEVICE);
wechselrichter_Buck1Curr.addField("Buck1Curr", influxdb_Buck1Curr);
wechselrichter_DcDcTemp.addTag("DcDcTemp", DEVICE);
wechselrichter_DcDcTemp.addField("DcDcTemp", influxdb_DcDcTemp);
wechselrichter_Eac_chrToday.addTag("Eac_chrToday", DEVICE);
wechselrichter_Eac_chrToday.addField("Eac_chrToday", influxdb_Eac_chrToday);
wechselrichter_Ebat_dischrTotal.addTag("Ebat_dischrTotal", DEVICE);
wechselrichter_Ebat_dischrTotal.addField("Ebat_dischrTotal", influxdb_Ebat_dischrTotal);
wechselrichter_Ebat_dischrToday.addTag("Ebat_dischrToday", DEVICE);
wechselrichter_Ebat_dischrToday.addField("Ebat_dischrToday", influxdb_Ebat_dischrToday);
wechselrichter_Vpv1.addTag("Vpv1", DEVICE);
wechselrichter_Vpv1.addField("Vpv1", influxdb_Vpv1);
wechselrichter_Ppv1.addTag("Ppv1", DEVICE);
wechselrichter_Ppv1.addField("Ppv1", influxdb_Ppv1);
wechselrichter_Apv1.addTag("Apv1", DEVICE);
wechselrichter_Apv1.addField("Apv1", influxdb_Apv1);
wechselrichter_OP_Curr.addTag("OP_Curr", DEVICE);
wechselrichter_OP_Curr.addField("OP_Curr", influxdb_OP_Curr);
wechselrichter_Inv_Curr.addTag("Inv_Curr", DEVICE);
wechselrichter_Inv_Curr.addField("Inv_Curr", influxdb_Inv_Curr);
wechselrichter_OP_Watt.addTag("OP_Watt", DEVICE);
wechselrichter_OP_Watt.addField("OP_Watt", influxdb_OP_Watt);
wechselrichter_Eac_chrTotal.addTag("Eac_chrTotal", DEVICE);
wechselrichter_Eac_chrTotal.addField("Eac_chrTotal", influxdb_Eac_chrTotal);
wechselrichter_Epv1_today.addTag("Epv1_today", DEVICE);
wechselrichter_Epv1_today.addField("Epv1_today", influxdb_Epv1_today);
wechselrichter_Epv1_total.addTag("Epv1_total", DEVICE);
wechselrichter_Epv1_total.addField("Epv1_total", influxdb_Epv1_total);
wechselrichter_AC_InWatt.addTag("AC_InWatt", DEVICE);
wechselrichter_AC_InWatt.addField("AC_InWatt", influxdb_AC_InWatt);
wechselrichter_Batt_Watt.addTag("Batt_Watt", DEVICE);
wechselrichter_Batt_Watt.addField("Batt_Watt", influxdb_Batt_Watt);
}void wifi_reconnect() {
WiFi.begin(SSID, PSK);
WiFi.hostname(myhostname);
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(LED_RT, !digitalRead(LED_RT));delay(50);
digitalWrite(LED_RT, !digitalRead(LED_RT));delay(50);
digitalWrite(LED_GN, !digitalRead(LED_GN));delay(50);
digitalWrite(LED_GN, !digitalRead(LED_GN));delay(50);
digitalWrite(LED_BL, !digitalRead(LED_BL));delay(50);
digitalWrite(LED_BL, !digitalRead(LED_BL));delay(50);
influxdb_Status = 400; //WLan-Verbindung war weg, Eintrag in DB
}//Serial.println(WiFi.localIP());
}
void ReadRegisters() {
ESP.wdtFeed();
result_8 = growatt.readInputRegisters(0, 80);if (result_8 == growatt.ku8MBSuccess) {
// Register Growatt SPF5000ES !
modbusdata.System = growatt.getResponseBuffer(0);
influxdb_System = modbusdata.System;
modbusdata.Vpv1 = growatt.getResponseBuffer(1) * 0.1;
influxdb_Vpv1 = modbusdata.Vpv1;
modbusdata.Ppv1 = ((growatt.getResponseBuffer(3) << 16) | growatt.getResponseBuffer(4)) * 0.1;
influxdb_Ppv1 = modbusdata.Ppv1;
modbusdata.Buck1Curr = growatt.getResponseBuffer(7)* 0.1;
influxdb_Buck1Curr = modbusdata.Buck1Curr;
modbusdata.OP_Watt = ((growatt.getResponseBuffer(9) << 16) | growatt.getResponseBuffer(10)) * 0.1;
influxdb_OP_Watt = modbusdata.OP_Watt;
modbusdata.BatteryVolt = growatt.getResponseBuffer(17)*0.01;
influxdb_BatteryVolt = modbusdata.BatteryVolt;
modbusdata.BatterySOC = growatt.getResponseBuffer(18);
influxdb_BatterySOC = modbusdata.BatterySOC;
modbusdata.InvTemp = growatt.getResponseBuffer(25)*0.1;
influxdb_InvTemp = modbusdata.InvTemp;
modbusdata.DcDcTemp = growatt.getResponseBuffer(26)*0.1;
influxdb_DcDcTemp = modbusdata.DcDcTemp;
modbusdata.OP_Curr = growatt.getResponseBuffer(34) * 0.1;
influxdb_OP_Curr = modbusdata.OP_Curr;
modbusdata.Inv_Curr = growatt.getResponseBuffer(35) * 0.1;
influxdb_Inv_Curr = modbusdata.Inv_Curr;
modbusdata.AC_InWatt = ((growatt.getResponseBuffer(36) << 16) | growatt.getResponseBuffer(37)) * 0.1;//Inputleistung AC
influxdb_AC_InWatt = modbusdata.AC_InWatt;
modbusdata.Epv1_today = ((growatt.getResponseBuffer(48) << 16) | growatt.getResponseBuffer(49)) * 0.1;
influxdb_Epv1_today = modbusdata.Epv1_today;
modbusdata.Epv1_total = ((growatt.getResponseBuffer(50) << 16) | growatt.getResponseBuffer(51)) * 0.1;
influxdb_Epv1_total = modbusdata.Epv1_total;
modbusdata.Eac_chrToday = ((growatt.getResponseBuffer(56) << 16) | growatt.getResponseBuffer(57)) * 0.1;
influxdb_Eac_chrToday = modbusdata.Eac_chrToday;
modbusdata.Eac_chrTotal = ((growatt.getResponseBuffer(58) << 16) | growatt.getResponseBuffer(59)) * 0.1;
influxdb_Eac_chrTotal = modbusdata.Eac_chrTotal;
modbusdata.Ebat_dischrToday = ((growatt.getResponseBuffer(60) << 16) | growatt.getResponseBuffer(61)) * 0.1;
influxdb_Ebat_dischrToday = modbusdata.Ebat_dischrToday;
modbusdata.Ebat_dischrTotal = ((growatt.getResponseBuffer(62) << 16) | growatt.getResponseBuffer(63)) * 0.1;
influxdb_Ebat_dischrTotal = modbusdata.Ebat_dischrTotal ;
modbusdata.Batt_Watt = ((growatt.getResponseBuffer(77) << 16) | growatt.getResponseBuffer(78)) * 0.1;
influxdb_Batt_Watt = modbusdata.Batt_Watt ;}
}void writefluxdb() {
// ordne Register zurecht
if(influxdb_Vpv1 > 0){
influxdb_Apv1=influxdb_Ppv1/influxdb_Vpv1;
}else{
influxdb_Apv1=0;
}wechselrichter_Status.addField("Status", influxdb_Status);
client.writePoint(wechselrichter_Status);
wechselrichter_System.addField("System", influxdb_System);
client.writePoint(wechselrichter_System);
wechselrichter_BatterySOC.addField("BatterySOC", influxdb_BatterySOC);
client.writePoint(wechselrichter_BatterySOC);
wechselrichter_BatteryVolt.addField("BatteryVolt", influxdb_BatteryVolt);
client.writePoint(wechselrichter_BatteryVolt);
wechselrichter_InvTemp.addField("InvTemp", influxdb_InvTemp);
client.writePoint(wechselrichter_InvTemp);
wechselrichter_DcDcTemp.addField("DcDcTemp", influxdb_DcDcTemp);
client.writePoint(wechselrichter_DcDcTemp);
wechselrichter_Buck1Curr.addField("Buck1Curr", influxdb_Buck1Curr);
client.writePoint(wechselrichter_Buck1Curr);
wechselrichter_Eac_chrToday.addField("Eac_chrToday", influxdb_Eac_chrToday) ;
client.writePoint(wechselrichter_Eac_chrToday);
wechselrichter_Eac_chrTotal.addField("Eac_chrTotal", influxdb_Eac_chrTotal) ;
client.writePoint(wechselrichter_Eac_chrTotal);
wechselrichter_Ebat_dischrTotal.addField("Ebat_dischrTotal", influxdb_Ebat_dischrTotal);
client.writePoint(wechselrichter_Ebat_dischrTotal);
wechselrichter_Ebat_dischrToday.addField("Ebat_dischrToday", influxdb_Ebat_dischrToday);
client.writePoint(wechselrichter_Ebat_dischrToday);
wechselrichter_Vpv1.addField("Vpv1", influxdb_Vpv1);
client.writePoint(wechselrichter_Vpv1);
wechselrichter_Ppv1.addField("Ppv1", influxdb_Ppv1);
client.writePoint(wechselrichter_Ppv1);
wechselrichter_Apv1.addField("Apv1", influxdb_Apv1);
client.writePoint(wechselrichter_Apv1);
wechselrichter_OP_Curr.addField("OP_Curr", influxdb_OP_Curr);
client.writePoint(wechselrichter_OP_Curr);
wechselrichter_Inv_Curr.addField("Inv_Curr", influxdb_Inv_Curr);
client.writePoint(wechselrichter_Inv_Curr);
wechselrichter_OP_Watt.addField("OP_Watt", influxdb_OP_Watt);
client.writePoint(wechselrichter_OP_Watt);
wechselrichter_Epv1_today.addField("Epv1_today", influxdb_Epv1_today);
client.writePoint(wechselrichter_Epv1_today);
wechselrichter_Epv1_total.addField("Epv1_total", influxdb_Epv1_total);
client.writePoint( wechselrichter_Epv1_total);
wechselrichter_AC_InWatt.addField("AC_InWatt", influxdb_AC_InWatt);
client.writePoint( wechselrichter_AC_InWatt);}
void loop() {
webserver.handleClient(); //Handle client requests
digitalWrite(LED_GN, !digitalRead(LED_GN)); delay(50); digitalWrite(LED_GN, !digitalRead(LED_GN));
ReadRegisters();
writefluxdb();switch (influxdb_System){
case 2:
meldung_system = "Discharge";
break;
case 3:
meldung_system = "Fault";
break;
case 4:
meldung_system = "Flash";
break;
case 5:
meldung_system = "PV charge";
break;
case 6:
meldung_system = "AC charge";
break;
case 7:
meldung_system = "Combine charge";
break;
case 8:
meldung_system = "Combine charge and Bypass";
break;
case 9:
meldung_system = " PV charge and Bypass";
break;
case 10:
meldung_system = "AC charge and Bypass";
break;
case 11:
meldung_system = "Bypass";
break;
case 12:
meldung_system = "PV charge and Discharg";
break;}
influxdb_Status = 0;
}
wäre jetzt mein Bereich. Batt_Watt ist dabei als int32_t Batt_Watt; in global.h deklariert.
Da Du offensichtlich mit mehreren Tabs arbeitest, sage mir, wo ich was finden soll, wenn nur einer da ist.
Werkzeuge, Sktech archivieren - das Archiv hochladen.
WLAN-Zugangsdaten vorher maskieren.
Shine-F_V2.zip (3.7 KB)
In global.h habe ich int32_t Batt_Watt; deklariert.
Im Hauptprogramm
Zeile 63 : int influxdb_Batt_Watt; .... sollte ich hier bei int32_t bleiben?
Zeile 260: Hier frage ich den Register ab.
versuch mal Zeile 263 zu ersetzen.
modbusdata.Batt_Watt = int32_t(((growatt.getResponseBuffer(77) << 16) | growatt.getResponseBuffer(78)) * 0.1);
Für den rest brauch ich mehr Zeit, das schaff ich nicht so zwischendurch
Also ich find jetzt nicht auf Anhieb einen Fehler.
Du initialisierst den seriellen Monitor. Las Dir doch mal ausgeben, was in modbusdata.Batt_Watt
drin steht.
Hi,
bin etwas abgedriftet und habe auch deine Antwort übersehen
modbusdata.Batt_Watt = int32_t(((growatt.getResponseBuffer(77) << 16) | growatt.getResponseBuffer(78)) * 0.1);
Brint uns nicht weiter.
Ich habe mal die Beschreibung aus der Modbuss-Tabelle heraus geschnitten.
Eventuell verstehe ich nur was falsch.
Die Lösung ist eigentlich ganz einfach...
Werte die >= 32768 liegen werden werden mit 65535 subtrahiert und mit 0,1 multipliziert. Daraus ergeben sich dann negative Werte für die Ladeleistung (W). Werte < 32768 werden mit 0,1 multipliziert. Das sind dann die Werte für die Entladeleistung (W)...
Tada!
Moin zusammen,
zuerst möchte ich mich bei @Ralle66 für das tolle Projekt bedanken.
Die version 2 läuft und liefert ihre Daten an den Mqtt-Server wie sie soll.
zu meine frage. Wird an den Projekt noch weiter gearbeitet oder bekommt man aus den Growatt nicht mehr daten raus?
Hi,
aktuell arbeite ich an anderen Sachen.
Viel wird wohl nicht mehr kommen. Denke die Parameter reichen für den alltäglichen Gebrauch aus.
Mit einem Modbus-Sniffer hab ich Adressen mit Daten herausgelesen. Ob ich die brauche?
Mir reicht es erst mal