RS485 / Modus EPever Xtra Solarregler

Moin,

in Topic MODBUS-Protocol-v25 verstehen (Epever 2210AN) ging es ja schon im Grunde um die Sache.

Nach etwas Recherche im Netz wurde ich fündig bei Infos das diese Daten für mich auch sinnvoll werden könnten - etwas probiert aber noch nicht ganz den Erfolg gehabt.

Die Daten werden vom EPever nicht erkannt / akzeptiert.

( 0x01,0x04,0x33,0x1A,0x00,0x01,0x1F,0x49 als Anforderung der aktuellen Akkuspannung zum Test gesendet ) - Ja ich weiß dazu nimmt man ModbusLIb ... .

Ein Monitoring der Daten zwischen Computer und EPever via dem USB-Kabel ( einen ESP32 mit RS485 Pegelwandler mit rangehängt ) zeigen teils Daten - aber irgendwie nur eine Seite und die Daten stimmen nicht mit Denen der im Netz zu findenden Dokus überein ( MODBUS-Protocol-v25.pdf für den EPever ).

F8 01 E8 81 BA FF F8 40 schnitt ich z.B. mit wenn per PC-Sofware die ID ausgelesen wird - das passt doch nicht zu den Dukus ?

Baudrate des EPever per PC-Software auf 19k2 gesetzt - wurde auch bestätigt das das geklappt hat - ein mitlesen ging aber wieder nur mit 155K2 ?

Fragen daher :

  1. ist die Baud doch fest auf 115K2 ?

  2. Geht Softserial bei 115k2 evt. nicht mehr ?

  3. der Sketch von nosiaca einfach zu ESP32 zu portieren und vor allem - was wird bei Einigen Wandlern noch geschaltet - das sieht mir teils nach Sende/Empfangsumschaltung aus ( modbusEnablePin )?

Bei meinem (China-billg) RS485 Pegelwandler habe ich keinen Anschluss für Weiteres außer ser tx/rx/GND/Versorgungsspannungseingang.

Was habe ich sonst gemacht ?

  • Widerstand als Abschluss versucht ob sich da was ändert ( keine Änderung )
  • AB getauscht ( kaum Änderung - aber A auf A und B auf B geht weit mehr )
    beim monitoring sehe ich ja die LED auf dem Wandler - auch wenn er nicht
    dekodiert.

Geplant wären nur ein paar Daten zu lesen die für mich interessant sind.
Und es scheint das der Ladestrom begrenzbar ist ?

Es kursieren verschiedene Versionen des Protokolls im Netz - die differrieren auch,
Welche ist denn die Richtige/Aktuelle ?

Ein Arduino Mega liegt hier zum Test auch noch herum - evt. damit anfangen ?

Projekt hat Zeit - also keine Hektik !

Aber interessant wäre das schon :slight_smile:

Gruß Bernd

Fest im Sinne ist konfiguriert. Die Geschwindigkeit lässt sich parametrieren und der Regler merkt sich dann das dauerhaft

viel mehr als 9600 oder 19200 würde ich nicht nehmen. In der Doku sind 57600 für den Arduino angegeben.

https://docs.arduino.cc/learn/built-in-libraries/software-serial/

das Code Schnipsel ist einerseits das schalten der Enable Pins und auch eine kurze blockierende Warteschleife falls die Aufrufe zu schnell hintereinander kämen. Der Epever den ich habe war sehr empfindlich auf zu schnelles Abfragen (außerhalb der Spec) und daher gibts dieses Zeitmanagement in postTransmission und preTransmission.

1 Like

https://www.abctech.cz/img.asp?attid=981574.

Moin und danke schon mal für die Info, die Baud hatte ich ja auf 19k2 geändert - das PC-Programm kann Die ja abfragen und anzeigen - das bestätigte das der Kontroller 19k2 haben soll - aber das Monitoren in 19K2 zeigte dann nichts an - als ich meinen Sketch auf 1115k2 stellte kamen dann die Bytes (?) - sonderbar.

