Jump to content

RS485 als master Modbus RTU konfigurieren


Recommended Posts

Posted

Hallo zusammen

Ich möchte einen Laserdistanzsensor mit dem RS485 Bricklet auslesen. Allerdings schaffe ich es nicht das Bricklet so zu Konfigurieren, dass ich etwas beim Sensor auslesen kann und hatte gehofft hier Hilfe zu finden. Der Sensor den ich verwende ist von Baumer: OM20-P0120.HH.TXN

Folgend der Ausschnitt aus der Anleitung um den Modbus einzurichten:

image.png.2d357c55196e161d49c53bc66580d104.png

Im Brickviewer habe ich das RS485 Bricklet entsprechend eingerichtet, löse jedoch beim senden einen Fehler aus.

image.png.31bdbf95eb40591d3a15e07e13242e98.png

 

Folgende drei Punkte sind für mich unklar und die könnten zu einem Fehler führen:

  • Ist meine Angabe bei "First Input Number" korrekt? Ich würde gerne wie nach Anleitung bei Addresse 200 die Messwerte auslesen, und so wie ich die Tinkerforge Dokumentation verstanden habe hat das Input Register den Prefix 3.
  • In der Anleitung des Sensors geben Sie eine Function ID von 4 an, im Brickviewer kann ich diesbezüglich allerdings nichts konfigurieren. Weiss jemand was dieser Wert bedeutet?
  • Die Sensoren haben zwei Kabel für die Kommunikation und können somit im Half-Duplex Modus betrieben werden. Ist es dann möglich zwei Sensoren an ein RS485 Bricklet anzuhängen, auch wenn ich die Slave Adressen bei den Sensoren nicht ändern kann?

Sieht jemand den Fehler beim Einrichten und könnte mir bitte helfen? Bin sehr dankbar für jegliches Feedback.

Freundliche Grüsse

Fridolin

Posted
  • First Input Number sollte korrekt sein.
  • „Function ID 4“ bedeutet „Read Input Registers“, was du korrekt ausgewählt hast.
  • Wenn die Sensoren für Halbduplex vorgesehen sind, muss das Bricklet auch auf Halbduplex eingestellt werden. Dabei werden RX und TX durch die DIP-Schalter gebrückt. Man kann die RX- und TX-Klemmen am Bricklet dann nicht unabhängig voneinander verwenden. Ob du deine Sensoren an den RX- oder TX-Klemmen anschließt, ist egal.

Meine Verschläge:

  • Überprüfe, ob die DIP-Schalter auf „Half-Duplex Terminated“ eingestellt sind, also 1, 2 und 3 ON, 4 nicht. Auf der Unterseite vom Bricklet ist das auch abgebildet.
  • Überprüfe, ob RX/TX+ und RX/TX- vom Sensor korrekt angeschlossen sind. Im Zweifelsfall einfach mal tauschen. Da kann nichts kaputtgehen.
  • Lies erstmal nur einen Wert ab Adresse 200 aus, also „Number of Inputs“ auf 1.
  • Sind die Sensoren neu oder besteht die Möglichkeit, dass sie auf eine andere Adresse oder oder Baudrate eingestellt wurden?

Ich bin mir übrigens nicht sicher, warum du meinst, dass du die Slave-Adresse der Sensoren nicht ändern kannst. Laut Anleitung steht die Adresse in Holding Register 1100 und kann einfach mit einer anderen Adresse überschrieben werden. Du kannst also bis zu 247 Sensoren an einem Bricklet anschließen.

Posted
On 1/11/2024 at 2:23 PM, fridolin11 said:

Ist meine Angabe bei "First Input Number" korrekt? Ich würde gerne wie nach Anleitung bei Addresse 200 die Messwerte auslesen, und so wie ich die Tinkerforge Dokumentation verstanden habe hat das Input Register den Prefix 3.

Da ist Modbus leider etwas verwirrend: Es gibt Registernummern, die bei 1 beginnen und Registeradressen, die bei 0 beginnen. Also z.B. das Register mit der Adresse 200 hat die Registernummer 201. Viele Hersteller bringen das auch in den Anleitungen durcheinander.

Außerdem gibt es die Präfixe, die im Endeffekt den Typ des Registers angeben (Weshalb die oft weggelassen werden):

  • 0 für Coils (les- und schreibbare 1-Bit-Werte)
  • 1 für Discrete Inputs (nur lesbare 1-Bit-Werte)
  • 3 für Input Registers (nur lesbare 16-Bit-Werte)
  • 4 für Holding Registers (les- und schreibbare 16-Bit-Werte)

