# Modbus RTU in Twincat, wie anfangen?



## damiche (19 Juli 2011)

Hallo,

ich habe eine Beckhoff CX9010 mit EL6022 und einen Vacon Frequenzumrichter mit Modbus RTU Schnittstelle sowie die Schnittstellenbeschreibung.

Ebenfalls habe ich die Beckhof Modbus RTU Library.

Ich möchte dem FU einen Startbefehl senden, ebenso einen Sollwert und dann das Drehmoment und die Drehzahl zurückbeommen.

Lt. Doku des Umrichters liegt in Adresse 2107 (Modbus-Register 32107 und 42107) das Motordrehmoment in %.
In Adresse 2001 (Modbus-Register 32001, 42001) muss ich das Feldbus-Steuerwort binärcodiert schreiben, damit der FU läuft.

Der FU hat Slave-Adresse 1.

Wie fange ich an? Könnt Ihr mir auf die Sprünge helfen?
Ich habe ein Programm in FBS, aus dem ich das Programm für die Modbus-Kommunikation aufrufen würde. Dieses würde ich in ST schreiben, nur bin ich mir nicht im Klaren, wie ich anfange.

Wie muss ich im System-Manager die Variablen zuordnen?

Danke im Voraus!

Gruß
Michi


----------



## SPSDAU (21 Juli 2011)

Hier gibt es ein Beispiel dafür (allerdings K-Bus)


----------



## Tobias5 (6 Februar 2018)

*gleiche Frage*

Hi, ich sehe dass der Post schon recht alt ist. Habe aber das gleiche Problem, ich muss über EL6022 mit einem Slave über Modbus kommunizieren und weiß nicht ganz wo ich anfangen soll. Ich habe gesehen, dass es für KL6x22B vorgefertigte Funktionsbausteine gibt. Gibt es sowas auch für die ELs?


----------



## weißnix_ (6 Februar 2018)

Es sind dieselben. Nicht von der Bezeichnung verwirren lassen: Dem Baustein ist es egal ob EL oder KL Klemmen dran hängen.
Entscheidend ist es, die Bibliothek richtig einzubinden und dann geht es (fast) wie von alleine


----------



## Tobias5 (13 Februar 2018)

@weißnix_, vielen Dank, dass sind gute Nachrichten.
Nach einer kurzen Pause solls jetzt wieder weiter gehen. Ich wollt die Klemme (EL6022) Konfigurieren bzw. die Baudrate usw. jetzt hatte ich den  Funktionsbaustein "KL6configuration(...)" endeckt, allerdings heißt es in der Beckhoffhilfe:*
_"*Hinweis*: Der Funktionsbaustein verwendet die bei KL-Klemmen übliche Registerkommunikation zur Konfiguration. Bei EtherCAT Klemmen EL ist diese Registerkommunikation nicht möglich. EL-Klemmen können mit Funktionsbausteinen aus der EtherCAT-Bibliothek konfiguriert werden (FB_EcCoeSdoWrite)."
_Bei "FB_EcCoeSdoWrite" finde ich aber nicht die typischeb Parameter für serielle Kommunikation.
Kann mir noch jemand einen Tipp geben?


----------



## oliver.tonn (13 Februar 2018)

Das ist auch klar das Du das da nicht findest. Der Baustein KL6configuration ist speziell für serielle Karten gedacht und hat dann natürlich auch Eingänge wie Baudrate, Datenbits, usw.
Der Baustein FB_EcCoeSdoWrite ist aber ganz allgemein zum Schreiben von SDO-Objekten in EtherCAT Klemmen da. Hier musst Du Dir aus dem Objektverzeichnis die gewünschten Objekte heraussuchen und diese dann jeweils einzeln schreiben. Für die Baudrate des ersten Kanals müsstest Du 0x8000 als Index und 0x11 als Subindex angeben. Außerdem musst Du noch die AMS.NetID des EtherCAT Masters und die Slave-Adresse der EL6022 Karte angeben.


----------



## weißnix_ (13 Februar 2018)