Wobei - ich wollte grad mit dem MT50 den einen Kontroller auslesen - Der findet aber jetzt den Kontroller nicht - hat der doch nun 19k2 - oder ist die Schnittstelle hin oder abgestürzt wegen meinen Spielereien ? PC-Programm findet Den auch nicht - evt. mal resetten den Kontroller ... .

Der EnablePin muss dann aber an den RS485 Wandler steuern - wenn der Wandler aber keinen Eingang dafür hat ? ( Oder sehe ich das falsch ? )

Für mich also erstmal sinnvoll das mit dem Mega nachzubauen wie von Dir original gemacht - und dann weiterschauen - nur eben EnablePin brauche ich noch die Info ( ob ich da anderen RS485 Wandler brauche ) .

Derzeit nutze ich:

Heemol 5pcs TTL to R485 Level Converter Module Adapter 485to Serial Port Automatic Flow Control Level Shifter 3.3v 5v for Uart Series: Amazon.de: Computer & Accessories

Grüße

Bernd

ich nutze meist die einfachen boards mit separater Ansteuerung:

https://amzn.to/3J0mSv8

Hallo Bernd
Ich weis nicht ob deine anfrage nicht im Forum besser ausgehoben wäre.
Da ich dir nur bedingt helfen kann.

Also Die Protokoll Geschichte lief bei mir auch nicht.
Baud = 115200 ist die Standard rate welche man zwar ändern kann aber ich glaube bei jeden Neustart erst manuell wieder gesetzt werden muss im Lade Regler.
Ich verwende einen DUE + Uart zu RS485 mit HAREWARE Serial.
Software Serial macht sich gut zum senden aber zum empfangen taugt es nicht unbedingt.

https://www.ebay.de/itm/153880466847?itmmeta=01HT7AHH9G8GESC4WKCM8AY5XJ&hash=item23d3fd959f:g:KiAAAOSwoJ5ef8eO&itmprp=enc%3AAQAJAAAA0BiwqrV9N8q75M49SZS4B7oyHapW2Yrt%2B23kFSxNvUtfAOPugdWzeJFSVT7QUb9ot8KFDReHhQKEn%2BmbgrjwT4ko5lDovOfr0kKEyaWG30lYrX3UFysnV7mcdsTKceCw6yR0mxEOm5qQDLezt%2BER8bZWWHCGyyknYjJ18NaaFQbUvUbGR%2FCiIjvUMGizAkRGVSDWrP45bCxHYMVARoFj2lscYfOw4Ie%2FA2gw%2FCJGISWMlqU8%2B863LUO80fqCLNcXhuWdFmXIQhrTsXiijiyqiIU%3D%7Ctkp%3ABFBMjpXG6tFj

als Vorlage habe ich diesen codeausschnitt genutzt und bei mir erweitert.

Das wird erstmal ausgelesen.

// RJ 45 cable: Green -> A, Blue -> B, Brown -> GND module + GND ESP8266
//PV Voltage: 0.00
//PV Current: 0.00
//PV Power: 0.00
//Battery Voltage: 13.53
//Battery Charge Current: 0.00
//Battery Charge Power: 0.00
//Load Current: 0.00
//Load Power: 0.00
//Battery Remaining %: 88.00
//Battery Temperature: 0.00
//Battery Discharge Current: 0.00

3,3 volt

#include <ModbusMaster.h>

#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

const int defaultBaudRate = 115200;
int timerTask1, timerTask2, timerTask3;
float battChargeCurrent, battDischargeCurrent, battOverallCurrent, battChargePower;
float bvoltage, ctemp, btemp, bremaining, lpower, lcurrent, pvvoltage, pvcurrent, pvpower;
float stats_today_pv_volt_min, stats_today_pv_volt_max;
uint8_t result;
bool rs485DataReceived = true;
bool loadPoweredOn = true;

ModbusMaster node;