Iin deinem Fall kann es also sein, dass du nicht bei 300200 anfangen musst zu lesen, sondern bei 300199 oder 300201.

Um zu testen, ob die Kommunikation prinzipiell funktioniert, kannst du auch mit "Read Holding Registers" das Register 401100 (oder 401099 oder 401101) lesen. Da solltest du eine 1 zurückbekommen, weil dort die Slave-Adresse steht.

Posted

Vielen Dank für das schnelle Feedback!

  • Meine DIP-Schalter waren falsch, ich hatte diese auf Half-Duplex Non-Terminated. Das wäre die korrekte Einstellung wenn das Bricklet als Slave betrieben würde? Ich habe sie jetzt auf Half-Duplex Terminated umgestellt.
  • Der Sensor sollte korrekt angehängt sein, siehe Bild unten. Habe die Leitungen trotzdem mal umgehängt jedoch ohne Erfolg.
  • Die Sensoren sind neu die Baudrate und die Adresse sollten also stimmen. Ich habe trotzdem sicherheitshalber die Sensoren auf Werkseinstellungen zurückgesetzt.

Leider kann ich immer noch keine Messwerte auslesen. Fällt Ihnen noch etwas weiteres auf was nicht passen könnte? Ansonsten, da anscheinend beim Bricklet soweit alles korrekt eingestellt ist, setze ich mich sonst mit dem Hersteller des Sensors in Verbindung und Frage da nach ;)

image.thumb.jpeg.7b79bbbf36d7ff719228a1ebb34d98f9.jpeg

 

Posted
Am 11.1.2024 um 15:09 schrieb rtrbt:

Da ist Modbus leider etwas verwirrend: Es gibt Registernummern, die bei 1 beginnen und Registeradressen, die bei 0 beginnen. Also z.B. das Register mit der Adresse 200 hat die Registernummer 201. Viele Hersteller bringen das auch in den Anleitungen durcheinander.

Außerdem gibt es die Präfixe, die im Endeffekt den Typ des Registers angeben (Weshalb die oft weggelassen werden):

  • 0 für Coils (les- und schreibbare 1-Bit-Werte)
  • 1 für Discrete Inputs (nur lesbare 1-Bit-Werte)
  • 3 für Input Registers (nur lesbare 16-Bit-Werte)
  • 4 für Holding Registers (les- und schreibbare 16-Bit-Werte)

Iin deinem Fall kann es also sein, dass du nicht bei 300200 anfangen musst zu lesen, sondern bei 300199 oder 300201.

Um zu testen, ob die Kommunikation prinzipiell funktioniert, kannst du auch mit "Read Holding Registers" das Register 401100 (oder 401099 oder 401101) lesen. Da solltest du eine 1 zurückbekommen, weil dort die Slave-Adresse steht.

Auch dir vielen dank für das Feedback und die Erklärungen!

Habe gerade getestet ob das Register 401100 ausgelesen werden kann und in meinem Fall bekomme ich auf Register 401101 die Antwort 0001. Die Kommunikation scheint also soweit zu funktionieren.

Beim auslesen des Input Registers bin ich allerdings immer noch nicht erfolgreich und bekomme bei Register 300199, 300200 und 300201 immer den Fehler "Received illegal data address"

image.png.d727be71836b5e271edaa12edffdd123.png

Posted
On 1/11/2024 at 3:40 PM, fridolin11 said:
  • Meine DIP-Schalter waren falsch, ich hatte diese auf Half-Duplex Non-Terminated. Das wäre die korrekte Einstellung wenn das Bricklet als Slave betrieben würde? Ich habe sie jetzt auf Half-Duplex Terminated umgestellt.

Bei RS485 handelt es sich üblicherweise um einen Bus, der an beiden Enden terminiert werden muss. Befindet sich das Bricklet an einem Ende, muss die Terminierung aktiv sein, befindet es sich in der Mitte, muss sie deaktiviert sein. Master oder Slave spielt dabei keine Rolle.

On 1/11/2024 at 3:47 PM, fridolin11 said:

Habe gerade getestet ob das Register 401100 ausgelesen werden kann und in meinem Fall bekomme ich auf Register 401101 die Antwort 0001. Die Kommunikation scheint also soweit zu funktionieren.

