Übersicht Modbus TCP Slave


Mit diesem Funktionsbaustein wird die Steuerung zum Modbus TCP Slave (Server). Ein Fremdsystem als Modbus Master, z.B. ein Gebäudeleitsystem, eine SPS, ein Energiemanager oder ein Wechselrichter, kann damit Werte der Steuerung lesen und Werte in die Steuerung schreiben.

Jeder Ein- und Ausgang des Bausteins entspricht einer Variable und belegt je nach Einstellung 1, 2 oder 4 Modbus-Register:
  • Eingänge sind die Werte, die der Master liest. Der Master erhält den aktuellen Wert der verknüpften Variable.
  • Ausgänge sind die Werte, die der Master schreibt. Der geschriebene Wert wird auf die verknüpfte Variable gesendet und steht damit im Programm, in der Visualisierung und auf dem Bus zur Verfügung.
An den Ein- und Ausgängen müssen Variablen verknüpft werden. Interne Verbindungen zu anderen Bausteinen sind nicht möglich, weil der Wert über die Variable geführt wird. Ein Baustein ohne Variable am Eingang liefert dem Master 0.

Unterstützte Funktionscodes:
  • FC 3: Read Holding Registers – liest Eingänge
  • FC 4: Read Input Registers – liest Eingänge (gleiche Werte wie FC 3)
  • FC 6: Write Single Register – schreibt einen Ausgang
  • FC 16: Write Multiple Registers – schreibt einen oder mehrere Ausgänge
Die Modbus-ID (Unit-ID) muss nicht eingestellt werden, die Steuerung beantwortet jede ID. Die Adressierung erfolgt über die IP-Adresse der Steuerung und den TCP-Port.

Ein Baustein kann bis zu 64 Ein- und Ausgänge haben. Werden mehr Werte oder unterschiedliche Datentypen benötigt, legt man mehrere Bausteine mit verschiedenen Startadressen an. Alle Bausteine mit demselben Port bilden gemeinsam einen Slave, Bausteine mit unterschiedlichen Ports sind voneinander getrennte Slaves. Ein deaktivierter Baustein wird nicht beantwortet.

Nach einer Änderung der Parameter oder der verknüpften Variablen startet der Slave nach etwa 5 Sekunden neu. Bestehende Verbindungen werden dabei getrennt, der Master muss sich neu verbinden.

Eingänge

Adresse Read Ein Eingang je Variable. Beschriftet ist der Anschluss mit seiner Registeradresse (z.B. 100), der Tooltip lautet „Read 100“. Der Master liest den Wert mit FC 3 oder FC 4, jederzeit und ohne Zutun des Programms.
Nicht verknüpft: der Master liest 0.

Ausgänge

Adresse Write Ein Ausgang je Variable, beschriftet mit seiner Registeradresse (Tooltip „Write 100“). Schreibt der Master mit FC 6 oder FC 16, wird der Wert sofort auf die verknüpfte Variable gesendet. Ob der Wert als vorzeichenbehaftet gilt, richtet sich nach dem Datentyp der verknüpften Variable.
Nicht verknüpft: Der Master erhält eine gültige Antwort, der Wert wird aber nirgends weitergegeben.

Parameter

Anzahl IO Anzahl der Ein- und Ausgänge, 1 bis 64. Es gibt immer gleich viele Eingänge wie Ausgänge. Eingang und Ausgang mit derselben Nummer haben dieselbe Registeradresse: Lesen liefert den Eingang, Schreiben setzt den Ausgang.
TCP Port TCP-Port, auf dem der Slave Verbindungen annimmt, 1 bis 65535. Vorgabe ist 502, der Standardport für Modbus TCP. Bausteine mit demselben Port teilen sich einen Slave. Der Port darf nicht von einem anderen Dienst der Steuerung belegt sein, z.B. 10001 (Studio/APP), 80/443 (Weboberfläche) oder dem Port der Netzwerk API. Läuft die Runtime unter Linux ohne Root-Rechte, sind nur Ports ab 1024 möglich.
Register Datentyp Integer (Ganzzahl) oder Float (Gleitkommazahl). Gilt für alle Ein- und Ausgänge des Bausteins. Die verknüpften Variablen werden umgewandelt und müssen daher nicht denselben Datentyp haben. Bei Integer werden Nachkommastellen abgeschnitten (21,7 wird 21). Float ist nur mit 2 oder 4 Registern pro Variable möglich, bei 1 Register wird immer als Integer übertragen.
Register pro Variable Anzahl der Register je Ein- und Ausgang:
  • 1: 16 Bit, Integer
  • 2: 32 Bit, Integer oder Float (IEEE 754 einfache Genauigkeit)
  • 4: 64 Bit, Integer oder Float (IEEE 754 doppelte Genauigkeit)
