EpEver Modbus zu MQTT Register werden nicht published

ich habe einen Sketch der von einem G1 viele (leider nicht "alle") Register ausliest.
Mit einem G3 kann ich erst wieder ende nächster Woche testen. Wenn du bis dahin Geduld hast, würde ich dann meinen Sketch posten.

Der Regler versieht ja seinen Dienst. Hintergrund ist die Integration ins Gebäudemanagement. Bin also nicht auf der Flucht - soll heißen: Ich habe Zeit/Geduld.
Leider habe ich noch keine nutzbare Information von EpEver erhalten.
Dein G1-Sketch benutzt die bekannten Register?
Wenn du deinen Sketch zur Datenübermittlung bringst, würde ich schon gerne auf dein Angebot zurückgreifen - nicht zuletzt zur Ursachensuche.
Gruß

imho ja. Der G3 war nur in einem Bereich zickiger, ist aber schon wieder ein paar Monate her. In meiner Echtanwendung brauch ich nicht alles.
Also muss der Testsketch ran der "alles" ausliest. Nur will ich das erst selber mit HW noch mal testen.

Mit meinem Testaufbau mit vorliegender HW tu ich mich noch ein wenig schwer, da, wie schon geschrieben, der Regler bereits in Betrieb ist und ohne größeren Aufwand nicht auf meinen Schreibtisch kommt. Ich hatte nicht erwartet, dass das zum Problem wird. Bei EpEver werde ich heute nochmal nachfragen.

Hallo und schönen Guten...,
habe nun die Versionen 2.3 und 2.5 (sind wohl die aktuellsten) des Controller Protocol von EpEver vorliegen.
Auf dieser Grundlage lässt sich sagen:
Mit an Sicherheit grenzender Wahrscheinlichkeit liegt es nicht an den Registern.
Da alles Andere jetzt Kaffeesatzleserei ist, werde ich meine Anlage demontieren und wie oben vorgeschlagen die Register einzeln Auslesen/Abfrage und hoffen, dass sich daraus ableiten lässt, wo der Unterschied zwischen den Geräten liegt.
Erkenntnisse werde ich posten
@noiasca Sollte sich bei deinen Versuchen ein sachdienlichen Hinweis ergeben, wäre ich dir dankbar von dir zu "hören".
Gruß

Sind die geheim? Wenn nein, kannst du sie der Allgemeinheit zur Verfügung stellen?

Hallo, gerade eben ist dann doch noch was aktuelleres von EpEver eingetroffen:

Third Generation Series Solar Charge Controller Communication Protocol-V1.00-EN-3.pdf (626,0 KB)

ControllerProtocolV2.3.pdf (374,8 KB)

A or BSeriesControllerProtocolv2.5.pdf (847,6 KB)

Die Einheiten sind schon phantasievoll: Kwh und AH z.B.

Also ich sehe nichts gravierendes.
Die Register sind noch immer 16bit und somit sollte bei richtiger CRC auch eine Antwort den echten Registerinhalt haben.

Da bin ich ja mal gespannt.

Ich auch.
Da der Sketch am Triron funktioniert bin ich schon irritiert und im Moment etwas ratlos.
Wird sich etwas hinziehen.
Bis dann

Hallo, kurzer Zwischenstand:
Einen weiteren Triron gekauft, ans Testsystem gehängt, läuft.
Am Wochenende werde ich mein Produktivsystem umrüsten und auf Fehlersuche gehen.


@noiasca Hast du schon deinen Plan umgesetzt und vielleicht Erkenntnisse?
Gruß und schönes WE, hobbyscripter

sorry, nein bin noch nicht dort wo meine Regler sind. Evtl. in zwei Wochen.

Wenn Du beim tauschen bist, dann schau mal, ob irgendwo die Firmware-Version zu finden ist.
Ansonsten würde mich nicht wundern, wenn die Sensorik nen Schuß hat und keine Werte liefert und damit immer 0 kommt.

Mach ich

Einen Gerätedefekt hatte ich auch schon mal im Sinn.
Am WE leihe ich mir mal einen original WiFi-Adapter von EpEver.
Wenn darüber die Werte auch nicht ausgegeben werden, dürfte der Fall klar sein.
Wenn doch ... Fehler-/ Ursachensuche.
Gruß hobbyscripter

Schönen guten...


Und was soll ich sagen? Der WiFi-Dongle liest die Statistikdaten aus dem Tracer.

Bis dann, hobbyscripter

Du könntest noch immer einen kleinen Sktech machen der nur einen der fraglichen Werte (also 2 Register) ausliest.

Sketch posten (kein MQTT, nur Modbus und Output auf Serial)
Ergebnis posten auf dein beiden Reglern posten.

Leider mangelt es bei mir an Zeit.
Habe jetzt erstmal umgerüstet und bei nächster Gelegenheit setz ich mal ran herauszufinden wo es klemmt.
Gruß

@hobbyscripter

wie es aussieht, wirft mir mein Tracer 1210AN G3 einen Fehler für Carbon dioxide reduction (0x3314-0x3315).

Alle anderen Werte bekomm ich im Großen und Ganzen raus so wie es soll.

