Fehlermeldung mit Modbus Library

Nun erfolgt folgende Ausgabe

[V] 22879| ModbusMessage.cpp    [ 529] checkData: Check data #3
[D] 22884| ModbusClientRTU.cpp  [ 107] addRequestM: request for 01/04
[D] 22889| ModbusClientRTU.cpp  [ 156] addToQueue: RC=01
[D] 22889| ModbusClientRTU.cpp  [ 174] handleConnection: Pulled request from queue
[D] 22890| ModbusClientRTU.cpp  [ 118] addRequestM: RC=00
[D] Sent packet: @3FFB98E4/6:
  | 0000: 01 04 00 2A 00 2A                                 |...*.*          |
[D] 22921| ModbusClientRTU.cpp  [ 179] handleConnection: Request sent.
[D] Received packet: @3FFBDB4C/1:
  | 0000: E5                                                |.               |
[D] 22933| ModbusClientRTU.cpp  [ 185] handleConnection: Error response (1 bytes) received.
[V] Data: @3FFBDB4C/1:
  | 0000: E5                                                |.               |
[D] 22952| ModbusClientRTU.cpp  [ 214] handleConnection: Response generated.
[V] Response packet: @3FFBDB4C/3:
  | 0000: 01 84 E5                                          |...             |
e[1;33m[E] 22967| SDM630_004.ino       [  57] handleError: Error response: E5 - Packet length error
e[0m

Das kommt mir leider bekannt vor, im Github-Issuetracker habe ich einen weiteren Nutzer, dem das passiert.

Mir fehlen da noch ein paar Logmeldungen aus RTUutils.cpp - kannst du mal nachsehen, ob da am Anfang der Datei vielleicht der LOCAL_LOG_LEVEL auf irgendwas gesetzt wird? Wenn ja, kommentiere die Zeile bitte mal aus. Ich würde gerne die Originalantwort des Zählers sehen, so, wie sie aus der Serial2 kommt.

Gerade gesehen: da ist kein Log-Statement dafür drin...

Kannst Du DIr die Lib jetzt nochmal von Github herunterladen und es damit (inklusive LOG_LEVEL_VERBOSE!) nochmal probieren? Ich habe einen Dump an die Stelle gesetzt, wo die ungefilterte Message hereinkommt.

habe in Logging.h

#ifndef LOG_LEVEL
#define LOG_LEVEL LOG_LEVEL_VERBOSE // LOG_LEVEL_ERROR
#endif

#ifndef LOCAL_LOG_LEVEL
#define LOCAL_LOG_LEVEL LOG_LEVEL
#endif

in RTUUtils.cpp steht..

#include "options.h"
#include "ModbusMessage.h"
#include "RTUutils.h"
#undef LOCAL_LOG_LEVEL
// #define LOCAL_LOG_LEVEL LOG_LEVEL_VERBOSE
#include "Logging.h"

Ergebnis ist nun...

[V] 20944| ModbusMessage.cpp    [ 529] checkData: Check data #3
14:24:28.364 -> [D] 20948| ModbusClientRTU.cpp  [ 107] addRequestM: request for 01/04
14:24:28.364 -> [D] 20953| ModbusClientRTU.cpp  [ 156] addToQueue: RC=01
14:24:28.364 -> [D] 20954| ModbusClientRTU.cpp  [ 174] handleConnection: Pulled request from queue
14:24:28.364 -> [D] 20955| ModbusClientRTU.cpp  [ 118] addRequestM: RC=00
14:24:28.464 -> [D] Sent packet: @3FFB98E4/6:
14:24:28.464 ->   | 0000: 01 04 00 2A 00 2A                                 |...*.*          |
14:24:28.464 -> [D] 20985| ModbusClientRTU.cpp  [ 179] handleConnection: Request sent.
14:24:28.464 -> [D] Raw buffer received: @3FFB2068/1:
14:24:28.464 ->   | 0000: 00                                                |.               |
14:24:28.464 -> [D] Received packet: @3FFBDB4C/1:
14:24:28.464 ->   | 0000: E5                                                |.               |
14:24:28.464 -> [D] 21008| ModbusClientRTU.cpp  [ 185] handleConnection: Error response (1 bytes) received.
14:24:28.464 -> [V] Data: @3FFBDB4C/1:
14:24:28.464 ->   | 0000: E5                                                |.               |
14:24:28.464 -> [D] 21026| ModbusClientRTU.cpp  [ 214] handleConnection: Response generated.
14:24:28.464 -> [V] Response packet: @3FFBDB4C/3:
14:24:28.464 ->   | 0000: 01 84 E5                                          |...             |
14:24:28.464 -> e[1;33m[E] 21041| SDM630_004.ino       [  57] handleError: Error response: E5 - Packet length error
14:24:28.464 -> e[0m[V]

Das ist das Problem. Da kommt irgendwo ein herrenloses 0-Byte her. Da das bei dem anderen User genauso ist, liegt die Vermutung nahe, dass die Lib das irgendwie erzeugt.

Ich würde gerne noch ein paar mehr Checks einbauen - hast du noch die Geduld, es damit dann nochmal zu probieren?

Klar, möchte eine stabile Lösung und wenn ich dabei anderen und auch dir weiterhelfen kann, wäre dies klasse...

1 Like

Versuche bitte mal folgendes - ich habe im Moment den Verdacht, dass der Zähler etwas Zeit braucht, um nach dem Übernehmen der RS485-Leitung durch den Client empfangsbereit zu sein.

In Deinen Sketch füge am Anfang ein und ändere die Deklaration des ModbusClientRTU:

// Definitions for this special case
#define RXPIN GPIO_NUM_16
#define TXPIN GPIO_NUM_17
#define REDEPIN GPIO_NUM_4
#define BAUDRATE 9600
#define FIRST_REGISTER 0x002A
#define NUM_VALUES 21
#define READ_INTERVAL 10000

bool data_ready = false;
float values[NUM_VALUES];
uint32_t request_time;

// ******* Das hier einfuegen! *******
void RTStest(bool level) {
  if (!level) delay(10); // Nur bei Ende der Sendung 
  digitalWrite(REDEPIN, level);
  if (level) delay(10); // Nur bei Beginn der Sendung
}
// ******** bis hier! *****

// Create a ModbusRTU client instance
// The RS485 module has no halfduplex, so the second parameter with the DE/RE pin is required!
ModbusClientRTU MB(Serial2, RTStest);  // <<<<---- ***** Hier aendern!

Hier benutze ich die Variante mit dem RTS callback, um vor dem Umschalten der RE/DE-Leitung etwas zu warten. Du kannst gerne die 10ms auch mal ändern, wenn du längere oder kürzere Pausen probieren willst.

Nach der Änderung...

15:27:54.368 -> [V] 34933| ModbusMessage.cpp    [ 529] checkData: Check data #3
15:27:54.368 -> [D] 34937| ModbusClientRTU.cpp  [ 107] addRequestM: request for 01/04
15:27:54.368 -> [D] 34942| ModbusClientRTU.cpp  [ 156] addToQueue: RC=01
15:27:54.368 -> [D] 34944| ModbusClientRTU.cpp  [ 118] addRequestM: RC=00
15:27:55.471 -> [D] Received packet: @3FFBDB4C/1:
15:27:55.471 ->   | 0000: E0                                                |.               |
15:27:55.471 -> [D] 36002| ModbusClientRTU.cpp  [ 185] handleConnection: Error response (1 bytes) received.
15:27:55.471 -> [V] Data: @3FFBDB4C/1:
15:27:55.471 ->   | 0000: E0                                                |.               |
15:27:55.471 -> [D] 36018| ModbusClientRTU.cpp  [ 214] handleConnection: Response generated.
15:27:55.471 -> [V] Response packet: @3FFBDB4C/3:
15:27:55.471 ->   | 0000: 01 84 E0                                          |...             |
15:27:55.471 -> e[1;33m[E] 36033| SDM630_004.ino       [  64] handleError: Error response: E0 - Timeout
15:27:55.471 -> e[0m[D] 36042| ModbusClientRTU.cpp  [ 174] handleConnection: Pulled request from queue
15:27:55.517 -> [D] Sent packet: @3FFB98CC/6:
15:27:55.517 ->   | 0000: 01 04 00 2A 00 2A                                 |...*.*          |
15:27:55.517 -> [D] 36078| ModbusClientRTU.cpp  [ 179] handleConnection: Request sent.

mit 5ms

15:31:33.455 -> [V] 109496| ModbusMessage.cpp    [ 529] checkData: Check data #3
15:31:33.455 -> [D] 109500| ModbusClientRTU.cpp  [ 107] addRequestM: request for 01/04
15:31:33.455 -> [D] 109505| ModbusClientRTU.cpp  [ 156] addToQueue: RC=01
15:31:33.455 -> [D] 109507| ModbusClientRTU.cpp  [ 118] addRequestM: RC=00
15:31:34.440 -> [D] Received packet: @3FFBDB4C/1:
15:31:34.440 ->   | 0000: E0                                                |.               |
15:31:34.440 -> [D] 110470| ModbusClientRTU.cpp  [ 185] handleConnection: Error response (1 bytes) received.
15:31:34.440 -> [V] Data: @3FFBDB4C/1:
15:31:34.440 ->   | 0000: E0                                                |.               |
15:31:34.440 -> [D] 110486| ModbusClientRTU.cpp  [ 214] handleConnection: Response generated.
15:31:34.440 -> [V] Response packet: @3FFBDB4C/3:
15:31:34.440 ->   | 0000: 01 84 E0                                          |...             |
15:31:34.440 -> e[1;33m[E] 110501| SDM630_004.ino       [  66] handleError: Error response: E0 - Timeout
15:31:34.440 -> e[0m[D] 110510| ModbusClientRTU.cpp  [ 174] handleConnection: Pulled request from queue
15:31:34.474 -> [D] Sent packet: @3FFB992C/6:
15:31:34.474 ->   | 0000: 01 04 00 2A 00 2A                                 |...*.*          |
15:31:34.474 -> [D] 110537| ModbusClientRTU.cpp  [ 179] handleConnection: Request sent.

mit 15ms

15:32:49.031 -> [V] 4739| ModbusMessage.cpp    [ 529] checkData: Check data #3
15:32:49.031 -> [D] 4742| ModbusClientRTU.cpp  [ 107] addRequestM: request for 01/04
15:32:49.031 -> [D] 4747| ModbusClientRTU.cpp  [ 156] addToQueue: RC=01
15:32:49.031 -> [D] 4748| ModbusClientRTU.cpp  [ 118] addRequestM: RC=00
15:32:49.084 -> [D] Received packet: @3FFBDB4C/1:
15:32:49.084 ->   | 0000: E0                                                |.               |
15:32:49.084 -> [D] 4793| ModbusClientRTU.cpp  [ 185] handleConnection: Error response (1 bytes) received.
15:32:49.084 -> [V] Data: @3FFBDB4C/1:
15:32:49.084 ->   | 0000: E0                                                |.               |
15:32:49.084 -> [D] 4809| ModbusClientRTU.cpp  [ 214] handleConnection: Response generated.
15:32:49.084 -> [V] Response packet: @3FFBDB4C/3:
15:32:49.084 ->   | 0000: 01 84 E0                                          |...             |
15:32:49.084 -> e[1;33m[E] 4824| SDM630_004.ino       [  66] handleError: Error response: E0 - Timeout
15:32:49.131 -> e[0m[D] 4833| ModbusClientRTU.cpp  [ 174] handleConnection: Pulled request from queue
15:32:49.131 -> [D] Sent packet: @3FFB98CC/6:
15:32:49.131 ->   | 0000: 01 04 00 2A 00 2A                                 |...*.*          |
15:32:49.131 -> [D] 4879| ModbusClientRTU.cpp  [ 179] handleConnection: Request sent.

Mist. Nur noch Timeouts - das war nichts. Kannst die Änderung wieder rauswerfen, die Theorie ist tot.

Hast du eventuell einen Logic Analyzer zur Hand und kannst die TX-, RX- und RE/DE-Leitung abgreifen? Mich würde interessieren, ob tatsächlich der Zähler die 0x00 sendet, oder ob das ein Artefakt ist.

Nein, habe ich nicht, leider.

Oszilloskop dann wahrscheinlich auch nicht :wink:

Ich bin ein bisschen ratlos, gebe ich zu:

  • die serielle Kommunikation hat kein Leck, soweit ich sehe. Keine andere Task o.ä. kann sich da einmischen.
  • das DE/RE-Handling scheint grundsätzlich ja zu klappen und produziert selbst keine Daten.
  • damit muss das überzählige 0x00-Byte tatsächlich aus der seriellen Schnittstelle kommen.
  • da kommt nur hinein, was aus dem RS485-Adapter kommt - also muss auch das 0x00-Byte daher stammen.
  • es könnte ein Artefakt des Adapters sein, oder es kommt über die Leitung.
  • es kann eine Einstreuuung auf die Leitung sein - unwahrscheinlich, weil da dann auch andere Bytes kommen müssten.
  • der Adapter könnte es aus welchem Grund auch immer erzeugen.
  • und zuletzt: der Zähler sendet es - aber warum? Ist nicht spezifiziert und auch keine vollständige Modbus-Nachricht.

Hast du noch andere Typen von RS485-Adaptern, die du versuchsweise mal einbauen könntest? Wenn es ein Adapter-Artefakt wäre, müsste es mit einem Adapter eines anderen Herstellers verschwinden. Obwohl: die machen ja nicht wirklich viel...

Interessant ist das hier: 0-Bytes durch RO erzeugt. Da geht es zwar um einen FTDI-Adapter, der RO schaltet, aber das Verhalten ist ähnlich. Es muss irgendwie mit dem Toggeln von RE/DE zu tun haben, denn die beiden anderen User auf Github benutzen auch solche Adapter.

Du könntest mal versuchen, den RE-Pin mit einem 10K-Widerstand auf Vcc hochzuziehen. Die Lib schaltet den im Normalzustand auf LOW, wodurch der Pullup nur in Pausen mit undefiniertem Zustand wirksam werden sollte.

Noch einer. Der Link hier beschreibt das im Detail; versuche mal, wie dort beschrieben, den RX-Pin (GPIO_NUM_16) mit den internen Pullup-Widerständen hochzuziehen (pinMode(GPIO_NUM_16, INPUT_PULLUP);

Hallo Miq1,

eigentlich sollten bei diesem alle 4 Leitungen zum µC mit PullUp Widerständen beschaltet sein. Kann es nachmessen.
Modbus_03

Habe keinen anderen Adapter. Kann mir aber kaum einen Einfluß vorstellen. Außer dem 485er Chip und den PullUp µC seitig, Busabschluß 120Ohm und den PullUp/PullDown an den A/B Leitungen ist ja nichts drauf. Zumindest verhält sich meine gelötete Variante und die prototypisch gesteckte Variante gleich - anderes Wemos ESP32 und RS485 Board.

Modbus_04

Gruß Arduino4Fun

Hallo Miq1,

habe nochmals den Aufbau gewechselt. Die Ausgabe sieht ein wenig anders aus...

[V] 216990| ModbusMessage.cpp    [ 529] checkData: Check data #3
18:48:01.436 -> [D] 216995| ModbusClientRTU.cpp  [ 107] addRequestM: request for 01/04
18:48:01.436 -> [D] 216999| ModbusClientRTU.cpp  [ 156] addToQueue: RC=01
18:48:01.436 -> [D] 217000| ModbusClientRTU.cpp  [ 174] handleConnection: Pulled request from queue
18:48:01.436 -> [D] 217001| ModbusClientRTU.cpp  [ 118] addRequestM: RC=00
18:48:01.484 -> [D] Sent packet: @3FFB98E4/6:
18:48:01.484 ->   | 0000: 01 04 00 2A 00 2A                                 |...*.*          |
18:48:01.484 -> [D] 217038| ModbusClientRTU.cpp  [ 179] handleConnection: Request sent.
18:48:01.484 -> [D] Raw buffer received: @3FFB2470/1:
18:48:01.484 ->   | 0000: 00                                                |.               |
18:48:01.484 -> [D] Received packet: @3FFBDB4C/1:
18:48:01.484 ->   | 0000: E5                                                |.               |
18:48:01.484 -> [D] 217061| ModbusClientRTU.cpp  [ 185] handleConnection: Error response (1 bytes) received.
18:48:01.484 -> [V] Data: @3FFBDB4C/1:
18:48:01.532 ->   | 0000: E5                                                |.               |
18:48:01.532 -> [D] 217079| ModbusClientRTU.cpp  [ 214] handleConnection: Response generated.
18:48:01.532 -> [V] Response packet: @3FFBDB4C/3:
18:48:01.532 ->   | 0000: 01 84 E5                                          |...             |
18:48:01.532 -> e[1;33m[E] 217094| SDM630_004.ino       [  57] handleError: Error response: E5 - Packet length error
18:48:01.532 -> e[0m

Danke - der Fehler E5 bleibt aber der gleiche, weil das 0-Byte empfangen wird. Das kommt in exakt der gleichen Millisekunde, in der der Versand abgeschlossen ist. Spricht also viel dafür, dass es entweder schon im RX-FIFO wartet oder durch das Toggeln ausgelöst wird.

Ich glaube immer noch, dass das letztere der Auslöser ist. Dafür passt das Fehlerbild einfach zu gut zu dem, das ich oben verlinkt hatte.

Der Unterschied zu den beiden Usern im Github-Issue ist, dass da sowohl vor als auch nach dem Responsepaket ein 0-Byte kommt. Der Zeitabstand zwischen 0-Byte und Message ist so kurz, dass der ESP32-Client kein 3,5-Character-Gap erkennt, das Meldungen trennt. Und das 1,5c-Gap, das eigentlich nicht zwischen Zeichen einer Meldung auftreten darf, checkt der ESP mangels verfügbarer Geschwindigkeit nicht. Spricht aber trotzdem dafür, dass es das Toggeln ist, das das auslöst.

Tu' mir mal den Gefallen und baue ein pinMode(REDEPIN, INPUT_PULLUP); in dein setup() ein...

nach Einfügen pinMode(REDEPIN, INPUT_PULLUP); vor Serial2.begin(BAUDRATE, SERIAL_8N1, RXPIN, TXPIN);

20:28:02.556 -> [V] 6061| ModbusMessage.cpp    [ 529] checkData: Check data #3
20:28:02.556 -> [D] 6061| ModbusClientRTU.cpp  [ 107] addRequestM: request for 01/04
20:28:02.556 -> [D] 6061| ModbusClientRTU.cpp  [ 156] addToQueue: RC=01
20:28:02.556 -> [D] 6066| ModbusClientRTU.cpp  [ 118] addRequestM: RC=00
20:28:02.656 -> [D] Received packet: @3FFBDB4C/1:
20:28:02.656 ->   | 0000: E0                                                |.               |
20:28:02.656 -> [D] 6134| ModbusClientRTU.cpp  [ 185] handleConnection: Error response (1 bytes) received.
20:28:02.656 -> [V] Data: @3FFBDB4C/1:
20:28:02.656 ->   | 0000: E0                                                |.               |
20:28:02.656 -> [D] 6149| ModbusClientRTU.cpp  [ 214] handleConnection: Response generated.
20:28:02.656 -> [V] Response packet: @3FFBDB4C/3:
20:28:02.656 ->   | 0000: 01 84 E0                                          |...             |
20:28:02.656 -> e[1;33m[E] 6166| SDM630_004.ino       [  57] handleError: Error response: E0 - Timeout
20:28:02.709 -> e[0m[D] 6174| ModbusClientRTU.cpp  [ 174] handleConnection: Pulled request from queue
20:28:02.709 -> [D] Sent packet: @3FFB98CC/6:
20:28:02.709 ->   | 0000: 01 04 00 2A 00 2A                                 |...*.*          |
20:28:02.709 -> [D] 6190| ModbusClientRTU.cpp  [ 179] handleConnection: Request sent.

und ganz am Ende

  MB.setTimeout(2000);
// Start ModbusRTU background task
  MB.begin();

  pinMode( REDEPIN,INPUT_PULLUP );
}

20:32:47.534 -> [V] 8072| ModbusMessage.cpp    [ 529] checkData: Check data #3
20:32:47.534 -> [D] 8072| ModbusClientRTU.cpp  [ 107] addRequestM: request for 01/04
20:32:47.534 -> [D] 8072| ModbusClientRTU.cpp  [ 156] addToQueue: RC=01
20:32:47.534 -> [D] 8077| ModbusClientRTU.cpp  [ 118] addRequestM: RC=00
20:32:47.672 -> [D] Received packet: @3FFBDB4C/1:
20:32:47.672 ->   | 0000: E0                                                |.               |
20:32:47.672 -> [D] 8197| ModbusClientRTU.cpp  [ 185] handleConnection: Error response (1 bytes) received.
20:32:47.672 -> [V] Data: @3FFBDB4C/1:
20:32:47.672 ->   | 0000: E0                                                |.               |
20:32:47.672 -> [D] 8212| ModbusClientRTU.cpp  [ 214] handleConnection: Response generated.
20:32:47.672 -> [V] Response packet: @3FFBDB4C/3:
20:32:47.672 ->   | 0000: 01 84 E0                                          |...             |
20:32:47.672 -> e[1;33m[E] 8229| SDM630_004.ino       [  57] handleError: Error response: E0 - Timeout
20:32:47.719 -> e[0m[D] 8237| ModbusClientRTU.cpp  [ 174] handleConnection: Pulled request from queue
20:32:47.719 -> [D] Sent packet: @3FFB98CC/6:
20:32:47.719 ->   | 0000: 01 04 00 2A 00 2A                                 |...*.*          |
20:32:47.719 -> [D] 8253| ModbusClientRTU.cpp  [ 179] handleConnection: Request sent.