Das hört sich schon mal sehr gut an. Was ist mit Holding Register 1100 und 1102? Direkt hinter dem Register 1100 steht im Register 1101 auch eine 1 (für die Baudrate). Es ist also immer noch nicht ganz klar, welches Register du ausgelesen hast. Lies doch auch mal 401102 aus, wo eine 100 oder 101 drinstehen sollte.

On 1/11/2024 at 3:47 PM, fridolin11 said:

Beim auslesen des Input Registers bin ich allerdings immer noch nicht erfolgreich und bekomme bei Register 300199, 300200 und 300201 immer den Fehler "Received illegal data address"

Manche Geräte mögen es nicht, wenn Einzelwerte ausgelesen werden, die nicht dafür vorgesehen sind. Versuch doch mal zwei Register ab Adresse 300201, 300202 oder 300203 auszulesen. Laut Anleitung ist das der Distanzwert, der einzeln gelesen werden kann. Da der Wert zwei Register belegt, müssen die aber gleichzeitig gelesen werden.

Ansonsten versuch einfach nochmal 13 Werte ab 300119, 300200 und 300201 auszulesen.

Posted

Jetzt scheint es zu funktionieren.

Wenn ich das Register 300201 auslese mit "Number of Inputs" 13 bekomme ich eine Antwort. Falls "Number of Inputs" 1 ist gibts ein Fehler. Ist also genau wie du gesagt hast und der Sensor mag es nicht wenn nur ein Einzelwert ausgelesen wird.

Vielen dank für eure Hilfe!

  • 3 weeks later...
Posted (edited)

Hallo zusammen

Das Auslesen der Lasersensoren mit Modbus funktioniert nun tadelos Dank eurer Hilfe! Bei einer anderen Modbus Anwendung bin ich auf neue Herausforderungen gestossen und hatte gehofft hier erneut Hilfe zu finden.

Ich würde gerne mehrere Servodrives (Anleitung ist angehängt) mit dem RS-485 Bricklet ansteuern und bin mir wieder nicht ganz sicher ob ich das Bricklet korrekt konfiguriert habe. In der Anleitung findet man folgende Parameter für die Modbus Kommunikation:

image.png.98ec9a4f8ddcb09d0fdecb103064e79b.png

image.png.12f99c35e3c98d111b68c4e106e12ec7.png

Die Servodrives sind neu und es sollten die Werkeinstellung aktiv sein. Dementsprechend habe ich das RS-485 Bricklet wie folgt konfiguriert:image.png.3ddda7ec3542a3b37dc29087ead023ac.png

Fragen zur Modbus Konfiguration:

  • Da nur zwei Signal Kabel bei den Netzwerkkabel angeschlossen sind, gehe ich davon aus, dass der Servodrive über Half-Duplex kommuniziert?
  • Der Parameter "Word Lenght" wird nicht spezifisch im Datenblatt des Servodrives erwähnt. Ist da "8" ein gängiger Wert oder wie findet man da raus was für ein Wert verwendet werden soll?

Weiter wenn ich nun ein Register auslesen möchte, würde ich gerne folgendes Beispiel aus dem Datenblatt reproduzieren:

image.png.a5db9bced01fe8e7126da40c0842ed5c.png

Fragen zum Auslesen der Input Register:

  • In diesem Fall sollte "First Input Number" 302833 bzw. 302832 oder 302834 betragen?
  • Wie find ich raus was für einen Wert bei "Number of Inputs" eingetragen werden soll?
  • Muss ich mich um CRC check Werte kümmern? Oder ist das etwas was das Bricklet automatisch macht?

Im Moment bekomme ich kein Feedback von dem Drive und ich gehe davon aus, dass das Problem bei Konfiguration liegt. Bei der Hardware gehe ich davon aus, dass ich diesmal alles richtig gemacht habe:

  • Dip Switches auf on-on-on-off
  • ein Netzwerkkabel verbindet mein RS-485 Bricklet mit dem Servodrive (vertauschen der beiden Litzen habe ich getestet, löst das Problem leider nicht)
  • ein Netzwerkkabel führt aus dem Servodrive wieder raus und die beiden Signallitzen sind mit einem 120 Ohm Widerstand verbunden.

Ich bin Dankbar für jegliches Feedback!

Freundliche Grüsse

Fridolin

A5 servo driver user manual 2023.pdf

image.png

Edited by fridolin11
Posted
  • Da nur zwei Signal Kabel bei den Netzwerkkabel angeschlossen sind, gehe ich davon aus, dass der Servodrive über Half-Duplex kommuniziert?

