Epever Tracer 2210AN Werte Schreiben

Hallo Liebe mit leser.
Ich stecke schon wieder fest heute ist es das Schreiben der werte in einen Lade Regler.

Das auslesen klappt soweit ganz gut.

[ (MODBUS-Protocol-v25 verstehen (Epever 2210AN))]

jetzt möchte ich für ein vorhaben aber die BoostSpannung in kleinen rahmen ändern.

leider kann ich in keinster weise nachvollziehen oder abschätzen wie so was gemacht wird. Also Super Aufgabe für einen Anfänger.

Aus der Anleitung bekomme ich zwar die Adresse 9007 raus aber wie kann man hier einen festen float wert zb (27.55 oder 27.90) übergeben ?

Hat das schon mal jemand gemacht ?

Wäre Super wenn mir jemand einen tipp oder noch besser ein Beispiel geben könnte.
Vielen Dank.

die Vorgangsweise ist ähnlich zu dem in deinen verlinkten Threads.

Ermittle:

  • In welches Register soll die BoostSpannung gestellt werden?
  • Welchen Function Code musst du dafür verwenden?
  • Auf welchen Wert willst du die Boost Spannung setzen?

Ich gehe mal von 9007 aus.

Ich denke mal den.
06 WRITE SINGLE REGISTER

Wahlweise auf 27.55 oder 27.90.

Die fragen bleiben aber offen.
Ist dafür 06 Write Single Register oder 15 Write multiple Coils das richtige?
Und wie übergebe ich den wert und wo nehme ich die prüfsumme her ?

wenn du denkst es wäre 06 write single Register, warum verwendest du dann nicht 06 Write Single Register?!?

die Volt sollst du lt PDF als Wert mal 100 eingeben.
also 2755 oder 2790 (also genau zwei Byte wie es für Function Code 6 vorgesehen ist)

Wozu brauchst du eine Prüfsumme? Die Modbus Master Library von DocWalker erstellt den CRC selber, damit hast du nichts zu tun.

schick mal 2755 mit FC 6 an Register 9007 und schau welche Antwort du erhältst.

So habe es mal so versucht umzusetzen wie ich das verstanden habe.

#include <ModbusMaster.h>
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
ModbusMaster node; int ledState = LOW;
#define RXD2 16
#define TXD2 17
int result;
byte wert1 = 2755;
void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);
  node.begin(1, Serial2);//10A
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
  Serial.println("Start");
  node.writeSingleRegister(06,9007, wert1);
  delay(5000);
  result = node.readHoldingRegisters(0x9000, 15);
  if (result == node.ku8MBSuccess) // do something if read is successfull
  {
    Serial.print(F("Boost voltage: ")); Serial.println(node.getResponseBuffer(0x9007 - 0x9000) / 100.0f);
    // Serial.print(F("Float voltage:  ")); Serial.println(node.getResponseBuffer(0x9008 - 0x9000) / 100.0f);
  }
  else
  {
    Serial.print(F(" Fehler"));
  } 
}
void loop()
{
  delay(1000);
}
void preTransmission() {
}
void postTransmission() {
}

Ergibt Fehler:

xxx 7:14: warning: large integer implicitly truncated to unsigned type [-Woverflow]
 byte wert1 = 2755;
              ^~~~
xxx In function 'void setup()':
spannung:16:42: error: no matching function for call to 'ModbusMaster::writeSingleRegister(int, int, byte&)'
   node.writeSingleRegister(10,9007, wert1);
                                          ^
C:\Users\S~1\Documents\Arduino\libraries\ModbusMaster-master\src/ModbusMaster.h:211:14: note: candidate: uint8_t ModbusMaster::writeSingleRegister(uint16_t, uint16_t)
     uint8_t  writeSingleRegister(uint16_t, uint16_t);
              ^~~~~~~~~~~~~~~~~~~
C:\Users\S~1\Documents\Arduino\libraries\ModbusMaster-master\src/ModbusMaster.h:211:14: note:   candidate expects 2 arguments, 3 provided
In file included from C:\Users\S~1\\Documents\Arduino\libraries\ModbusMaster-master\src/ModbusMaster.h:58:0,
                 from 
C:\Users\S~1\Documents\Arduino\libraries\ModbusMaster-master\src/util/crc16.h: At global scope:
C:\Users\S~1\Documents\Arduino\libraries\ModbusMaster-master\src/util/crc16.h:71:17: warning: 'uint16_t crc16_update(uint16_t, uint8_t)' defined but not used [-Wunused-function]
 static uint16_t crc16_update(uint16_t crc, uint8_t a)
                 ^~~~~~~~~~~~