Erste Register Adresse Registeradresse von Ein- und Ausgang 1, 0 bis 65535. Die weiteren folgen im Abstand von „Register pro Variable“.

Siehe auch allgemeine Parameter aller Funktionsbausteine.

Adressierung und Datenformat

Die Registeradresse eines Ein- oder Ausgangs ergibt sich aus:

Adresse = Erste Register Adresse + (Nummer − 1) × Register pro Variable

Die Adressen werden ab 0 gezählt, so wie sie im Telegramm stehen. Manche Master zählen ab 1 oder verwenden die Schreibweise 4xxxx für Holding Register. Dort ist Adresse 100 als 101 bzw. 40101 einzutragen.

Regeln für eine Anfrage:
  • Die Anfrage muss an der Startadresse einer Variable beginnen. Eine Anfrage mitten in eine Variable liefert die Register ab dem Anfang dieser Variable, die Werte sind dann verschoben.
  • Die Registeranzahl sollte ein Vielfaches von „Register pro Variable“ sein. Beim Lesen werden genau die angeforderten Register geliefert, eine angeschnittene letzte Variable nur mit ihren vorderen Registern. Beim Schreiben werden nur vollständige Variablen übernommen.
  • Eine Anfrage darf nicht über den letzten Ein- oder Ausgang des Bausteins hinausgehen und nicht mehrere Bausteine umfassen, auch wenn deren Adressen lückenlos aneinander anschließen.
Byte-Reihenfolge ist Big Endian, das höchstwertige Register steht zuerst (ohne Word-Swap, oft als „ABCD“ bezeichnet). Das entspricht der Modbus-Norm. Bei manchen Mastern ist das als „High Word first“ einzustellen.

Register pro Variable Integer Float
1 16 Bit: −32768 … 32767, als vorzeichenlos gelesen 0 … 65535 nicht möglich, es wird als 16-Bit-Integer übertragen
2 32 Bit: −2147483648 … 2147483647 32 Bit, etwa 7 gültige Stellen
4 64 Bit 64 Bit, etwa 15 gültige Stellen

Beispiele

Beispiel 1 – Zustände und Zähler, 1 Register: Erste Register Adresse 100, Register pro Variable 1, Datentyp Integer. Ein- und Ausgang 1 haben Adresse 100, 2 hat 101, 3 hat 102 usw. Ein Schaltzustand wird als 0/1 gelesen, ein Sollwert 21 °C als 21.

Beispiel 2 – Temperaturen mit Nachkommastellen, 2 Register: Erste Register Adresse 100, Register pro Variable 2, Datentyp Float. Ein- und Ausgang 1 haben Adresse 100 (Register 100 und 101), 2 hat 102, 3 hat 104 usw. Der Wert 22,5 steht als 0x41B4 0x0000 in den beiden Registern. Im Master wird „Float 32 Bit, Big Endian“ gewählt und ab Adresse 100 jeweils 2 Register gelesen.

Beispiel 3 – Zählerstände, 4 Register: Erste Register Adresse 0, Register pro Variable 4, Datentyp Float. Ein- und Ausgang 1 haben Adresse 0, 2 hat 4, 3 hat 8 usw. Geeignet für große Energiezählerstände, die mit 32 Bit nicht genau genug wären.

Beispiel 4 – Telegramm: Der Master liest Eingang 1 aus Beispiel 2 (FC 3, 2 Register ab Adresse 100, Transaktion 1, Unit-ID 1). Alle Werte hexadezimal:

Anfrage:  00 01 00 00 00 06 01 03 00 64 00 02
Antwort:  00 01 00 00 00 07 01 03 04 41 B4 00 00

Die Antwort enthält nach Funktionscode 03 die Byteanzahl 04 und danach die beiden Register mit dem Wert 22,5. Wird eine Adresse außerhalb des Bausteins angefragt, lautet die Antwort
00 01 00 00 00 03 01 83 02 (Exception 02).

Beispiel 5 – verschiedene Datentypen: Ein Energiemanager soll Schaltzustände und Leistungswerte lesen. Baustein A: Integer, 1 Register, erste Adresse 0, 20 IO → Adressen 0 bis 19. Baustein B: Float, 2 Register, erste Adresse 1000, 10 IO → Adressen 1000, 1002 … 1018. Der Master fragt die beiden Bereiche getrennt ab.