Korrekt.

  • Der Parameter "Word Lenght" wird nicht spezifisch im Datenblatt des Servodrives erwähnt. Ist da "8" ein gängiger Wert oder wie findet man da raus was für ein Wert verwendet werden soll?

8 ist der Standardwert und is gibt kaum eine Anwendung, die etwas anderes verwendet. Falls doch, ist das eigentlich immer angegeben.

  • In diesem Fall sollte "First Input Number" 302833 bzw. 302832 oder 302834 betragen?

Wenn ich mir das Datasheet so ansehe, bezweifele ich eher, dass es sich tatsächlich um Input Register handelt. In der Doku ist bei 9.2.1 Code 0x06 angegeben, aber das ist ein Schreibzugriff, der korrekt bei 9.2.2 angegeben ist. Ich vermute daher, dass es Holding Register sind. Dementsprechend muss First Register Number 402833 bzw. 402832 oder 402834 sein.

  • Wie find ich raus was für einen Wert bei "Number of Inputs" eingetragen werden soll?

Register sind immer zwei Bytes groß. Bei Number of Inputs muss also eine 1 eingetragen werden. Leider ist das bei dem Gerät von Register zu Register unterschiedlich.

  • P05-35 hat einen Wertebereich von 0~65535 und ist somit ein uint16, der in ein Register passt.
  • P05-04 hat einen Wertebereich von 0~6553.5 und ist somit eine uint16 Festkommazahl, die in ein Register passt.
  • P05-05 hat einen Wertebereich von -9999~9999 und ist wahrscheinlich ein int16, der in ein Register passt.
  • P05-07 hat einen Wertebereich von 1~1073741824, was nicht in ein Register passt und wahrscheinlich ein uint32 ist, der zwei Register belegt, nämlich P05-07 und P05-08, was nicht in der Tabelle steht. Da musst du also 2 als Number of Inputs angeben.

 

  • Muss ich mich um CRC check Werte kümmern? Oder ist das etwas was das Bricklet automatisch macht?

Musst du nicht, das macht das Bricklet automatisch.

Posted

Vielen Dank für deine ausführliche Antwort! Deine Antworten und Tipps haben mir beim Troubleshooting sehr gut geholfen und mittlerweile steht die Kommunikation zwischen Bricklet und Servodrive.

Wie du vermutet hast handelt es sich um holding register und nicht input register. Ein weiterer Fehler meinerseits waren die Angaben zu Baudrate, Parity und Stop Bits. Da hatte das Servo Drive leider komplett andere Werkeinstellungen als im Datenblatt angegeben waren. Ich hoffe nun, dass wenigstens alle Servo Drives die gleichen Einstellungen haben.

Folgende weitere Frage ist noch aufgekommen:

  • Wie viele Slaves kann ich in meinem Modbus haben? Theoretisch sind ja 247 verschiedene Adressen möglich, allerdings habe ich bei einem sehr ähnlichen Servo Drive wie jenem den ich jetzt verwende gelesen, dass maximal 32 Slaves möglich sind:

image.png.11f338d3a89fa0c765b77e2fff32f443.png

  • In einem Modbus Grundlagen Datenblatt habe ich ebenfalls von diesen maximalen 32 Slaves gelesen. Ist es lediglich möglich mehr als 32 Slaves zu haben wenn man einem repeater verwendet? Oder kann man den Modbus sternenförmig anordnen wie im Bild unten um mehr als 32 Slaves anzusteuern ohne repeater?
  • image.thumb.png.0efde4fda3759b578b5806ad5d6e4dfb.png
  • Ist die maximale Anzahl Slaves abhängig von der Kabellänge oder Kabelqualität?
  • Für meine Anwendung habe ich folgende Kabel ausgesucht: CAT6 S/FTP, die sind so wie ich verstanden habe ungefähr im Mittelfeld was Qualität und Abschirmung angeht. Passen die, oder sind die Overkill? Die Frage kommt evt. stark auf meine Anwendung und das Umfeld an ;)

Freundliche Grüsse

Fridolin

 