Jetzt habe ich noch mal den Sketch überarbeitet. Die Ausgabe der laufenden Werte erfolgt nun "in einem rutsch". Es kamen auch weitere Register hinzu.

Resümee: die oben verlinkte Gen3 Beschreibung passt auch nicht in allen Details zu meinem Tracer 1210AN G3.

ich habs im Code angemerkt was Gen1 was Gen3 ist. Auf Precompiler directiven habe ich verzichtet, da die oben verlinkten Registerbeschreibungen ohnehin nicht das tun was sie schreiben.

Sketch Modbus Client for EPever Tracer Series
/*******************************************************

  Modbus Client Example 0362 (Modbus Master)
  Read EPSOLAR - all registers

  This Modbus Client
  - reads registers from Modbus Servers periodically

  This example is tested against an EPSolar Tracer 1210AN G3 solar charge controller.
  kompatible  Models of XTRA-N G3、XTRA-N G3 BLE、Tracer-AN G3、Tracer-CPN series

  and an EPSolar Tracer 1210 (first generation)

  See here for protocol specs
  Gen1: http://www.solar-elektro.cz/data/dokumenty/1733_modbus_protocol.pdf
  Gen3: https://cdck-file-uploads-europe1.s3.dualstack.eu-west-1.amazonaws.com/arduino/original/4X/f/8/9/f89535b09569a1306594bf817ebd679ee483ffe0.pdf

  remark:
  - even some registers are documented for the G3 some are not working,
  - furthermore there are Gen1 registers which are still working on Gen3 devices
  - published as result of https://forum.arduino.cc/t/epever-modbus-zu-mqtt-register-werden-nicht-published/1404889/39

  hardware
  - a MAX485-TTL adapter

  by noiasca
  2025-09-28 noiasca added some casts and units
  2025-09-27 noiasca separated registers 0x3314 0x3315 as they didn't work on an Tracer 1210AN G3

 *******************************************************/

#//include "tracer.h"

/* *******************************************************
   Serial Interface
 * **************************************************** */
// if you don't have enough HW Serial (e.g. on an UNO)
// you are forced to use SoftwareSerial or AltSoftSerial
//include <SoftwareSerial.h>
//constexpr uint8_t rxPin = 2;                   // for Softserial
//constexpr uint8_t txPin = 3;
//SoftwareSerial mySerial(rxPin, txPin);

// On a Mega you can simply use
// a Reference to an existing HW Serial:
HardwareSerial &mySerial = Serial3;

/* **************************************************** *
   Modbus
 * **************************************************** */

#include <ModbusMaster.h>                        // Modbus Master 2.0.0 by Doc Walker - install with Library Manager
constexpr uint8_t modbusEnablePin = 5;           // The GPIO used to control the MAX485 TX pin. Set to 255 if you are not using RS485 or a selfsensing adapter
constexpr uint32_t modbusBaud = 115200;          // use slow speeds with SoftSerial
constexpr uint16_t modbusRestTx = 15000;         // rest time between transmissions - microseconds
uint32_t modbusPreviousTx = 0;                   // timestamp of last transmission - microseconds
ModbusMaster serverA;                            // instantiate ModbusMaster object - slave - node

// this function will be called before the client transmits data
void preTransmission() {
  while (micros() - modbusPreviousTx < modbusRestTx) { // check last transmission end and wait if the call was to early
    yield();                                           // wait some time and allow background tasks
  }
  digitalWrite(modbusEnablePin, HIGH);
}

// this function will be called after the transmission
void postTransmission() {
  digitalWrite(modbusEnablePin, LOW);
  modbusPreviousTx = micros();         // remember last timestamp
}

// do all the settings for the Modbus
void modbusInit() {
  mySerial.begin(modbusBaud);                     // initialize Modbus communication baud rate
  serverA.begin(1, mySerial);                     // communicate with Modbus server ID over the given Serial interface
  pinMode(modbusEnablePin, OUTPUT);               // Init enable pins for modbus master library
  digitalWrite(modbusEnablePin, LOW);
  serverA.preTransmission(preTransmission);       // Callbacks allow us to configure the RS485 transceiver correctly
  serverA.postTransmission(postTransmission);
}