Bibliothek ModbusMaster-master in Version 2.0.1 im Ordner: C:\Users\S~1\\Documents\Arduino\libraries\ModbusMaster-master  wird verwendet
exit status 1
no matching function for call to 'ModbusMaster::writeSingleRegister(int, int, byte&)'

und wenn ich anstelle von node.writeSingleRegister(06,9007, wert1); nur node.writeSingleRegister(9007, wert1); verwende wird es fehlerfrei geschrieben den wert ändert tut es aber natürlich nicht.
Und ob ich jetzt node.writeSingleRegister(06,9007, wert1); oder node.writeSingleRegister(0x06,9007, wert1); schreibe spielt wohl keine rolle.

Das Auslesen geht aber.

2755 passt halt nicht in ein byte.

mach

uint16_t wert1 = 2755;

write single register verlangt zwei Parameter, das Register und den Wert. jeweils in einem uint16_t

außerdem gib dir im Fehlerfall auch den returncode von Result in HEX aus.
Auch beim write single register bekommst du von der Funktion ein ergebnis zurück - lies das wie beim read in einen Variable ein und gib es aus!

   Serial.print(F(" Fehler "));
   Serial.println(result, HEX);

wie willst du sonst sehen, warum das Device den Wert nicht aktzeptieren will?!?

ok auf ein neues.
Dank deiner Tipps kann ich es zumindest mal hoch laden.
Mit einen Fehler der aber automatisch übergangen wird.

In file included from C:\Users\S1\Documents\Arduino\libraries\ModbusMaster-master\src/ModbusMaster.h:58:0,
                 from C:\Users\S1\AppData\Local\Temp\arduino_modified_sketch_438559\spannung.ino:1:
C:\Users\S1\Documents\Arduino\libraries\ModbusMaster-master\src/util/crc16.h:71:17: warning: 'uint16_t crc16_update(uint16_t, uint8_t)' defined but not used [-Wunused-function]
 static uint16_t crc16_update(uint16_t crc, uint8_t a)

Auch ist mir aufgefallen das ich falsch geguckt habe es muss mit 10 und nicht mit 6 gesendet werden also nicht node.writeSingleRegister sondern node.writeMultipleRegisters.
Am Ergebnis ändert es leider nichts wert wird nicht geändert.

12:01:59.884 -> Start
12:02:01.894 ->  Fehler 0  //Schreiben
12:02:06.987 -> Boost voltage: 27.90 (Auslesen aber nichts geändert)

Mein Code ist jetzt wie folgt:

#include <ModbusMaster.h>
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
ModbusMaster node; int ledState = LOW;
#define RXD2 16
#define TXD2 17
int result;
uint16_t wert1 = 2755;
uint16_t id = 0x9007;
void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);
  node.begin(1, Serial2);//10A
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
  Serial.println("Start");
  //node.writeSingleRegister(id, wert1);
  node.writeMultipleRegisters(id, wert1);  //10 schreiben 3 Lesen
  if (result == node.ku8MBSuccess) // do something if read is successfull
  {
   Serial.print(F(" Fehler "));
   Serial.println(result, HEX);
  }
  delay(5000);
  result = node.readHoldingRegisters(0x9000, 15);
  if (result == node.ku8MBSuccess) // do something if read is successfull
  {
    Serial.print(F("Boost voltage: ")); Serial.println(node.getResponseBuffer(0x9007 - 0x9000) / 100.0f);
   }
  else
  {
    Serial.print(F(" node no success register "));
  } 
}
void loop()
{
  delay(1000);
}
void preTransmission() {
}
void postTransmission() {
}

also ob single older Multiple soll nur daran liegen, ob du einen Wert oder mehrere setzen willst. Mir scheint du willst nur einen Wert setzen. Möchtest du mehrere Werte setzen wirst du vieleicht ein Array übergeben müssen.

dass soll wohl eher so sein:

  if (result != node.ku8MBSuccess) // on error

und dann würde ich an deiner Stelle mal das Holding register aus der Variable id verwenden und nicht 15 Werte auslesen, sondern exakt das vorhin geschriebene Register.
1 Wert geschrieben --> 1 Wert zurücklesen.

Hast du eine Doku dazu?

Sicher das es HEX ist?

Wo wird result gesetzt? In der Doku sieht das so aus:

// slave: write TX buffer to (2) 16-bit registers starting at register 0
  result = node.writeMultipleRegisters(0, 2);

Schau dir mal in ModbusMaster/examples/Basic/Basic.pde at master · syvic/ModbusMaster · GitHub wie mit

umgegangen wird.

naja die Doku zu dem Regler ist nur die aus dem andern link.

if (result != node.ku8MBSuccess) // on error