Grenzen

  • Lesen: höchstens 125 Register je Anfrage, Schreiben mit FC 16: höchstens 123 Register je Anfrage (Modbus-Norm). Größere Anfragen werden mit Exception 03 beantwortet.
  • FC 6 schreibt genau ein Register und ist deshalb nur bei 1 Register pro Variable sinnvoll. Bei 2 oder 4 Registern übernimmt der Ausgang den 16-Bit-Wert als ganze Zahl. Dafür FC 16 verwenden.
  • Höchstens 64 Ein- und Ausgänge je Baustein.
  • Höchstens 32 gleichzeitige Verbindungen je Port.
  • Coils und Discrete Inputs (FC 1, 2, 5, 15) werden nicht unterstützt. Schaltzustände werden als Register mit 0/1 übertragen.
  • Jeder Schreibzugriff auf einen Ausgang mit KNX-Variable erzeugt ein Telegramm auf dem Bus. Der Master sollte Werte daher nur bei Änderung schreiben, nicht zyklisch.

Fehlersuche

Die Telegramme des Slaves lassen sich im Studio mit der Schaltfläche Modbus SL in der Statusleiste mitschauen: Richtung (I/O), Zeitstempel und Inhalt in Hex. Abgelehnte Anfragen protokolliert die Steuerung zusätzlich mit der angefragten Adresse, z.B. READ REGISTER: UNKNOWN REGISTER, ADDRESS: 99.

Beobachtung Ursache und Abhilfe
Master bekommt keine Verbindung
  • Port im Master stimmt nicht mit dem Parameter TCP Port überein.
  • Port ist durch ein anderes Programm oder einen anderen Dienst der Steuerung belegt. Die Steuerung meldet dann ERROR BIND PORT und versucht es alle 5 Sekunden erneut. Anderen Port wählen.
  • Falsche IP-Adresse, Firewall oder getrenntes Netz.
  • Baustein deaktiviert, auf einer deaktivierten Seite oder Projekt nicht in die Steuerung übertragen.
  • Mehr als 32 Verbindungen: die Steuerung meldet MAXIMUM CONNECTIONS. Der Master baut oft für jede Abfrage eine neue Verbindung auf, ohne die alte zu schließen.
Verbindung bricht kurz ab Nach jeder Änderung von Parametern oder Variablen startet der Slave neu. Der Master sollte sich selbständig neu verbinden.
Exception 01 (Illegal Function) Der Funktionscode wird nicht unterstützt, z.B. Coils (FC 1/5). Im Master Holding Register (FC 3/16) oder Input Register (FC 4) wählen.
Exception 02 (Illegal Data Address)
  • Die Adresse liegt außerhalb aller Bausteine auf diesem Port. Häufigste Ursache ist ein Versatz um 1: Der Master zählt ab 1 oder in der Schreibweise 40001.
  • Die Anfrage geht über den letzten Ein-/Ausgang hinaus oder umfasst zwei Bausteine. Anzahl IO erhöhen oder die Anfrage aufteilen.
  • Beim Schreiben ist die Registeranzahl kleiner als „Register pro Variable“.
Exception 03 (Illegal Data Value) Zu viele Register in einer Anfrage (lesen über 125, schreiben über 123) oder ein unvollständiges Schreibtelegramm. Die Abfrage im Master aufteilen.
Werte sind unsinnig, z.B. sehr große Zahlen
  • Datentyp oder Registeranzahl im Master stimmen nicht mit dem Baustein überein (Float statt Integer, 16 statt 32 Bit).
  • Word-Swap im Master eingeschaltet. Der Slave sendet das höchstwertige Register zuerst.
  • Die Anfrage beginnt nicht an der Startadresse einer Variable (bei 2 Registern z.B. 101 statt 100).
Wert ist immer 0 Am Eingang ist keine Variable verknüpft, oder die Variable hat noch keinen Wert erhalten.
Nachkommastellen fehlen Datentyp Integer schneidet ab. Float mit 2 Registern verwenden oder den Wert im Programm skalieren (z.B. × 10).
Geschriebener Wert kommt nicht an
  • Am Ausgang ist keine Variable verknüpft.
  • Bei 2 oder 4 Registern wurde FC 6 verwendet. FC 16 verwenden.
  • Es wurde auf die Adresse eines Eingangs geschrieben, der zugehörige Ausgang hat aber keine Variable. Eingänge können nicht beschrieben werden.