// data will be read during loop
// we read all parameter at once
// preTransmission and postTransmission take care of the requested "delay" between requests
void requestData() {
  uint16_t reg = 0x3100;  // used for the register(s) to read
  uint16_t length = 1;    // requested amount of registers
  int result;             // stores the result of the Modbus Command

  reg = 0x3100;
  length = 8;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) { // do something if read is successfull
    Serial.print(F("Charging equipment input V:     ")); Serial.println(serverA.getResponseBuffer(0x3100 - reg) / 100.0f);
    Serial.print(F("Charging equipment input A:     ")); Serial.println(serverA.getResponseBuffer(0x3101 - reg) / 100.0f);
    Serial.print(F("Charging equipment input W:     ")); Serial.println((serverA.getResponseBuffer(0x3102 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3103 - reg) << 16)) / 100.0f); // cast and brackets
    Serial.print(F("Charging equipment output V:    ")); Serial.println(serverA.getResponseBuffer(0x3104 - reg) / 100.0f);
    Serial.print(F("Charging equipment output A:    ")); Serial.println(serverA.getResponseBuffer(0x3105 - reg) / 100.0f);
    Serial.print(F("Charging equipment output W:    ")); Serial.println((serverA.getResponseBuffer(0x3106 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3107 - reg) << 16)) / 100.0f); // cast and brackets
  }
  else {
    debugPrint(reg, length, result);
  }

  // Gen3 only
  reg = 0x3108;
  length = 4;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) { // do something if read is successfull
    Serial.print(F("Battery Voltage V:              ")); Serial.println(serverA.getResponseBuffer(0x3108 - reg) / 100.0f);
    Serial.print(F("Battery Output Current A:       ")); Serial.println(serverA.getResponseBuffer(0x3109 - reg) / 100.0f);
    Serial.print(F("Battery Ouptut Power W:         ")); Serial.println((serverA.getResponseBuffer(0x310A - reg) + ((uint32_t)serverA.getResponseBuffer(0x310B - reg) << 16)) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x310C;
  length = 7;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Charging equipment input V:     ")); Serial.println(serverA.getResponseBuffer(0x310C - reg) / 100.0f);
    Serial.print(F("Charging equipment input A:     ")); Serial.println(serverA.getResponseBuffer(0x310D - reg) / 100.0f);
    Serial.print(F("Charging equipment input W:     ")); Serial.println((serverA.getResponseBuffer(0x310E - reg) + ((uint32_t)serverA.getResponseBuffer(0x310F - reg) << 16)) / 100.0f);
    Serial.print(F("Battery Temperature C:          ")); Serial.println((int16_t)serverA.getResponseBuffer(0x3110 - reg) / 100.0f);
    Serial.print(F("Temperature inside equipment C: ")); Serial.println((int16_t)serverA.getResponseBuffer(0x3111 - reg) / 100.0f);
    Serial.print(F("Power components temperature C: ")); Serial.println(serverA.getResponseBuffer(0x3112 - reg) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x311A;
  length = 1;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {// do something if read is successfull
    Serial.print(F("Battery SoC:                    ")); Serial.println(serverA.getResponseBuffer(0x311A - reg));
  }
  else  {
    debugPrint(reg, length, result);
  }

  // not in GEN3
  reg = 0x311B;
  length = 1;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {// do something if read is successfull
    Serial.print(F("Remote battery temperature C:   ")); Serial.println((int16_t)serverA.getResponseBuffer(0x311B - reg) / 100.0f);
  }
  else  {
    debugPrint(reg, length, result);
  }

  reg = 0x311D;
  length = 1;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Battery's real rated power:     ")); Serial.println(serverA.getResponseBuffer(0x311D - reg) / 100.0f);
    //             "Current System Voltage          "  // name of register in Gen3
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x3200;
  length = 2;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Battery status:                 0b")); Serial.println(serverA.getResponseBuffer(0x3200 - reg), BIN);
    Serial.print(F("Charging equipment:             0b")); Serial.println(serverA.getResponseBuffer(0x3201 - reg), BIN);
  }
  else {
    debugPrint(reg, length, result);
  }

  // Gen 3 only
  reg = 0x3202;
  length = 1;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Equipment Discharging Status:   0b")); Serial.println(serverA.getResponseBuffer(0x3202 - reg), BIN);
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x3300;
  length = 20;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Max input (PV) volt:            ")); Serial.println(serverA.getResponseBuffer(0x3300 - reg) / 100.0f);
    Serial.print(F("Min input (PV) volt:            ")); Serial.println(serverA.getResponseBuffer(0x3301 - reg) / 100.0f);
    Serial.print(F("Max battery volt:               ")); Serial.println(serverA.getResponseBuffer(0x3302 - reg) / 100.0f);
    Serial.print(F("Min battery volt:               ")); Serial.println(serverA.getResponseBuffer(0x3303 - reg) / 100.0f);
    Serial.print(F("Consumed energy today:          ")); Serial.println((serverA.getResponseBuffer(0x3304 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3305 - reg) << 16)) / 100.0f);
    Serial.print(F("Consumed energy month:          ")); Serial.println((serverA.getResponseBuffer(0x3306 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3307 - reg) << 16)) / 100.0f);
    Serial.print(F("Consumed energy year:           ")); Serial.println((serverA.getResponseBuffer(0x3308 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3309 - reg) << 16)) / 100.0f);
    Serial.print(F("Total consumed:                 ")); Serial.println((serverA.getResponseBuffer(0x330A - reg) + ((uint32_t)serverA.getResponseBuffer(0x330B - reg) << 16)) / 100.0f);
    Serial.print(F("Generated energy today:         ")); Serial.println((serverA.getResponseBuffer(0x330C - reg) + ((uint32_t)serverA.getResponseBuffer(0x330D - reg) << 16)) / 100.0f);
    Serial.print(F("Generated energy month:         ")); Serial.println((serverA.getResponseBuffer(0x330E - reg) + ((uint32_t)serverA.getResponseBuffer(0x330F - reg) << 16)) / 100.0f);
    Serial.print(F("Generated energy year:          ")); Serial.println((serverA.getResponseBuffer(0x3310 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3311 - reg) << 16)) / 100.0f);
    Serial.print(F("Total generated energy:         ")); Serial.println((serverA.getResponseBuffer(0x3312 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3313 - reg) << 16)) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  // not on Gen3
  reg = 0x3314;
  length = 2;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) { // do something if read is successfull
    Serial.print(F("CO2 reduction:                  ")); Serial.println((serverA.getResponseBuffer(0x3314 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3315 - reg) << 16)) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  // Gen3 only
  reg = 0x3318;
  length = 2;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Battery Total Discharging A :   ")); Serial.println((serverA.getResponseBuffer(0x3318 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3319 - reg) << 16)) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x331B;
  length = 2;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Battery Current A:              ")); Serial.println((int32_t)(serverA.getResponseBuffer(0x331B - reg) + ((uint32_t)serverA.getResponseBuffer(0x331C - reg) << 16)) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  // not documented for Gen3 (but working on mine)
  reg = 0x331D;
  length = 2;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Battery Temperature C:          ")); Serial.println((int16_t)serverA.getResponseBuffer(0x331D - reg) / 100.0f);
    Serial.print(F("Ambient Temperature C:          ")); Serial.println((int16_t)serverA.getResponseBuffer(0x331E - reg) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  // documented for Gen3 but not working on mine
  reg = 0x3400;
  length = 22;  // 22
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Cells :                         ")); Serial.println(serverA.getResponseBuffer(0x3400 - reg));
    Serial.print(F("Battery Pack Voltage V:         ")); Serial.println(serverA.getResponseBuffer(0x3401 - reg) / 100.0f);
    Serial.print(F("Battery Pack Power W:           ")); Serial.println((serverA.getResponseBuffer(0x3403 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3404 - reg) << 16)) / 100.0f);
    Serial.print(F("Battery Pack Full Charge Ah:    ")); Serial.println(serverA.getResponseBuffer(0x3405 - reg));
    Serial.print(F("Battery Pack Remaining Capacity:")); Serial.print (serverA.getResponseBuffer(0x3405 - reg)); Serial.println("%");
    Serial.print(F("Battery Pack Remaining Duration:")); Serial.print (serverA.getResponseBuffer(0x3406 - reg)); Serial.println("min");
    Serial.print(F("Maximum Cell Temperature of Battery Pack C:")); Serial.print ((int16_t)serverA.getResponseBuffer(0x3408 - reg) / 100.0f); Serial.println("°C");
    Serial.print(F("Minimum Cell Temperature of Battery Pack C:")); Serial.print ((int16_t)serverA.getResponseBuffer(0x3409 - reg) / 100.0f); Serial.println("°C");
    Serial.print(F("Equalization Charging Temperature:")); Serial.print ((int16_t)serverA.getResponseBuffer(0x340A - reg) / 100.0f); Serial.println("°C");
    Serial.print(F("Ambient Temperature C:          ")); Serial.print ((int16_t)serverA.getResponseBuffer(0x340B - reg) / 100.0f); Serial.println("°C");
    Serial.print(F("MOSFET Temperature C:           ")); Serial.print ((int16_t)serverA.getResponseBuffer(0x340C - reg) / 100.0f); Serial.println("°C");
    Serial.print(F("Cylces:                         ")); Serial.println (serverA.getResponseBuffer(0x340D - reg));
    Serial.print(F("Equalization Charging Status:   ")); Serial.println (serverA.getResponseBuffer(0x340E - reg));
    Serial.print(F("Battery Pack Voltage Status:    0x")); Serial.println (serverA.getResponseBuffer(0x340F - reg), HEX);
    Serial.print(F("Current Status:                 0x")); Serial.println (serverA.getResponseBuffer(0x3410 - reg), HEX);
    Serial.print(F("MOSFET Status:                  0b")); Serial.println (serverA.getResponseBuffer(0x3411 - reg), BIN);
    Serial.print(F("Cells Temperature Status:       0x")); Serial.println (serverA.getResponseBuffer(0x3412 - reg), HEX);
    Serial.print(F("Equalization Charging Temperature Status: 0x")); Serial.println (serverA.getResponseBuffer(0x3413 - reg), HEX);
    Serial.print(F("Ambient Temperature Status:     0x")); Serial.println (serverA.getResponseBuffer(0x3414 - reg), HEX);
    Serial.print(F("MOSFET Temperature Status:      0x")); Serial.println (serverA.getResponseBuffer(0x3415 - reg), HEX);
  }
  else {
    debugPrint(reg, length, result);
  }

  //documented for Gen3 but not working on mine
  reg = 0x3417;
  length = 1;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Battery Protokol:               ")); Serial.println(serverA.getResponseBuffer(0x3417 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }
}