Ok geändert.
Ich möchte eigentlich NUR diesen einen wert ändern.
Boost charging voltage / 9007 (03 read)(10 write)

"Sicher das es HEX ist?"
Nein bin ich nicht aber zum auslesen wird hex genutzt also bin ich davon ausgegangen.
Spielt aber auch keine rolle ob ich 0x mit setzte oder nicht wert wird so und so nicht geändert.

"Wo wird result gesetzt?"
Ich habe es mit und ohne versucht ändert auch nichts nur das ich mal 0 und mal Gar keine Ausgabe bekomme.

Dein verlinken Beitrag hab ich schon mehrfach versucht zu verstehen aber hab es nicht verstanden. Weswegen ich nach eine Beispiel gefragt hatte. an dem ich mir das ableiten kann.

Für was da (0, 2); ist bleibt mir zz verborgen.
Jetzt bekomme ich beim schreiben schonmal den fehler code:

14:20:44.071 ->  Fehler E2
14:20:49.153 -> Boost voltage: 27.90

E2 ist ein Timeout.

ModbusMaster/src/ModbusMaster.h at master · 4-20ma/ModbusMaster · GitHub

wenn du deinen Code veränderst, poste auch deinen gesamten Code.

P.S.: die Registeradressen sind in HEX im PDF.

Code ist der selbe wie in post 7 nur halt mit:

 result = node.writeMultipleRegisters(id, wert1); //10 schreiben 3 Lesen
   if (result != node.ku8MBSuccess) // do something if read is successfull

Anstelle von

node.writeMultipleRegisters(id, wert1);  //10 schreiben 3 Lesen
  if (result == node.ku8MBSuccess) // do something if read is successfull

"P.S.: die Registeradressen sind in HEX im PDF."
Ja habe ich gesehen habe es zum test mit und ohne 0x versucht ist aber nicht das Problem wie ich dachte.

bitte poste einen vollständigen sketch.

#include <ModbusMaster.h>
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
ModbusMaster node; int ledState = LOW;
#define RXD2 16
#define TXD2 17
int result;
uint16_t wert1 = 2755;
uint16_t id = 0x9007;
void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);
  node.begin(1, Serial2);//10A
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
  Serial.println("Start");
  //node.writeSingleRegister(id, wert1);
  result = node.writeMultipleRegisters(id, wert1); //10 schreiben 3 Lesen
   if (result != node.ku8MBSuccess) // do something if read is successfull
  {
   Serial.print(F(" Fehler "));
   Serial.println(result, HEX);
  }

  
  delay(5000);
  result = node.readHoldingRegisters(0x9000, 15);
  if (result == node.ku8MBSuccess) // do something if read is successfull
  {
    Serial.print(F("Boost voltage: ")); Serial.println(node.getResponseBuffer(0x9007 - 0x9000) / 100.0f);
    // Serial.print(F("Float voltage:  ")); Serial.println(node.getResponseBuffer(0x9008 - 0x9000) / 100.0f);
  }
  else
  {
    Serial.print(F(" node no success register "));
  }
  
}

void loop()
{
  delay(1000);
}


void preTransmission() {
}

void postTransmission() {
}

Probier mal

/*
    Versuch mit Single Register
*/

#include <ModbusMaster.h>
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
ModbusMaster node; int ledState = LOW;
#define RXD2 16
#define TXD2 17
int result;
uint16_t wert1 = 2755;
uint16_t id = 0x9007;
void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);
  node.begin(1, Serial2);//10A
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
  Serial.println("Start");
  
  //result = node.writeMultipleRegisters(id, wert1); //10 schreiben 3 Lesen
  result = node.writeSingleRegister(id, wert1);
  if (result != node.ku8MBSuccess) 
  {
   Serial.print(F(" Fehler "));
   Serial.println(result, HEX);
  }
  
  delay(5000);
  result = node.readHoldingRegisters(id, 1);
  if (result == node.ku8MBSuccess) // do something if read is successfull
  {
    Serial.print(F("Register: ")); Serial.print(id); Serial.print(' '); Serial.println(node.getResponseBuffer(0) / 100.0f);
  }
  else
  {
    Serial.print(F(" node no success register "));
  }
  
}

void loop()
{
  delay(1000);
}


void preTransmission() {
}

void postTransmission() {
}

Poste den ganzen Serial output

15:40:46.963 -> Start
15:40:47.056 -> Fehler 4
15:40:52.107 -> Register: 36871 27.90

    An unrecoverable error occurred while the server (or slave) was
    attempting to perform the requested action.
    
    @ingroup constant
    */
    static const uint8_t ku8MBSlaveDeviceFailure         = 0x04;

