eModbus: 2. Register abfragen und weiterverarbeiten

Morgen zusammen,

ich steh vor einem kleinen Problem.
Ich benutze zum Abfragen meines PV Wechselrichters die eModbus lib.

Diese funktioniert für mich auch so weit gut, allerdings mit einer Registerabfrage.
Die Beispiele der lib habe ich schon durch, aber ich komm da nicht weiter bzw. steh auf dem Schlauch.

Ich würde gern ein 2. Register vom Wechselrichter abfragen und weiter verarbeiten.

@Miq1 du hast mir damals in einem andern Thread bereist geschrieben wie ich mit den Befehlen

offs = response.get(offs, Reg1);
offs = response.get(offs, Reg2);

usw. die übertragen Register „greifbar“ machen kann.

Aber wir funktioniert das mit einem weiteren Register?

Hier zur Sicherheit mein abgeänderter sketch:

// =================================================================================================
// eModbus: Copyright 2020 by Michael Harwerth, Bert Melis and the contributors to ModbusClient
//               MIT license - see license.md for details
// =================================================================================================

// Example code to show the usage of the eModbus library. 
// Please refer to root/Readme.md for a full description.

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ModbusClientTCPasync.h>                                         // lib für emodbus

// WiFi
#define MY_SSID "***"
#define MY_PASS "***"
char ssid[] = MY_SSID;                                                    // SSID and ...
char pass[] = MY_PASS;                                                    // password for the WiFi network used

IPAddress ip = {192, 168, 178, 54};                                       // IP address of modbus server > Wechselrichter Batterie
uint16_t port = 502;                                                      // port of modbus server > Wechselrichter Solaranlage

const long T  = 60000;


// Create a ModbusTCP client instance
ModbusClientTCPasync MB(ip, port);

void handleData(ModbusMessage response, uint32_t token)
{
  Serial.printf("Antwort Solar-WR: serverID=%d, FC=%d, Token=%08X, length=%d:\n", response.getServerID(), response.getFunctionCode(), token, response.size());
  for (auto& byte : response) {
    Serial.printf("%02X ", byte);
  }
  Serial.println("");
  uint16_t offs = 3;                                                      // offset: 1. Datenbyte steht bei READ_HOLD_REGISTER hinter ServerID, Funktionscode und Längenfeld > Offset = 3.
  uint16_t Reg1, Reg2;                                                    // 2x 16bit-Register

  offs = response.get(offs, Reg1);                                        // schreibe es in Register 1
  offs = response.get(offs, Reg2);                                        // schreibe es in Register 2
  Serial.print("Register 1: ");   Serial.println(Reg1);
  Serial.print("Register 2: ");   Serial.println(Reg2);
}

void handleError(Error error, uint32_t token)
{
  ModbusError me(error);                                                  // ModbusError wraps the error code and provides a readable error message for it
  Serial.printf("Error response: %02X - %s token: %d\n", (int)me, (const char *)me, token);
}


//--- Setup ----------------------------------------------------------------------------------
void setup() {
  // Starte Serielle Verbindung
  Serial.begin(115200);
  while (!Serial) {}
  Serial.println("__ OK __");
  Serial.printf("\nSketchname: %s\nBuild: %s\t\tIDE: %d.%d.%d\n%s\n\n",
                (__FILE__), (__TIMESTAMP__), ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10, ESP.getFullVersion().c_str());


  // Starte WiFi Verbindung
  WiFi.begin(ssid, pass);
  delay(200);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  IPAddress wIP = WiFi.localIP();
  Serial.printf("WIFi IP address: %u.%u.%u.%u\n", wIP[0], wIP[1], wIP[2], wIP[3]);

  // Set up ModbusTCP client.
  MB.onDataHandler(&handleData);                                          // - provide onData handler function
  MB.onErrorHandler(&handleError);                                        // - provide onError handler function
  MB.setTimeout(10000);                                                   // Set message timeout to 2000ms and interval between requests to the same host to 200ms
  MB.setIdleTimeout(60000);                                               // Start ModbusTCP background task
}


void loop() {
  static unsigned long lastMillis = 0;
  if (millis() - lastMillis > T) { 
    lastMillis = millis();

    Serial.printf("Sende Anfrage mit token %d\n", (uint32_t)lastMillis);
    Error err;
    //err = MB.addRequest((uint32_t)lastMillis, 3, READ_HOLD_REGISTER, 0x7837, 2);              // > Aktuelle PV-Einspeisewirkleistung
    err = MB.addRequest((uint32_t)lastMillis, 3, READ_HOLD_REGISTER, 0x787D, 2);              // > Batterieladezustand

    if (err != SUCCESS) {
      ModbusError e(err);
      Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
    }
  }
}

Grüße!

Weiteres Register direkt anschließend, oder an einer ganz anderen Adresse?
Ersteres ginge mit einer 3 als letztem Parameter in addRequest() und einem weiteren get().
Letzteres geht mit einem zweiten Request, wobei du dann einen anderen Token mitgeben musst und in handleData() daran die beiden Responses unterscheiden!

Ja das! War unsauber ausgedrückt.
Eine neue Adresse (hab ich in meinem Sketch auskommentiert).

Das mit dem token hab ich mir gedacht...
Dieser wird ja derzeit durch die millis bestimmt wenn ich das richtig blicke, und im String mitgegeben.

Aber wie geht das? Einen anderen mitgeben und den response danach abfragen?

Da steig ich aus.

Nix String - millis() liefert einen uint32_t-Wert zurück, und ist halbwegs eindeutig. Deswegen wird das in den Beispielen als Token benutzt.

Der Token ist (siehe Dokumentation... :wink: ) ein beliebiger, von dir zu wählender Wert, an dem du erkennen kannst, zu welchem Request eine Response gehört. Es steht dir völlig frei, z.B. 1 und 2 oder 4711 und 23 zu nehmen. Du musst nur wissen, welchen Wert du für welchen Request benutzt.

Morgen, habs kapiert, hat geklappt!
Bist ein Schatz Danke!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.