Also Leutz, macht mal langsam.
Die Kommunikation mit einem Slave ist m.E. nicht so hochdynamisch, das man die serielle Schnittstelle laufend umparametrieren muß. Ich würde die Parameter der SS einmalig im Systemmanager (CoE-Parameter) festlegen. Eventuell ist es sinnvoll, gegenüber der Werkseinstellung geänderte Parameter als Startup festzulegen. Aber das sollte es doch schon gewesen sein.
Im laufenden Programm ändert sich nicht die Baudrate und auch nicht die Parität. Ergo: Spar Dir den Streßß, aus dem Programm auf die Konfig zuzugreifen (in diesem Fall).

Du willst Kommunizieren und dafür ist nur der Baustein ModbusRtuMaster in der (5 Byte oder 22Byte Version, je nach Klemmenkonfig) erforderlich.


----------



## Tobias5 (16 März 2018)

Vielen Dank für die Tipps.
Die Antwort weißnix_ habe ich irgendwie überlesen, und ja da hatte ich mich wohl tatsächlich verrannt.

  Nach längerer Pause hab ich mich jetzt wieder an das Thema gemacht, stecke aber schon wieder fest und dachte vielleicht kann mir jemand von euch auch hier wieder weiterhelfen.

  Ich habe die Konfiguration im CoE-online Reiter verglichen und die default Einstellungen passen ganz gut. 9600 Baud und Datenframe 8N1 passen, nur Halfduplex muss ich enablen.
  Im SPS-Projekt hab ich unter References die Tc2_ModbusRTU (und Tc2_Standard, Tc2_System, Tc3_Module).
  Dann habe ich ein Programm erstellt in dem ich den Funktionsblock „ModbusRtuMaster_KL6x22B“ aufrufe. Hier ist mir nicht klar was man überhaupt mit dem FB macht, erstmal garnichts oder? Weil wenn ich dann die Aktionen zB. ReadInputsRegs aufrufe. Wird sowieso wieder ein kompletter FB geöffnet „ModbusRtuMaster_KL6x22B.ReadInputRegs“ der die gleichen Eingangs und Ausgangsparameter hat.
  Naja, ich habe Ihm dann mal entsprechente Variablen zugewiesen. (UnitID := 1; Qauntity := 1, MBAdrr 4999; cbLength mit Sizeof(ModbusDaten) (Modbusdaten habe ich im gleichen Programm definiert.) pMemoryAddr mit ADR (ModbusDaten). Timeout einfach mal mit T#1s. Und Execute als NO den ich dann zum Test als True force.
  Beim builden (es tut mir leid ich habe ein englisches Visio und bin mit den TwinCat Begriffen noch nicht so vertraut). Werden mir dann Instanzen von „ModbusRtuMaster_KL6x22B_0“ (der ModbusMaster FB wo ich nicht weis wofür er gedacht ist) und ModbusRtuMaster_KL6x22B_1“ der FB „ModbusRtuMaster_KL6x22B.ReadInputRegs“) erstellt. Diese habe ich dann über change link mit den I0 von meiner EL6022B erstellt.
  Mein Problem ist, das jetzt nicht wirklich was passiert.
  Das erste was mit Merkwürdig erschien, ist dass ich als ich das Programm neu erstellt habe kein Assingment and Busy machen konnte, beim ersten Versuch ging das noch.
  Dann bekomme ich die Warnung „No initial value for const variable #stLibVersion_Tc2_Modbus_RTU“ (vielleicht liegt dort auch mein Fehler (nach Hinweis von)
  Über andere Software oder auch über ein Terminal Programm (Hterm) kann ich den Slave problemlos ansprechen und bekomme die erwartete Antworten. Daher vermute ich den Fehler in meiem SPS Programm. Außerdem habe ich verstgestellt, dass weder mit den den Werten in der Instanz noch mit den Eingängen irgendetwas passiert, sie bleiben in der Online Ansicht immer Null.
  (Als Hinweis, dass ist mein erstes TwinCat Projekt, also es kann auch gut sein, dass ich irgendwo einen groben Anfängerfehler begangen habe.)
  Wen mir jemand nochmal einen Tipp geben kann, würde ich mich super freuen.


----------



## Tobias5 (21 März 2018)