Posted
  • Modbus darf nie ein Stern sein sondern nur ein Bus. Es heißt ja auch Modbus und nicht Modstern. 😜 Der Master muss aber nicht an einem Ende sitzen sondern darf auch in der Mitte sitzen. Beide Enden müssen Terminiert werden, aber nie in der Mitte.
  • Die 32 Geräte kommen daher, dass jedes Gerät einen gewissen Unit Load verursacht. Schau dir mal dieses Dokument dazu an. Ein Driver muss 32 Unit Loads und 2x Terminierung unterstützen. Ein Receiver ist standardmäßig 1 Unit Load. Moderne RS485-Transceiver haben aber einen Unit Load von 0.5 oder 0.25, sodass du 64 oder sogar 128 Geräte an einen Bus hängen kannst. Wahrscheinlich ist der Unit Load aber nicht im Datasheet deiner Servos angegeben. Probier es einfach aus.
  • In gewissem Rahmen ist die Anzahl der Slaves abhängig von Kabellänge oder Kabelqualität. Ist das Kabel zu lang oder der Querschnitt zu gering, ist der Widerstand zu hoch und es kommt am Ende kein ausreichend starkes Signal mehr an. Ich glaube, dazu gibt es auch Tabellen mit Richtwerten, aber dazu habe ich gerade nichts. Such mal nach RS485 statt Modbus, dann solltest du da mehr finden.
  • CAT6 ist overkill. Für Modbus brauchst du keine Schirmung. Der Widerstand pro Meter ist da wahrscheinlich interessanter. CAT5 geschirmt oder ungeschirmt ist genauso gut. Ich würde das mit dem größeren Aderquerschnitt bzw. der kleineren AWG-Angabe nehmen.
  • 4 weeks later...
Posted

Ich habe nun alle meine Servo drives angeschlossen und mir sind dabei folgende Dinge aufgefallen:

  • Nach ca. 42 Drives wurde die Modbus Verbindung unzuverlässig und ich vermute dass dies der maximalen Slave Anzahl für mein Setup entspricht.
  • Ich verwende nun drei separate RS485 Bricklets mit 2x 35 und 1x 28 Slaves und das funktioniert tiptop. Ich habe mich hier gegen einen Modbus Repeater entschieden, da ich gerade genügend RS485 Bricklets zur Verfügung hatte ;)
  • Alle drei Modbus Systeme sind nur am einen Ende mit dem Master mit 120 Ohm Terminiert. Sobald ich das andere Ende ebenfalls terminiert habe, wurde die Übertragung unzuverlässig bei vielen Slaves.

Die Maschine wurde wie folgt programmiert:

  • Während die Maschine läuft frage ich beginnend bei Slave 1 dessen Drehgeschwindigkeit ab ("modbus_master_read_holding_registers"), und gebe ihm dann entsprechend ein Moment vor, mit dem der Servo bremsen soll ("modbus_master_write_single_register"). Danach wiederhole ich diesen Vorgang für den nächsten Slave usw. bis zu Slave Nummer 98, und beginne den Prozess dann wieder von vorne.
  • Für eine gesamte Schleife benötige ich ca. 8 Sekunden und am meisten Zeit verliere ich dadurch, dass ich zwischen dem "read" und dem "write" Befehl einen Delay von 60 ms einbauen musste, da ich sonst ein Timeout bekomme.

Ist das eine Übliche Übertragungsrate für Modbus? Die Baudrate beträgt 19200 bps. Für meine Anwendung passt das so aber ich hatte erwartet dass es ein bisschen schneller laufen würde. Es kann allerdings auch gut daran liegen, dass meine Software zu langsam ist. Das Programm läuft auf Node-Red und die Bricklets werden über MQTT angesteuert.

Posted

Eigentlich muss ein Bus an beiden Enden terminiert werden. Ist dein Bus ausreichend kurz, geht das auch mit nur einer Terminierung. Wenn die Übertragung mit beiden Terminierungen unzuverlässig wird, ist das eigentlich ein Zeichen, dass der Bus überlastet ist. Wenn’s aber so funktioniert, ignorier es einfach.

Wenn ich die Modbus-Spezifikation gerade richtig im Kopf habe, muss ein Gerät innerhalb von 50 ms auf eine Leseanfrage antworten. Wenn du ein Delay von 60 ms brauchst, ist das daher nicht ungewöhnlich. Die Baudrate ist dabei unerheblich, da das angesprochene Gerät halt eine gewisse Zeit braucht, um die Anfrage zu verarbeiten und eine Antwort zu generieren. Da du aber drei unabhängige Busse hast, parallelisiere das Ganze doch einfach. Du sprichst immer drei Geräte gleichzeitig an, eins pro Bus. Dann brauchst du nur noch ca. 3 Sekunden pro Schleife. Noch besser wird es dann, wenn du die Geräte in 2 x 33 und 1 x 32 auf die Busse aufteilst.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...