Forum: Mikrocontroller und Digitale Elektronik CRC Fehler bei Modbus RTU


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Denis (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,

Ich bin schon eine Weile dabei, eine Kommunikation über Modbus zwischen 
meinem Smart-Meter (CAN-EZ3 von technischer Alternative) und meinem 
Atmega 2560 über den max485 hin zu bekommen. Das SMart-Meter ist der 
Master. ICh kann ohne Probleme Nachrichten vom Smart-Meter empfangen und 
auch vernünftig lesen. Jetzt möchte ich allerdings auch antworten, um 
gewisse Messwerte zurück zu schicken. Und da sagt mir mein Smart-Meter, 
dass er einen CRC Fehler hat.

Meine Hardware sieht folgendermaßen aus: der Max485 ist auf einem 
fertigen Board von Ebay, 20k Pullup an "A", 20k pulldown an "B" und 
zwischen "A" und "B" 120Ohm. Auf Smart-Meter Seite finde ich keine 
Information beim Hersteller, ob da was terminiert ist.

Bisher habe ich an der Zeit zwischen Anfrage und Antwort gespielt. Das 
bringt etwas Verbesserung, jede 4. bis 6. Antwort ist lesbar. Aktuell 
lass ich etwa 1,2ms Pause dazwischen.

Das Bild ist direkt an den Klemmen am Smart-Meter gemessen. Die Masse 
vom Tastkopf ist an "B", der Tastkopf selbst an "A".

Wie könnte ich weiter vorgehen um den Fehler einzukreisen?

Vielen Dank für eure Antworten!


Denis

von N. M. (mani)


Lesenswert?

Denis schrieb:
> Bisher habe ich an der Zeit zwischen Anfrage und Antwort gespielt. Das
> bringt etwas Verbesserung, jede 4. bis 6. Antwort ist lesbar. Aktuell
> lass ich etwa 1,2ms Pause dazwischen.

Also kann es wohl nicht ganz falsch sein. Ansonsten würde es ja nicht ab 
und zu gehen.

Denis schrieb:
> Das Bild ist direkt an den Klemmen am Smart-Meter gemessen. Die Masse
> vom Tastkopf ist an "B", der Tastkopf selbst an "A".

Du misst also differentiell. Dafür sieht dein Signal aber echt 
bescheiden aus.

Denis schrieb:
> Wie könnte ich weiter vorgehen um den Fehler einzukreisen?

Du könntest als erstes die Fälle die schief gehen mitschreiben um die 
dann nochmal genauer anzuschauen. Die Frage ist ja ob es an einem 
fehlerhaften Datum liegt das du sendest, an Störungen auf der Leitung 
oder evtl an einer Kollision. Das müsstest du am besten messtechnisch 
erfassen.
Am besten analog und digital.
Wenn dein Oszi nur einen Kanal hat dann miss mit dem analog und hänge 
noch einen RS485/FTDI zum lauschen dran.

Die Daten kannst Du dann hier wieder zeigen und man schaut Mal drüber.

von N. M. (mani)


Lesenswert?

Denis schrieb:
> Atmega 2560

Was für einen Clock verwendest du? Und was für eine Datenrate auf RS485?

Denis schrieb:
> Das SMart-Meter ist der Master. ICh kann ohne Probleme Nachrichten vom
> Smart-Meter empfangen und auch vernünftig lesen. Jetzt möchte ich
> allerdings auch antworten, um gewisse Messwerte zurück zu schicken.

Das Smart Meter unterstützt auch den Slave Modus. Warum verwendest du 
nicht den? Damit wären Kollisionen schonmal weniger möglich. Es ist 
ungewöhnlich an einen Master etwas zu schicken ohne Requests. Kann 
funktionieren, muss aber nicht.

von MaWin (Gast)


Lesenswert?

Denis schrieb:
> Meine Hardware sieht folgendermaßen aus: der Max485 ist auf einem
> fertigen Board von Ebay,

Hat das denn eine Senderichtungsumschaltung, bedienst du die richtig ?

Sendest du schnell genug damit es als eine Botschaft verstanden wird, 
und ist deine Wartepause danach lang genug damit er Zeit hat, das Ende 
zu erkennen und die Botschaft zu verarbeiten ?

Könnte dein eigener Code deine gesendete Botschaft akzeptieren und die 
CRC validieren ?

Ich bau mir gerne (Arduinos mit LCD als) Empfänger, damit ich sehe, ob 
ich zumindest so sende, wie ich glaube dass es das Fertiggerät hören 
will.

von Hmmm (Gast)


Lesenswert?

Denis schrieb:
> Max485 ist auf einem fertigen Board von Ebay, 20k Pullup an "A", 20k
> pulldown an "B" und zwischen "A" und "B" 120Ohm.

Viel zu grosse Bias-Widerstände für einen terminierten Bus.

Bei 5V und beidseitiger Terminierung mit 120 Ohm sind 680 Ohm sinnvoll, 
mit Deinen Werten erreichst Du eine Differenz von 7mV statt der 
geforderten 200mV.

Undefinierte Pegel können als Datenmüll interpretiert werden.

Denis schrieb:
> Die Masse vom Tastkopf ist an "B", der Tastkopf selbst an "A".

Miss besser zwischen GND und A.

Die Frage nach der Taktquelle wurde ja schon gestellt, auch schiefe 
Baudraten passen zu sporadischen Fehlern.

Wenn Du einen Logic Analyzer hast, kannst Du nochmal die Daten- und 
Enable-Leitungen des MAX485 (also die Controllerseite) angucken, um 
Probleme bei der RX/TX-Umschaltung zu sehen und Dir die gesendeten Daten 
anzusehen.

von Denis (Gast)


Lesenswert?

Hallo Zusammen,

Ich danke euch für eure Beiträge.

N. M. schrieb:
> Am besten analog und digital.
> Wenn dein Oszi nur einen Kanal hat dann miss mit dem analog und hänge
> noch einen RS485/FTDI zum lauschen dran.

Mein Oszi hat zwei Kanäle, aber kein Logic Analyzer. Das ist ein 
einfaches Von Conrad, nennt sich sds200. Reicht bis jetzt für meine 
Anforderungen.

N. M. schrieb:
> Was für einen Clock verwendest du? Und was für eine Datenrate auf RS485?

Ich nutze so einen Arduino-Nachbau, da ist ein 16MHz Quarz drauf. RS485 
läuft zur Zeit mit 19200 Baud, aber bei 2400Baud lief es auch nicht.

N. M. schrieb:
> Das Smart Meter unterstützt auch den Slave Modus. Warum verwendest du
> nicht den?

Ich denke, damit wäre das Problem nicht gelöst. Ein Slave war für mich 
einfacher auf dem AVR zu realisieren.

N. M. schrieb:
> Es ist
> ungewöhnlich an einen Master etwas zu schicken ohne Requests. Kann
> funktionieren, muss aber nicht.

Was meinst du damit genau? Auf meinem Oszi-Bild ist auf der linken Seite 
die Anfrage vom Smart-Meter, dann meine kurze Pause, und auf der rechten 
Seite die Antwort von meinem Atmega zu sehen.

MaWin schrieb:
> Hat das denn eine Senderichtungsumschaltung, bedienst du die richtig ?
>
> Sendest du schnell genug damit es als eine Botschaft verstanden wird,
> und ist deine Wartepause danach lang genug damit er Zeit hat, das Ende
> zu erkennen und die Botschaft zu verarbeiten ?

Ja, die gibt es und die bediene ich auch, sonst würde es ja manchmal 
nicht funktionieren. Bis jetzt schalte ich den Max485 wieder auf 
Empfang, wenn mein Transmit-Interrupt sagt, dass die Übertragung 
abgeschlossen ist. Ob ich da auch noch eine kleine Pause brauche, bis 
ich wieder auf Empfang schalte?

Hmmm schrieb:
> Die Frage nach der Taktquelle wurde ja schon gestellt, auch schiefe
> Baudraten passen zu sporadischen Fehlern.

Für die Baudrate nutze ich den Berechnungscode von hier aus den 
Artikeln:

#define BAUD1 19200UL      // Baudrate

// Berechnungen
#define UBRR_VAL1 ((F_CPU+BAUD1*8)/(BAUD1*16)-1)   // clever runden
#define BAUD_REAL1 (F_CPU/(16*(UBRR_VAL1+1)))     // Reale Baudrate
#define BAUD_ERROR1 ((BAUD_REAL1*1000)/BAUD1) // Fehler in Promille, 
1000 = kein Fehler.

#if ((BAUD_ERROR1<990) || (BAUD_ERROR1>1010))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu 
hoch!
#endif


Vielleicht liegt es auch am Kabel. Ich nutze zur Zeit ein JY(ST)Y, 
2x2x0,8. Den Schirm habe ich an einer Seite mit auf Masse gelegt. 
Verlegt ist es mit neben den Stromkabeln und ca. 8m lang. Ich denke, bei 
den "langsamen" Baudraten sollte das eigentlich kein Problem weiter 
sein. Ob der Max485 bessere Pegel bringt, wenn ich ihm mit 12V und nicht 
mit 5V versorge?

Denis

von Hmmm (Gast)


Lesenswert?

Denis schrieb:
> Aktuell
> lass ich etwa 1,2ms Pause dazwischen.

Du musst bei Modbus RTU vor dem Senden 3.5 Zeichenlängen Stille 
einhalten. Bei 9600/8N1 wären das schon 3.65ms, welche Baudrate (und 
Stopbit- und Parity-Einstellungen) verwendest Du?

Denis schrieb:
> Für die Baudrate nutze ich den Berechnungscode von hier

Die Frage war eher, ob Quarz oder interner RC-Oszillator. Letzterer ist 
oft nicht genau genug.

Denis schrieb:
> Vielleicht liegt es auch am Kabel.

Sehr unwahrscheinlich, RS485 ist sehr robust.

von Zack B. (zack)


Lesenswert?

Mal was anderes: Hast du den korrekten CRC Algorithmus mit korrektem 
Polynom?

von Andy (Gast)


Lesenswert?

Ich kenne die Atmel Prozessoren nicht, habe aber einmal einen Blick ins 
Datenblatt geworfen.
Es gibt ein Register: UCSRnA – USART Control and Status Register A
und darin Bit 6 – TXCn: USART Transmit Complete
Ich würde sagen, wenn dieses Bit gesetzt ist, darfst du wieder auf 
Empfang schalten. Andernfalls zerschießt du dir das letzte Byte von der 
CRC.

von Denis (Gast)


Lesenswert?

Hallo Zusammen,

Hmmm schrieb:
> Du musst bei Modbus RTU vor dem Senden 3.5 Zeichenlängen Stille
> einhalten. Bei 9600/8N1 wären das schon 3.65ms, welche Baudrate (und
> Stopbit- und Parity-Einstellungen) verwendest Du?

Genau, weil ich diese Info gefunden habe, habe ich die Pause eingebaut. 
Bei 19200/8N1 bin ich irgendwo bei 1,7ms rausgekommen. Da war allerdings 
nix zu machen, bei 1,2ms funktioniert es wenigstens sporadisch. Länger 
als 1,7ms habe ich bis jetzt noch nicht probiert, könnte ich aber mal 
machen.

Zack B. schrieb:
> Mal was anderes: Hast du den korrekten CRC Algorithmus mit korrektem
> Polynom?

Ja, das passt. Ich habe da verschiedene Websites probiert, die mir 
bestätigen, dass meine Daten valide sind. Außerdem sind ja hin und 
wieder Daten lesbar.

Andy schrieb:
> Ich würde sagen, wenn dieses Bit gesetzt ist, darfst du wieder auf
> Empfang schalten. Andernfalls zerschießt du dir das letzte Byte von der
> CRC.

Genau so habe ich es gemacht. Mit dem letzten Byte aktiviere ich den 
Interrupt zu dem Status-Bit und wenn der kommt schalte ich wieder um auf 
Empfangen.

Ich werde mal noch bisschen an den Pausen-Zeiten probieren. Wenn das 
alles nichts bringt muss ich mal schauen, ob ich irgendwo bessere 
Messtechnik borgen kann, mit meinem zarten Oszi ist da nicht so richtig 
was zu wollen..


Denis

von Hmmm (Gast)


Lesenswert?

Denis schrieb:
> Bei 19200/8N1 bin ich irgendwo bei 1,7ms rausgekommen. Da war allerdings
> nix zu machen, bei 1,2ms funktioniert es wenigstens sporadisch.

1.82ms wären es da.

Ich tendiere dazu, dass es an den falschen Bias-Widerständen liegt. Wenn 
Du die Pause lang genug machst, steigt das Risiko, dass in der Zeit 
fälschlicherweise ein Startbit erkannt wird. Wenn Du sie kürzer machst, 
sinkt diese Gefahr, dafür verletzt Du das Modbus-RTU-Timing.

von Denis (Gast)


Lesenswert?

Hmmm schrieb:
> Ich tendiere dazu, dass es an den falschen Bias-Widerständen liegt.

Und genau da lag der Fehler, du hattest es ja schon gleich am Anfang 
geschrieben. Habe die beiden 20k gegen 1k getauscht, seitdem klappt es 
vom feinsten.

Wieder was gelernt, solche fertigen Boards müssen nicht zwingend gut 
funktionieren..

Vielen Dank an Alle für die Hilfe!


Denis

von MaWin (Gast)


Lesenswert?


von Harald A. (embedded)


Lesenswert?

Eine Investition in einen 10€ Logic Analyzer mit Pulseview schadet auch 
hier bestimmt nicht. MODBUS wird von Pulseview unterstützt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.