Bin jetzt von FUP auf ST umgestiegen und damit haben sich einige Probleme von oben selbst gelöst.
Gerne kann ich das Programm mal hochladen.
Wenn man noch daran dennkt am 9-Pol Stecker Tx und Rx zu Brücken, dann läuft es (hatte ich erst vergessen).


----------



## chreischei (26 Juni 2018)

Hallo Tobias5,
ich habe mit ähnlichen Anfangsschwierigkeiten wie Du zu kämpfen. Könntest Du Dein Programm, wie angeboten, zum Download zur Verfügung stellen?
Danke und Grüße
Chreischei


----------



## weißnix_ (26 Juni 2018)

OffTopic:
SChaut sich überhaupt noch jemand die Beispiele an?
Ich hatte auch gelegentlich so ein Problem. Da hab ich einfach erstmal die Beckhoff-Hilfe durchforstet und den Beispielcode ausprobiert.
Der war einfach an mein Problem anpassbar - Problem gelöst.


----------



## Tobias5 (26 Juni 2018)

Ich habe dir eine PN geschickt


----------



## Christian Tepper (27 November 2018)

Hallo und zwar habe ich ein sehr ähnliches Problem und weiß nicht so recht wie ich anfangen soll Code für die Modbus Kommunikation zu schreiben.
Habe leider bei Beckhoff auch keinen Beispiel Code gefunden mit dem ich hätte rumspielen können.

@weißnix_ du meintest es gäbe welchen könntest du mir den verlinken ?

MfG

Christian


----------



## weißnix_ (28 November 2018)

https://download.beckhoff.com/downl...AT2/Infosystem/1031/chm/TcPlcLibModbusRTU.chm

4 Beispielprojekte sind in der chm eingebettet.


----------



## Christian Tepper (6 Dezember 2018)

"Bei einer PC-Steuerung oder einer CX1000-Steuerung wird die verwendetet serielle Schnittstelle im TwinCAT System Manager mit dem Modbus-RTU Funktionsbaustein verknüpft."

Versteh ich das richtig, dass die ModbusRtuMaster_PcCom automatisch mit den RS232 Input und Output verbunden wird ? Ansonsten frage ich mich wie das geschehen soll. Bzw. wie man das am besten macht.
Und woher weiß das Programm welche Serielle Schnittstelle es nehme nsoll ?


----------



## oliver.tonn (6 Dezember 2018)

Christian Tepper schrieb:


> "Bei einer PC-Steuerung oder einer CX1000-Steuerung wird die verwendetet serielle Schnittstelle im TwinCAT System Manager mit dem Modbus-RTU Funktionsbaustein verknüpft."
> 
> Versteh ich das richtig, dass die ModbusRtuMaster_PcCom automatisch mit den RS232 Input und Output verbunden wird ? Ansonsten frage ich mich wie das geschehen soll. Bzw. wie man das am besten macht.
> Und woher weiß das Programm welche Serielle Schnittstelle es nehme nsoll ?


In dem Du die I/Os der gewünschten seriellen Schnittstelle im System Manager mit den passenden Variablen der gewünsten Instanz des FBs ModbusRtuMaster_PcCom verknüpfst.


----------



## weißnix_ (6 Dezember 2018)

Hast Du Dir denn schonmal die Hilfe durchgelesen?
Es ist zwar schon eine Weile her aber ich habe damals die Kommunikation zu meinem Stromzähler mit der Hilfe und dem Beispielprojekt hinbekommen.

Die Verknüpfung der Hardware mit der Software ist eigentlich in allen aktuellen .pdf-Hilfedateien ausführlich und fast idiotensicher beschrieben. Das war in den alten Hilfen noch nicht so.


----------



## Christian Tepper (6 Dezember 2018)

Ok ich glaube ich hab es. Hab den Satz irgendwie falsch gelesen und die Variable vom FB ist bei mir in den Inputs irgendwie nicht aufgetaucht.
Erstmal danke


----------



## Adelic (14 Februar 2019)

Hallo Tobias5,

ich habe ebenfalls mit Anfangsschwierigkeiten zu kämpfen. Kannst Du bitte Dein Programm zur Verfügung stellen?

Betsen Dank im Voraus!

Adelic


----------



## wollvieh (14 Februar 2019)