void preTransmission() {
}

void postTransmission() {
}

// A list of the regisities to query in order
typedef void (*RegistryList[])();

RegistryList Registries = {
AddressRegistry_3100,
AddressRegistry_3106,
AddressRegistry_310D,
AddressRegistry_311A,
AddressRegistry_331B,
};

// keep log of where we are
uint8_t currentRegistryNumber = 0;

// function to switch to next registry
void nextRegistryNumber() {
// better not use modulo, because after overlow it will start reading in incorrect order
currentRegistryNumber++;
if (currentRegistryNumber >= ARRAY_SIZE(Registries)) {
currentRegistryNumber = 0;
}
}

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

// --------------------------------------------------------------------------------

// exec a function of registry read (cycles between different addresses)
void executeCurrentRegistryFunction() {
RegistriescurrentRegistryNumber;
}

uint8_t setOutputLoadPower(uint8_t state) {
Serial.print("Writing coil 0x0006 value to: ");
Serial.println(state);

delay(10);
// Set coil at address 0x0006 (Force the load on/off)
result = node.writeSingleCoil(0x0006, state);

if (result == node.ku8MBSuccess) {
node.getResponseBuffer(0x00);
Serial.println("Success.");
}

return result;
}

// callback to on/off button state changes from the Blynk app

uint8_t readOutputLoadState() {
delay(10);
result = node.readHoldingRegisters(0x903D, 1);

if (result == node.ku8MBSuccess) {
loadPoweredOn = (node.getResponseBuffer(0x00) & 0x02) > 0;

Serial.print("Set success. Load: ");
Serial.println(loadPoweredOn);
} else {
// update of status failed
Serial.println("readHoldingRegisters(0x903D, 1) failed!");
}
return result;
}

// reads Load Enable Override coil
uint8_t checkLoadCoilState() {
Serial.print("Reading coil 0x0006... ");

delay(10);
result = node.readCoils(0x0006, 1);

Serial.print("Result: ");
Serial.println(result);

if (result == node.ku8MBSuccess) {
loadPoweredOn = (node.getResponseBuffer(0x00) > 0);

Serial.print(" Value: ");
Serial.println(loadPoweredOn);
} else {
Serial.println("Failed to read coil 0x0006!");
}

return result;
}

// -----------------------------------------------------------------

void AddressRegistry_3100() {
result = node.readInputRegisters(0x3100, 6);

if (result == node.ku8MBSuccess) {

pvvoltage = node.getResponseBuffer(0x00) / 100.0f;
Serial.print("PV Voltage: ");
Serial.println(pvvoltage);

pvcurrent = node.getResponseBuffer(0x01) / 100.0f;
Serial.print("PV Current: ");
Serial.println(pvcurrent);

pvpower = (node.getResponseBuffer(0x02) | node.getResponseBuffer(0x03) << 16) / 100.0f;
Serial.print("PV Power: ");
Serial.println(pvpower);

bvoltage = node.getResponseBuffer(0x04) / 100.0f;
Serial.print("Battery Voltage: ");
Serial.println(bvoltage);

battChargeCurrent = node.getResponseBuffer(0x05) / 100.0f;
Serial.print("Battery Charge Current: ");
Serial.println(battChargeCurrent);
}
}

void AddressRegistry_3106()
{
result = node.readInputRegisters(0x3106, 2);

if (result == node.ku8MBSuccess) {
battChargePower = (node.getResponseBuffer(0x00) | node.getResponseBuffer(0x01) << 16) / 100.0f;
Serial.print("Battery Charge Power: ");
Serial.println(battChargePower);
}
}

void AddressRegistry_310D()
{
result = node.readInputRegisters(0x310D, 3);

if (result == node.ku8MBSuccess) {
lcurrent = node.getResponseBuffer(0x00) / 100.0f;
Serial.print("Load Current: ");
Serial.println(lcurrent);

lpower = (node.getResponseBuffer(0x01) | node.getResponseBuffer(0x02) << 16) / 100.0f;
Serial.print("Load Power: ");
Serial.println(lpower);
} else {
rs485DataReceived = false;
Serial.println("Read register 0x310D failed!");
}
}