// Parameters don't change so often, we only read them once after startup
// we read all parameter at once
// preTransmission and postTransmission take care of the requested "delay" between requests
void requestParameter() {
  uint16_t reg;    // start register to read from
  uint16_t length; // length / count of registers to read
  int result;

  reg = 0x3000;
  length = 8;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) { // do something if read is successfull
    Serial.print(F("Charging equipment rated input V: ")); Serial.println(serverA.getResponseBuffer(0x3000 - reg) / 100.0f);
    Serial.print(F("Charging equipment rated input A: ")); Serial.println(serverA.getResponseBuffer(0x3001 - reg) / 100.0f);
    Serial.print(F("Charging equipment rated input W: ")); Serial.println((serverA.getResponseBuffer(0x3002 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3003 - reg) << 16)) / 100.0f); // cast and brackets
    Serial.print(F("Charging equipment rated output V:")); Serial.println(serverA.getResponseBuffer(0x3004 - reg) / 100.0f);
    Serial.print(F("Charging equipment rated output A:")); Serial.println(serverA.getResponseBuffer(0x3005 - reg) / 100.0f);
    Serial.print(F("Charging equipment rated output W:")); Serial.println((serverA.getResponseBuffer(0x3006 - reg) + ((uint32_t)serverA.getResponseBuffer(0x3007 - reg) << 16)) / 100.0f); // cast and brackets
    Serial.print(F("Charging mode:                    ")); Serial.println(serverA.getResponseBuffer(0x3008 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x300E;
  length = 1;
  result = serverA.readInputRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Rated output current of load:     ")); Serial.println(serverA.getResponseBuffer(0x300E - reg) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x9000;
  length = 15;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Battery Type:                   ")); Serial.println(serverA.getResponseBuffer(0x9000 - reg));
    Serial.print(F("Battery Capacity:               ")); Serial.println(serverA.getResponseBuffer(0x9001 - reg));
    Serial.print(F("Temperature compensation coeff: ")); Serial.println((int16_t)serverA.getResponseBuffer(0x9002 - reg) / 100.0f);
    Serial.print(F("High Volt disconnect:           ")); Serial.println(serverA.getResponseBuffer(0x9003 - reg) / 100.0f);
    Serial.print(F("Charging limit voltage:         ")); Serial.println(serverA.getResponseBuffer(0x9004 - reg) / 100.0f);
    Serial.print(F("Over voltage reconnect:         ")); Serial.println((int16_t)serverA.getResponseBuffer(0x9005 - reg) / 100.0f);
    Serial.print(F("Equalization voltage:           ")); Serial.println(serverA.getResponseBuffer(0x9006 - reg) / 100.0f);
    Serial.print(F("Boost voltage:                  ")); Serial.println(serverA.getResponseBuffer(0x9007 - reg) / 100.0f);
    Serial.print(F("Float voltage:                  ")); Serial.println(serverA.getResponseBuffer(0x9008 - reg) / 100.0f);
    Serial.print(F("Boost reconnect voltage:        ")); Serial.println((int16_t)serverA.getResponseBuffer(0x9009 - reg) / 100.0f);
    Serial.print(F("Low voltage reconnect:          ")); Serial.println(serverA.getResponseBuffer(0x900A - reg) / 100.0f);
    Serial.print(F("Under voltage recover:          ")); Serial.println(serverA.getResponseBuffer(0x900B - reg) / 100.0f);
    Serial.print(F("Under voltage warning:          ")); Serial.println(serverA.getResponseBuffer(0x900C - reg) / 100.0f);
    Serial.print(F("Low voltage disconnect:         ")); Serial.println(serverA.getResponseBuffer(0x900D - reg) / 100.0f);
    Serial.print(F("Discharging limit voltage recon:")); Serial.println(serverA.getResponseBuffer(0x900E - reg) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x9013;
  length = 15;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) { // do something if read is successfull
    Serial.print(F("RTC: SS MM                      ")); Serial.println(serverA.getResponseBuffer(0x9013 - reg));
    Serial.print(F("RTC: HH DD                      ")); Serial.println(serverA.getResponseBuffer(0x9014 - reg));
    Serial.print(F("RTC: MM YY                      ")); Serial.println(serverA.getResponseBuffer(0x9015 - reg));
    Serial.print(F("Equalization charging cycle:    ")); Serial.println(serverA.getResponseBuffer(0x9016 - reg));
    Serial.print(F("Batterie Warning upper Limit:   ")); Serial.println(serverA.getResponseBuffer(0x9017 - reg));
    Serial.print(F("Batterie Warning upper Limit:   ")); Serial.println(serverA.getResponseBuffer(0x9018 - reg));
    Serial.print(F("Controller inner temperature upper limit: ")); Serial.println(serverA.getResponseBuffer(0x9019 - reg) / 100.0f);
    Serial.print(F("Controller inner temperature upper limit recover: ")); Serial.println(serverA.getResponseBuffer(0x901A - reg) / 100.0f);
    Serial.print(F("Power component temperature upper limit: ")); Serial.println(serverA.getResponseBuffer(0x901B - reg) / 100.0f);
    Serial.print(F("Power component temperature upper limit recover: ")); Serial.println(serverA.getResponseBuffer(0x901C - reg) / 100.0f);
    Serial.print(F("Line impedance:                 ")); Serial.println(serverA.getResponseBuffer(0x901D - reg) / 100.0f);
    Serial.print(F("Night Time Threshold Volt:      ")); Serial.println(serverA.getResponseBuffer(0x901C - reg) / 100.0f);
    Serial.print(F("Light signal startup night delay:")); Serial.println(serverA.getResponseBuffer(0x901F - reg));
    Serial.print(F("Day Time Threshold Volt:        ")); Serial.println(serverA.getResponseBuffer(0x9020 - reg) / 100.0f);
    Serial.print(F("Light signal startup day delay: ")); Serial.println(serverA.getResponseBuffer(0x9021 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x903D;
  length = 3;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Load controlling modes:         ")); Serial.println(serverA.getResponseBuffer(0x903D - reg));
    Serial.print(F("Working time length 1:          ")); Serial.println(serverA.getResponseBuffer(0x903E - reg));
    Serial.print(F("Working time length 2:          ")); Serial.println(serverA.getResponseBuffer(0x903F - reg));
  }
  else  {
    debugPrint(reg, length, result);
  }

  reg = 0x9042;
  length = 12;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Turn on timing 1 (sec):         ")); Serial.println(serverA.getResponseBuffer(0x9042 - reg));
    Serial.print(F("Turn on timing 1 (min):         ")); Serial.println(serverA.getResponseBuffer(0x9043 - reg));
    Serial.print(F("Turn on timing 1 (hou):         ")); Serial.println(serverA.getResponseBuffer(0x9044 - reg));
    Serial.print(F("Turn off timing 1 (sec):        ")); Serial.println(serverA.getResponseBuffer(0x9045 - reg));
    Serial.print(F("Turn off timing 1 (min):        ")); Serial.println(serverA.getResponseBuffer(0x9046 - reg));
    Serial.print(F("Turn off timing 1 (h):          ")); Serial.println(serverA.getResponseBuffer(0x9047 - reg));
    Serial.print(F("Turn on timing 2 (sec):         ")); Serial.println(serverA.getResponseBuffer(0x9048 - reg));
    Serial.print(F("Turn on timing 2 (min):         ")); Serial.println(serverA.getResponseBuffer(0x9049 - reg));
    Serial.print(F("Turn on timing 2 (h):           ")); Serial.println(serverA.getResponseBuffer(0x904A - reg));
    Serial.print(F("Turn off timing 2 (sec):        ")); Serial.println(serverA.getResponseBuffer(0x904B - reg));
    Serial.print(F("Turn off timing 2 (min):        ")); Serial.println(serverA.getResponseBuffer(0x904C - reg));
    Serial.print(F("Turn off timing 2 (h):          ")); Serial.println(serverA.getResponseBuffer(0x904D - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  // only Gen3
  reg = 0x9063;
  length = 1;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Screen Backlight Time:          ")); Serial.println(serverA.getResponseBuffer(0x9063 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x9065;
  length = 1;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Length of Night:                ")); Serial.println(serverA.getResponseBuffer(0x9065 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x9067;
  length = 1;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Battery rated voltage code:     ")); Serial.println(serverA.getResponseBuffer(0x9067 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x9069;
  length = 7;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Load timing control selection:  ")); Serial.println(serverA.getResponseBuffer(0x9069 - reg));
    Serial.print(F("Default load on/off:            ")); Serial.println(serverA.getResponseBuffer(0x906A - reg));
    Serial.print(F("Equalize Duration:              ")); Serial.println(serverA.getResponseBuffer(0x906B - reg));
    Serial.print(F("Boost Duration:                 ")); Serial.println(serverA.getResponseBuffer(0x906C - reg));
    Serial.print(F("Discharge percentage:           ")); Serial.println(serverA.getResponseBuffer(0x906D - reg) / 100.0f);
    Serial.print(F("Charging percentage:            ")); Serial.println(serverA.getResponseBuffer(0x906E - reg) / 100.0f);
    Serial.print(F("Management Mode of battery:     ")); Serial.println(serverA.getResponseBuffer(0x9070 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  //only Gen3
  reg = 0x90BF;
  length = 1;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Maximum Charging Current A:     ")); Serial.println(serverA.getResponseBuffer(0x90BF - reg) / 100.0f);
  }
  else {
    debugPrint(reg, length, result);
  }

  //only Gen3 - documented but not working on mine
  reg = 0x90F1;
  length = 2;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("PV Restart Charging Period:     ")); Serial.println(serverA.getResponseBuffer(0x90F1 - reg));
    Serial.print(F("Light Control Inversion Mode:   ")); Serial.println(serverA.getResponseBuffer(0x90F2 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  //only Gen3 - documented but not working on mine
  reg = 0x90F3;
  length = 2;
  result = serverA.readHoldingRegisters(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Modbus Master-Slave Mode:       ")); Serial.println(serverA.getResponseBuffer(0x90F3 - reg));
    Serial.print(F("BMS Protocol:                   ")); Serial.println(serverA.getResponseBuffer(0x90F4 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x2;
  length = 1;
  result = serverA.readCoils(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Manual control the load:        ")); Serial.println(serverA.getResponseBuffer(0x2 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x5;
  length = 1;
  result = serverA.readCoils(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Enable load test mode:          ")); Serial.println(serverA.getResponseBuffer(0x5 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  // not on Gen3
  reg = 0x6;
  length = 1;
  result = serverA.readCoils(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Force the load on/off:          ")); Serial.println(serverA.getResponseBuffer(0x6 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  reg = 0x2000;
  length = 1;
  result = serverA.readDiscreteInputs(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Over temperature inside device: ")); Serial.println(serverA.getResponseBuffer(0x2000 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  //only on Gen3
  reg = 0x2001;
  length = 1;
  result = serverA.readDiscreteInputs(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Power Device Over-temperature:     ")); Serial.println(serverA.getResponseBuffer(0x2001 - reg));
  }
  else {
    debugPrint(reg, length, result);
  }

  // not on Gen3
  reg = 0x200C;
  length = 1;
  result = serverA.readDiscreteInputs(reg, length);
  if (result == serverA.ku8MBSuccess) {
    Serial.print(F("Day/Night:                      ")); Serial.println(serverA.getResponseBuffer(0x200C - reg));
  }
  else {
    debugPrint(reg, length, result);
  }
}

//trigger the requestData() function
void timerRequestData() {
  const uint16_t interval = 5000;                // how many ms between calls
  static uint32_t previousMillis = 0 - interval; // timestamp of last request
  uint32_t currentMillis = millis();             // actual timestamp

  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    Serial.println(F("\nRequest new Data"));
    requestData();
  }
}

void debugPrint(uint16_t reg, uint16_t length, int result) {
  Serial.print(F(" no success register=0x")); Serial.print(reg, HEX);
  Serial.print(F(" length=")); Serial.print(length);
  Serial.print(F(" result=")); Serial.println(result, HEX);
}

/* **************************************************** *
   setup and loop
 * **************************************************** */

void setup() {
  Serial.begin(115200);
  Serial.println(F("\n\nModbus Client Example 0362"));
  Serial.println(F("by noiasca https://werner.rothschopft.net"));
  modbusInit();
  Serial.println(F("\nParameters:"));
  requestParameter();
}

void loop() {
  timerRequestData();
}
//

Muster Output auf meinem Tracer 1210AN G3 ("Gen3")

Summary
Modbus Client Example 0362
by noiasca https://werner.rothschopft.net

Parameters:
Charging equipment rated input V: 100.00
Charging equipment rated input A: 10.00
Charging equipment rated input W: 260.00
Charging equipment rated output V:24.00
Charging equipment rated output A:10.00
Charging equipment rated output W:260.00
Charging mode:                    0
Rated output current of load:     10.00
Battery Type:                   1
Battery Capacity:               200
Temperature compensation coeff: 3.00
High Volt disconnect:           16.00
Charging limit voltage:         15.00
Over voltage reconnect:         15.00
Equalization voltage:           14.60
Boost voltage:                  14.40
Float voltage:                  13.80
Boost reconnect voltage:        13.20
Low voltage reconnect:          12.60
Under voltage recover:          12.20
Under voltage warning:          12.00
Low voltage disconnect:         11.10
Discharging limit voltage recon:10.60
RTC: SS MM                      1029
RTC: HH DD                      7178
RTC: MM YY                      6409
Equalization charging cycle:    30
Batterie Warning upper Limit:   6500
Batterie Warning upper Limit:   61536
Controller inner temperature upper limit: 85.00
Controller inner temperature upper limit recover: 75.00
Power component temperature upper limit: 85.00
Power component temperature upper limit recover: 75.00
Line impedance:                 0.00
Night Time Threshold Volt:      75.00
Light signal startup night delay:10
Day Time Threshold Volt:        6.00
Light signal startup day delay: 10
Load controlling modes:         0
Working time length 1:          256
Working time length 2:          256
Turn on timing 1 (sec):         0
Turn on timing 1 (min):         0
Turn on timing 1 (hou):         19
Turn off timing 1 (sec):        0
Turn off timing 1 (min):        0
Turn off timing 1 (h):          6
Turn on timing 2 (sec):         0
Turn on timing 2 (min):         0
Turn on timing 2 (h):           19
Turn off timing 2 (sec):        0
Turn off timing 2 (min):        0
Turn off timing 2 (h):          6
Screen Backlight Time:          60
Length of Night:                3072
Battery rated voltage code:     0
Load timing control selection:  0
Default load on/off:            1
Equalize Duration:              120
Boost Duration:                 120
Discharge percentage:           0.30
Charging percentage:            1.00
Management Mode of battery:     0
Maximum Charging Current A:     40.00
PV Restart Charging Period:     600
Light Control Inversion Mode:   0
 no success register=0x90F3 length=2 result=2
Manual control the load:        1
Enable load test mode:          0
Force the load on/off:          0
Over temperature inside device: 0
Power Device Over-temperature:     0
Day/Night:                      0

Request new Data
Charging equipment input V:     16.05
Charging equipment input A:     0.50
Charging equipment input W:     8.17
Charging equipment output V:    14.35
Charging equipment output A:    0.57
Charging equipment output W:    8.17
Battery Voltage V:              14.35
Battery Output Current A:       1.02
Battery Ouptut Power W:         14.92
Charging equipment input V:     14.35
Charging equipment input A:     1.02
Charging equipment input W:     14.92
Battery Temperature C:          12.71
Temperature inside equipment C: 16.48
Power components temperature C: 16.48
Battery SoC:                    100
Remote battery temperature C:   0.00
Battery's real rated power:     12.00
Battery status:                 0b0
Charging equipment:             0b1101
Equipment Discharging Status:   0b1
Max input (PV) volt:            19.74
Min input (PV) volt:            0.00
Max battery volt:               14.88
Min battery volt:               12.66
Consumed energy today:          0.04
Consumed energy month:          0.07
Consumed energy year:           0.07
Total consumed:                 21.88
Generated energy today:         0.00
Generated energy month:         0.01
Generated energy year:          0.01
Total generated energy:         9.22
 no success register=0x3314 length=2 result=2
Battery Total Discharging A :   1.02
Battery Current A:              -0.45
Battery Temperature C:          12.71
Ambient Temperature C:          12.71
 no success register=0x3400 length=22 result=2
 no success register=0x3417 length=1 result=2

Muster Output von meinem Tracer 1210 ("Gen1"):

Summary
Modbus Client Example 0361
by noiasca https://werner.rothschopft.net

Parameters:
Charging equipment rated input V: 100.00
Charging equipment rated input A: 10.00
Charging equipment rated input W: 260.00
Charging equipment rated output V:24.00
Charging equipment rated output A:10.00
Charging equipment rated output W:260.00
Charging mode:                    0
Rated output current of load:     10.00
Battery Type:                   1
Battery Capacity:               12
Temperature compensation coeff: 2.00
High Volt disconnect:           16.00
Charging limit voltage:         15.00
Over voltage reconnect:         15.00
Equalization voltage:           14.60
Boost voltage:                  14.40
Float voltage:                  13.80
Boost reconnect voltage:        13.20
Low voltage reconnect:          12.60
Under voltage recover:          12.40
Under voltage warning:          12.20
Low voltage disconnect:         11.10
Discharging limit voltage recon:10.60
RTC: SS MM                      2315
RTC: HH DD                      6410
RTC: MM YY                      6156
Equalization charging cycle:    30
Batterie Warning upper Limit:   6500
Batterie Warning upper Limit:   61536
Controller inner temperature upper limit: 85.00
Controller inner temperature upper limit recover: 75.00
Power component temperature upper limit: 85.00
Power component temperature upper limit recover: 75.00
Line impedance:                 0.00
Night Time Threshold Volt:      75.00
Light signal startup night delay:10
Day Time Threshold Volt:        6.00
Light signal startup day delay: 10
Load controlling modes:         0
Working time length 1:          256
Working time length 2:          256
Turn on timing 1 (sec):         0
Turn on timing 1 (min):         0
Turn on timing 1 (hou):         19
Turn off timing 1 (sec):        0
Turn off timing 1 (min):        0
Turn off timing 1 (h):          6
Turn on timing 2 (sec):         0
Turn on timing 2 (min):         0
Turn on timing 2 (h):           19
Turn off timing 2 (sec):        0
Turn off timing 2 (min):        0
Turn off timing 2 (h):          6
Screen Backlight Time:          60
Length of Night:                2092
Battery rated voltage code:     1
Load timing control selection:  0
Default load on/off:            1
Equalize Duration:              120
Boost Duration:                 120
Discharge percentage:           0.80
Charging percentage:            1.00
Management Mode of battery:     0
 no success register=0x90BF length=1 result=2
 no success register=0x90F1 length=2 result=2
 no success register=0x90F3 length=2 result=2
Manual control the load:        1
Enable load test mode:          0
Force the load on/off:          0
Over temperature inside device: 0
Power Device Over-temperature:     0
Day/Night:                      0

Request new Data
Charging equipment input V:     0.07
Charging equipment input A:     0.00
Charging equipment input W:     0.00
Charging equipment output V:    12.25
Charging equipment output A:    0.00
Charging equipment output W:    0.00
Battery Voltage V:              12.25
Battery Output Current A:       0.00
Battery Ouptut Power W:         0.00
Charging equipment input V:     12.25
Charging equipment input A:     0.00
Charging equipment input W:     0.00
Battery Temperature:            25.00
Temperature inside equipment:   20.83
Power components temperature:   20.83
Battery SoC:                    28
Remote battery temperature:     25.00
Battery's real rated power:     12.00
Battery status:                 0
Charging equipment:             1
Equipment Discharging Status:   1
Max input (PV) volt:            0.14
Min input (PV) volt:            0.00
Max battery volt:               12.33
Min battery volt:               12.23
Consumed energy today:          0.00
Consumed energy month:          1.78
Consumed energy year:           32.62
Total consumed:                 342.32
Generated energy today:         0.00
Generated energy month:         0.15
Generated energy year:          18.80
Total generated energy:         199.06
CO2 reduction:                  0.19
Battery Total Discharging A :   0.00
Battery Current A:              0.00
Battery Temperature :           25.00
Ambient Temperature :           25.00
 no success register=0x3400 length=22 result=2
 no success register=0x3417 length=1 result=2

Da stimmt was nicht....