https://www.beckhoff.de/default.asp?twincat/tf6340.htm
Einfach mal durchlesen...


----------



## __thomas (11 Mai 2019)

Hallo Tobias5,

kannst Du mir bitte auch dein ST-Programm zur Modbus RTU schicken?
Ich wühle mich schon Tage durch und bekomme es nicht hin.

Vielen Dank und Gruß
Thomas


----------



## Christian Tepper (13 Juni 2019)

Ich habe weiterhin ein Problem mit dem ModBus.
Und zwar wenn ich die Funktion ReadRegs mit folgenden Parametern ausführe:

ModbusMaster.ReadInputRegs(
UnitID:=1   <- Adress of the Slave
Quantity:=2  <- How many coils i want to read
MBAddr:=30001 <- Modbus Adress (Also wo zB der Messwert liegt)

cbLength:=SIZEOF(???)  <- i read something like it hast to be 2 times of Quantity and i  would think its the length of the value i read out of the regs ?
pMemoryAddr:=ADR(???) <- this is probably the address of the value read ?
Execute:= TRUE <- to start reading ?
cbRead=>ocbRead <- Probably what was read ?

Bei den Fragezeichen müsste theoretisch stehen wo das gelesene abgelegt wird oder ?

Habe auch ein paar Tests durchgeführt und frage mich, wenn cih diese Funktion ausführe müsste in den Ausgängen der seriellen Schnittstelle nicht ein paar bytes liegen ?

MfG

Christian


----------



## wollvieh (15 Juni 2019)

Schon mal die Dokumentation  von Beckhoff gelesen...



Die 30001 wäre zu überdenken.


----------



## Christian Tepper (15 Juni 2019)

Also greife ich mit Inputs[0] auf die Adresse 30001 im Gerät zu ?
Und MBaddr:= Inputs[0] oder wie ?
Habe die Doku des öfteren gelesen werde da aber nicht ganz schlau draus


----------



## wollvieh (15 Juni 2019)

So wie ich das lese ist bei dem Baustein die Adresse 0 die Modbus Adresse 30001. In der Dokumentation der RS485 Modbusklemme ist auch ein Link auf ein Beispielprogramm enthalten.
Such mal im Google nach CAS Modbus Scanner , ist ein Windows Programm, eignet sich hervorragend zum Testen von Modbus Slaves. Gruß, Wollvieh.


----------



## Christian Tepper (17 Juni 2019)

Ich wollte mir das Beispiel mal anschauen von diesem Link: https://infosys.beckhoff.com/englis...usrtubc/html/tcplclibmodbusrtu_common.htm&id=
Die Datei ist jedoch ein *.pr6 und ich weiß nicht wie ich diese mit TwinCat3 öffnen soll.

Ich habe mir zu dem auch mal das Video: https://www.youtube.com/watch?v=-wIu1eaS0vs&t=440s angeschaut. Ohne ein Wort zu verstehen sehe ich aber das die auch keinen Array wie Inputs benutzen. Sondern unter MBAddr nur die 0 und bei cbLength und pMemoryAddr die Variable in der der Wert gespeichert werden soll.

Bin ein bisschen verwirrt von dem ganzen wenn ich ehrlich bin. Mir fehlt irgendwie aktuell das Verständnis was ich genau womit verknüpfen soll. Ich habe die Eingänge der seriellen Schnittstelle mit Modbus.InData verbunden. Ist das richtig ??

Mit dem Scanner werde ich mich die Tage mal ausprobieren vielleicht finde ich da die Lösung.

Danke für die Hilfe


----------



## wollvieh (17 Juni 2019)

Entpacken und mit Notepad öffnen.


----------



## Christian Tepper (25 Juni 2019)

Also mittlerweile habe ich dieVerlinkung mit den Ausgängen der seriellen Schnittstelle und dem ModbusMaster hinbekommen. Man muss die ModbusMaster.InData mit den Eingängen verbinden. Außerdem ist die Adresse 30001 in ReadInputRegs 0. Außerdem muss man darauf achten wie viel Bit das empfange hat und die in einer Variable speichern, die auch ausreichend groß ist.

Das Bild was du weiter oben geschickt hast mit den Inputs[0] z.B. ist für einen ModbusSlave. Falls jemand die gleichen Probleme hat.

Aktuell muss ich nur noch die empfangenen Bytes in ein Real umwandeln nach dem 32 bit floating point format. Da hänge ich aktuell noch.


----------



## oliver.tonn (25 Juni 2019)

Soweit die Bytes ein Real darstellen und die Ausrichtung (Stichwort: Little-Endian, Big-Endian) passt brauchst Du die Bytes nur per MEMCPY in eine REAL Variable zu kopieren oder Du erstellst eine UNION mit einem ARRAY von 4 Bytes und einer REAL-Variable.


----------



## Christian Tepper (25 Juni 2019)

Also die Reihenfolge ist falsch. Das habe ich gestern schon festgestellt. Daraufhin habe ich die Bytes in einen Array in der richtigen Reihenfolge gepackt. Und diese dann versucht mit folgendem Code:
FUNCTION B_IEEE32_TO_REAL : REAL

VAR_INPUT
 IN : ARRAY[0..3] OF BYTE;
END_VAR
VAR
      PTREALOINTER TO REAL;
END_VAR



PTREAL:=ADR(IN);
B_IEEE32_TO_REAL := PTREAL^;


in eine Real Variable zulegen. Aber der Wert der mir angezeigt wird ist nicht der richtige. In Hexadezimal bekomme ich die Bytes in der Reihenfolge 16#0B2141A8 übergeben. Dann packe ich sie in der Reihenfolge 16#41A80B21, dass einen Wert von ca. 21 ergeben müsste. Die Variable hat aber einen Wert der sehr schwankt und immer mit e^-12 oder e^17 belegt ist. Also sehr weit vom erwarteten Wert entfernt ist. 

Wenn ich die Bytes aber zB hier eintrage https://www.h-schmidt.net/FloatConverter/IEEE754de.html bekomme ich das richtige Ergebnis.


----------



## oliver.tonn (25 Juni 2019)

Dann dreh die Zahlen mal wieder (16#210BA841) und schon bekommst Du einen Wert von um 21 raus.


----------



## Christian Tepper (28 Juni 2019)

Top genau das war das Problem. Bekomme nun die richtigen Messwerte.

Kann man ein gelesenes REAL in seine Bytes auf Teilen um die in die richtige Reihenfolge zu bekommen ?

Hat sich erledigt. Danke für die Hilfe soweit klappt alles.


----------



## Hüpf3R (21 April 2020)

Ich habe ein ähnliches Problem wie die vorherigen Nutzer. Ich versuche Momentan eine Verbindung über einen PcCom aufzubauen. Dazu habe ich eine serielle Schnittstelle hinzugefügt. Die Ein- und Ausgänge der Schnittstelle habe ich mit der Modbus.InData bzw Modbus.OutData Instanz verknüpft. Folgendermaßen wird die Funktion ReadRegs vom Master ausgeführt:
MB.ReadRegs(
UnitID:=1,
Quantity:=SIZEOF(Data)/2 ,
MBAddr:=0,
cbLength:=SIZEOF(Data),
pMemoryAddr:=ADR(Data),
... );
(allen nicht aufgeführten Variablen habe ich eine lokale Variable zugewiesen)

Den Salve habe ich so eingestellt:
VAR_INPUT
   MS : ModbusRtuSlave_PcCOM; 
   Inputs AT %IW0 : ARRAY[0..63] OF WORD;
   Outputs AT %QW0 : ARRAY[0..63] OF WORD;
   Memory AT %MW0 : ARRAY[0..63] OF WORD;
END_VAR

MS(
UnitID   :=1, 
AdrInputs   := ADR(Inputs),
SizeInputBytes   := SIZEOF(Inputs),
AdrOutputs   := ADR(Outputs),
SizeOutputBytes   := SIZEOF(Outputs),
AdrMemory   := ADR(Memory),
SizeMemoryBytes   := SIZEOF(Memory),
ErrorId   => );


Mein Problem ist nun dass ich beim Versuch eine Verbindung aufzubauen immer folgende ErrorId beim Master erhalte: MODBUSERROR_NO_RESPONSE
Kann mir da jemand weiterhelfen? Ich konnte im infosys von Beckhoff und auch auf sonstigen Internetseiten nichts genaues finden.


----------



## Guga (29 April 2020)

@Hüpf3R : ein neuer Threat wäre prinzipiell schön gewesen.

So ganz verstehe ich nicht was du machst.
Du hast einen Baustein für den Master erstellt vom Typ ModbusRtuMaster_PcCom und die Eingänge/Ausgänge auf die Com-Schnittstelle verlinkt.
Was willst du dann mit dem Slave und das auch noch als Baustein wo die als VAR_INPUT ... END_VAR mit Speicheradressen versiehst? Speicheradressen gibt es physikalisch nur 1x im Gerät.

Aaaalso, bitte einmal strukturiert von Anfang an beschreiben was du machst, sonst wird das nichts.

Guga


----------



## Hüpf3R (30 April 2020)

Das Ganze hat sich gestern erledigt. Gestern wurde die Entscheidung getroffen nicht mit Beckhoff bzw. TwinCAT weiter zumachen. Trotzdem Danke für die Antwort


----------



## oliver.tonn (30 April 2020)

Nur aus Neugier, was hat gegen Beckhoff TwinCAT gesprochen? 

Von irgendwas mit Internetzugang gesendet.


----------



## Hüpf3R (30 April 2020)

Der eher mäßige Beckhoffsupport und die Tatsache, dass es einfach nicht ging 2 PCs über den COM-Port mit Modbus RTU zu verbinden, bzw. einfahc nicht die Zeit ist noch länger daran rumzuprobieren.
Das hat 2 gründe. Zum einen der eher mäßige Beckhoffsupport. Zum anderen die Tatsache dass es einfach nicht ging 2 PCs über den COM-Port mit Modbus RTU zu verbinden, bzw. einfach nicht die Zeit ist noch länger daran rum zuprobieren und die Doku leider auch nicht weiterhilft.


----------



## oliver.tonn (30 April 2020)

Ich hatte das eine oder andere mal auch schon meine Probleme mit dem Beckhoff Support, bin aber ansonsten sehr zufrieden mit deren Leistung.
Ich bin mir nicht sicher ob es bei Modbus RTU überhaupt möglich ist, dass Master und Slave über die selbe Schnittstelle laufen. Sowohl der Master als auch der Slave müssten ja über die Schnittstelle gleichzeitig senden und empfangen können. Habt Ihr das mit einer anderen Steuerung denn schon am Laufen?

Von irgendwas mit Internetzugang gesendet.


----------



## Hüpf3R (30 April 2020)

Naja Modbus RTU funktioniert ja so, dass der Master ein Telegramm sendet worauf der Slave antwortet. D.h. es ist immer nur einer der sendet. Das Problem bei uns war, dass TwinCAT zwar die COM-Schnittstelle blockier hat, aber keine Daten darüber gesendet hat, obwohl der Master ein Telegramm gesendet hat.
Mit der anderen Steuerung wird es erst die nächsten Tage getestet.


----------



## BRO76 (17 Mai 2022)

Tobias5 schrieb:


> Bin jetzt von FUP auf ST umgestiegen und damit haben sich einige Probleme von oben selbst gelöst.
> Gerne kann ich das Programm mal hochladen.
> Wenn man noch daran dennkt am 9-Pol Stecker Tx und Rx zu Brücken, dann läuft es (hatte ich erst vergessen).


Hallo Tobias,

ich weiß, der Eintrag ist schon ein wenig älter, ich habe jedoch ganz ähnliche Probleme.
Könntest Du Dein Programm bitte nochmal hochladen?

Vielen Dank im voraus

MfG

Björn


----------



## Tobias5 (18 Mai 2022)

Hi, tut mir leid ich habe leider weder das programm noch irgendwelche dokumentation mehr finden können.


----------



## BRO76 (18 Mai 2022)

Ich bin woanders fündig geworden :
Codebeispiel im Beitrag von MasterOhh vom 15. Juli 2020 im Thread "TwinCat: Modbus Register Lesen und Schreiben"​
Damit hat es dann geklappt !
Ohne dieses Forum wäre ich noch auf der Suche ...

Vielen Dank !

Björn


----------