void AddressRegistry_311A() {
result = node.readInputRegisters(0x311A, 2);

if (result == node.ku8MBSuccess) {
bremaining = node.getResponseBuffer(0x00) / 1.0f;
Serial.print("Battery Remaining %: ");
Serial.println(bremaining);

btemp = node.getResponseBuffer(0x01) / 100.0f;
Serial.print("Battery Temperature: ");
Serial.println(btemp);
} else {
rs485DataReceived = false;
Serial.println("Read register 0x311A failed!");
}
}

void AddressRegistry_331B() {
result = node.readInputRegisters(0x331B, 2);

if (result == node.ku8MBSuccess) {
battOverallCurrent = (node.getResponseBuffer(0x00) | node.getResponseBuffer(0x01) << 16) / 100.0f;
Serial.print("Battery Discharge Current: ");
Serial.println(battOverallCurrent);
} else {
rs485DataReceived = false;
Serial.println("Read register 0x331B failed!");
}
}

#define p_ledtick LED_BUILTIN
int ledState = LOW;
unsigned long previousMillis = 0;

#define RXD2 16
#define TXD2 17

void setup()
{
Serial.begin(defaultBaudRate);
Serial2.begin(defaultBaudRate);

// Modbus slave ID 1
node.begin(1, Serial2);

// callbacks to toggle DE + RE on MAX485
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);

pinMode(p_ledtick, OUTPUT);

Serial.println("Setup OK!");
Serial.println("----------------------------");
Serial.println();
}

void loop()
{
unsigned long currentMillis = millis();
const long interval = 5000;
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;

if (ledState == LOW)
{
ledState = HIGH;
} else {
ledState = LOW;
}

digitalWrite(p_ledtick, ledState);

executeCurrentRegistryFunction();
nextRegistryNumber();
}
}

Gibt noch viel mehr zb das schalten der last Ausgänge aber das scheint bei jedeladeregler anderes zu sein.
Ob du jetzt einen ESP mit 3,3 Volt nutzt oder einen Atmega 2560 (Mega) ist egal aber der Mega hat VIEL mehr Pins (4-mal Hardware Serial) und ist besser dokumentiert bei den Beispielen und hat einen EEPROM :slightly_smiling_face:
Ich hoffe ich konnte dir ein BISSEL weiterhelfen.

MFg David

Dann hast du einen Wandler mit Auto-Halbduplexlogik. Die sind mir persönlich eh' lieber.

Falls du geneigt bist, nochmal von vorne zu beginnen: auf einem ESP32 läuft meine eModbus-Library recht bequem. Vielleicht kommst du damit leichter klar.

Kurz gelesen, danke schon mal für die Info´s - später mehr !
( Ich nutze das Wetter grad draußen )

Bernd

Das scheint das selbe Chinateil zu sein wie ich Die habe.

5 Stk. nen paar Euro das war im Fluss sogar billiger als hier bei E-Bay :face_with_peeking_eye:

Die Verwendung der Adapter mit "automatischer" Umschaltung sollten mit dem Sketch aber dann ja auch funktionieren ?