na, dann halt doch mit FC 10 ... probiern... dauert was muss mir das erst durchsehen...

kanns nicht testen, ich hoffe ich habe mich nicht vertippt.

/*
    Versuch mit Multiple Register
*/

#include <ModbusMaster.h>
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
ModbusMaster node; 
int ledState = LOW;
#define RXD2 16
#define TXD2 17
int result;
uint16_t wert1 = 2755;
uint16_t id = 0x9007;


void schreiben() {
  result = node.clearTransmitBuffer();
  result = node.setTransmitBuffer(0, wert1);
  if (result != node.ku8MBSuccess) // on error
  {
   Serial.print(F(" Fehler Buffer "));
   Serial.println(result, HEX);
  }
  
  result = node.writeMultipleRegisters(id, 1); // einen Wert aus dem Buffer Übertragen
  // result = node.writeSingleRegister(id, wert1);  // NOK liefert Fehler 4
  if (result != node.ku8MBSuccess) // on error
  {
   Serial.print(F(" Fehler "));
   Serial.println(result, HEX);
  }
}

void lesen() {
  result = node.readHoldingRegisters(id, 1);
  if (result == node.ku8MBSuccess) // do something if read is successfull
  {
    Serial.print(F("Register: ")); Serial.print(id, HEX); Serial.print(' '); Serial.println(node.getResponseBuffer(0) / 100.0f);
  }
  else
  {
    Serial.print(F(" node no success register "));
  }	
}

void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);
  node.begin(1, Serial2);//10A
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
  Serial.println("Start");
  
  lesen();
  delay(5000);
  schreiben();
  delay(5000);

  lesen();
  
}

void loop()
{
  delay(1000);
}


void preTransmission() {
}

void postTransmission() {
}
C:\Users\S1\AppData\Local\Temp\arduino_modified_sketch_199562\sketch_mar28a.ino: In function 'void schreiben()':
sketch_mar28a:17:37: error: void value not ignored as it ought to be
   result = node.clearTransmitBuffer();
                                     ^
In file included from C:\Users\S1\Documents\Arduino\libraries\ModbusMaster-master\src/ModbusMaster.h:58:0,
                 from C:\Users\S1\AppData\Local\Temp\arduino_modified_sketch_199562\sketch_mar28a.ino:5:
C:\Users\S1\Documents\Arduino\libraries\ModbusMaster-master\src/util/crc16.h: At global scope:
C:\Users\S1\Documents\Arduino\libraries\ModbusMaster-master\src/util/crc16.h:71:17: warning: 'uint16_t crc16_update(uint16_t, uint8_t)' defined but not used [-Wunused-function]
 static uint16_t crc16_update(uint16_t crc, uint8_t a)
                 ^~~~~~~~~~~~
Bibliothek ModbusMaster-master in Version 2.0.1 im Ordner: C:\Users\S1\Documents\Arduino\libraries\ModbusMaster-master  wird verwendet
exit status 1
void value not ignored as it ought to be

ja ok, die funktion gibt nichts zurück ... sorry.

/*
    Versuch mit Multiple Register
*/

#include <ModbusMaster.h>
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
ModbusMaster node; 
int ledState = LOW;
#define RXD2 16
#define TXD2 17
int result;
uint16_t wert1 = 2755;
uint16_t id = 0x9007;


void schreiben() {
  node.clearTransmitBuffer();
  result = node.setTransmitBuffer(0, wert1);
  if (result != node.ku8MBSuccess) // on error
  {
   Serial.print(F(" Fehler Buffer "));
   Serial.println(result, HEX);
  }
  
  result = node.writeMultipleRegisters(id, 1); // einen Wert aus dem Buffer Übertragen
  // result = node.writeSingleRegister(id, wert1);  // NOK liefert Fehler 4
  if (result != node.ku8MBSuccess) // on error
  {
   Serial.print(F(" Fehler "));
   Serial.println(result, HEX);
  }
}

void lesen() {
  result = node.readHoldingRegisters(id, 1);
  if (result == node.ku8MBSuccess) // do something if read is successfull
  {
    Serial.print(F("Register: ")); Serial.print(id, HEX); Serial.print(' '); Serial.println(node.getResponseBuffer(0) / 100.0f);
  }
  else
  {
    Serial.print(F(" node no success register "));
  }	
}

void setup()
{
  Serial.begin(115200);
  Serial2.begin(115200);
  node.begin(1, Serial2);//10A
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
  Serial.println("Start");
  
  lesen();
  delay(5000);
  
  schreiben();
  delay(5000);

  lesen();
}

void loop()
{
  delay(1000);
}


void preTransmission() {
}

void postTransmission() {
}