( habe davon ja erstmal 5 zum basteln - 4 fest bereits verplant - Einer könnte ja für den Epever genutzt werden.

Erst mal Ostergrüße >- Kaffee & den auf der RS485 grad undefinierten EPever resetten.
( Hardware sollte ok sein da ich ein Kabel baute wo wirklich nur Pin 4 - 6 & 8 angeschlossen waren - die Kontakte aus dem Westernstecker die nicht genutzt wurden zu Sicherheit vor dem crimpen entfernt - die EPEver sind wohl auch empfindlich wenn man die anliegende Spannung dort belastet ? )

Denke auch das man da nichts ändern sollte - siehe auch meine "Effekte"

Möglicherweise ja.
Bei dir gibts aber viele unbekannte Faktoren weswegen man nicht beantworten weshalb es bei dir nicht stabil funktioniert.

Wegen der Westernbuchse - verlinke mal die Bedienungsanleitung von deinem Regler. Vermutlich steht da was dazu drinnen (bei meinen Epever Tracer Serien - gibts da Hinweise).

Auch dass die Baudeinstellung verloren geht, kann ich nicht nachvollziehen (ist bei meinen Epever Tracer definitiv nicht so).

Mit einem Schaltplan könnte man sich besser vorstellen was du da momentan angeschlossen hast.

Ja, wobei die sonderbaren Effekte weitergehen - nun funktioniert die RS485 bei BEIDEN EPevers scheinbar nicht mehr - wobei der Eine normal am MT50 über Nacht hing - da nichts geändert wurde - ich befürchte fast das das Original USB-Kabel einen wech haben könnte - und das Dies die Schnittstellen killte ?
Unschön auch das damit gerade nichts läuft - wobei die Regler arbeiten sonst normal und haben Ihre Settings.
Ein Trennen des einen Reglers von Panels und Akku = Reset brachte keine Änderung.

Beim USB-Interface sind auch nur Pin 4,6&8 angeschlossen - das kann man sehen - ich mache da nachher mal Bilder. Ich befürchte aber da ist was hinüber.

Spannung vom RS485 Port der Regler läuft - der MT50 geht an - bekommt aber keinen Connect - die Spannungspins sind aber bei meinem Zwischenstecker und dem USB-Interface auch gar nicht angeschlossen.

https://www.epever.com/upload/file/1811/XTRA-SMS-EL-V1.3.pdf der Neuere
https://www.epever.com/upload/cert/file/1811/Tracer-AN-SMS-EL-V1.0.pdf der Ältere

Der Neuere läuft in 26V LiFePoSetup, der Ältere in 12V Blei-AGM Setup

wegen der Westernbuchse siehst schon einen Unterschied, der eine gibt dir 200mA, der andere gar nur 100mA. Versuche da nicht deine Microcontroller anzuschließen so lange du nicht 100%ig unter diesen Grenzen bist.

Ich habe die Spannung vom EPeverport nicht angeschlossen - weil mir das bekannt war das es Probleme geben kann.

nur Pin 4,6,8 wie auch beim Original USB-Kabel

Die Spannungsversorgung des MT50 funktioniert auch bei beiden Kontrollern.

Schliesse ich den MT50 an einen der Beiden an startet der MT50 - aber er bekommt halt keine Verbindung.
Dito mit dem USB-Kabel das findet die Kontroller jetzt nicht mehr :woozy_face:

zunächst muss mal wieder das originale USB Kabel und die original Software laufen.

Meldet sich das USB Kabel mit einem XR21B1411 USB UART im Windows (?) ?

Wie das Kabel in Windows angezeigt wird schaue ich gleich.

Anbei 4 Bilder - die 3 Stecker wo auch die Belegung max Kontakte sichtbar sind und Screenshot des MT50




Entwarnung: Nun sind die Regler tatsächlich in 19K2 !
( Auch nach reboot der Regler )

Daher frisst der MT50 die jetzt nicht.
Und ( der Kaffee war wohl zu schwach ) bemerkte erst zu spät das die ComPortsettings in der PC-Software noch auf 115K2 eingestellt waren.
Klarer Userfehler - Idee wäre dann NUN meinen Sketch noch mal zu testen weil Baud nun auch für Softserial langsam genug ist.

Danke aber schon mal für die Mühen !

Tipp für Nutzer des USB-Kabels - einige Windowsversionen wollten bei mir das Kabel immer wieder mal nicht im RS485 Modus laufen lassen - das kann und muss ( evt. ) im Gerätemanager eingestellt werden ( hier etwas oot - aber evt. hilft das ja jemandem einmal )