# TCP Modbusslave an Wago Master anbinden?



## stfan1409 (24 August 2013)

Hallo,
ich habe eine Wago 750-885 CPU. Nun möchte ich einen Slave mit der "WagoLibModbus_IP_01.lib" über TCP einbinden.
Leider habe ich bisher nur Beispiele für UDP und nicht für TCP gefunden. Da der Slave nur Modbus TCP unterstützt, habe ich einfach mal angefangen.
Zum testen möchte ich 1 Byte senden und 1 Byte empfangen. Das Programm hat keine Fehler aber auch keine Funktion...

xConnect=TRUE
xIS_Connected=TRUE
wError gibt mal "sucessfull" und mal "illegal function Code" zurück

Wo kann ich bei dem Wagomaster vorgeben, ob erst die Eingänge vom Slave empfangen oder erst die Ausgänge an den Slave gesendet werden?


Tobi
Anhang anzeigen 0_leer885_Lib01.zip


----------



## stfan1409 (3 September 2013)

Halloooooo,
ich habe es endlich geschafft - der Bus läuft ;-)
Ich kann senden und empfangen.

Eine Frage habe ich aber denn doch noch:
Ich nutze die "WagoLibModbus_IP_01.lib" über TCP. Es gibt den Baustein Pin "bFUNCTION_CODE":
Im Datenblatt vom Slave stehen die unterstützden Modi:

----------------------
Supported operations:
0x01: Read coils
0x02: Read discrete input
0x05: Write single coil
0x0F: Write multiple coils
----------------------

d.h. ich kann nur lesen oder schreiben.
nun habe ich zwei Bausteine genommen(einen zum Eingänge lesen und einen zum Ausgänge schreiben) und setze abwechselnd jeweils den "xCONNECT" Pin am Baustein auf HIGH.
Es funktioniert...aber gibt es da eine schönere Lösung für?

Vielen Dank
Tobias

PS: leider zieht es sich mit dem Slave etwas hin... 
ich mache z.Z. meinen Techniker in Abendschule und da bleibt kaum Zeit zum "basteln"...
Aber es wird


----------



## stfan1409 (8 September 2013)

Projekt läuft   

Also wenn jemand eine Pokeys 56E oder 57E Platine als Slave über Modbus TCP an eine Wago 750-880 CPU anbinden möchte, kann er gerne diesen Programmvorschlag nutzen.
Das Programm ist bei weitem noch nicht perfekt, aber es läuft und man kann zuverlässig digitale und analoge Eingänge abfragen, sowie digitale Ausgänge setzen. Es wird die "WagoLibModbus_IP_01.lib" benötigt(kostenloser Download bei Wago).
Interessiert hat mich die Platine, weil sie 55 IO´s hat und nur 60€ kostet...

Viel Spaß,
Tobi
Anhang anzeigen PoKeys_56E_Modbus_v18_slave02.zip


----------



## @lex (17 September 2013)

Zu deiner Frage wie du es anders machen kannst:
Nimm einen Baustein mit Variablen als Übergabeparamter (und keine fixen Werte). Wenn der Client durch ist (xSEND fällt ab), überschreibe  die Variablen bedingt und setze xSEND wieder auf true - usw...


----------



## stfan1409 (18 September 2013)

Hallo, danke für die Antwort.
Ich kann leider erst wieder am Wochenende auf sie SPS zugreifen.
 Im Prinziep meinst du das wohl so oder?


IF Slave01_xSend =0 THEN;

	IF Slave01_xSend_Zaehler < 3 THEN;
	Slave01_xSend_Zaehler:= Slave01_xSend_Zaehler + 1;
	ELSE;
	Slave01_xSend_Zaehler:= 0;
	END_IF;

	IF Slave01_xSend_Zaehler =0 THEN;
	Slave01_24DO_Buffer:=Slave01_Buffer; (*Daten von Abfrage zuvor ernehmen*)
	PLC_SLAVE_01.Function_Code:=15;
	PLC_SLAVE_01.wRead_adr:=0;
	PLC_SLAVE_01.wRead_q:=0;
	PLC_SLAVE_01.wWrite_Adr:=0;
	PLC_SLAVE_01.wWrite_q:=24;
	END_IF;

	IF Slave01_xSend_Zaehler =1 THEN;
	Slave01_24DI_Buffer:=Slave01_Buffer;
	PLC_SLAVE_01.Function_Code:=2;
	PLC_SLAVE_01.wRead_adr:=24;
	PLC_SLAVE_01.wRead_q:=31;
	PLC_SLAVE_01.wWrite_Adr:=0;
	PLC_SLAVE_01.wWrite_q:=0;
	END_IF;

	IF Slave01_xSend_Zaehler =2 THEN;
	Slave01_7AI_Buffer:=Slave01_Buffer;
	PLC_SLAVE_01.Function_Code:=4;
	PLC_SLAVE_01.wRead_adr:=10;
	PLC_SLAVE_01.wRead_q:=7;
	PLC_SLAVE_01.wWrite_Adr:=0;
	PLC_SLAVE_01.wWrite_q:=0;
	END_IF;


Slave01_xSend:=1;
END_IF;


----------



## @lex (23 September 2013)

Ja, zum Beispiel. Oder über CASE. Oder via Strukturen...


----------



## stfan1409 (25 September 2013)

Hallo,
ich habe in zwei Schritten getestet.

Im ersten Schritt habe ich eine Scrollbar genommen um die einzelnen Funktionen abzufragen also -> Wert 0=digitale Ausgänge setzen, 1=digitale Eingänge abfragen,  2=analoge Eingänge abfragen. Das funktioniert wunderbar, wie zuvor.

Im zweiten Schritt habe ich die Scrollbar gelöscht und durch einen Zähler (0,1,2,0,1,2,...) ersetzt. Leider funktioniert nur der Analogwert. Digitale Eingänge werden manchmal mit einem anderen Wert gemischt. Und die digitalen Ausgänge funktionieren garnicht.

Ich denke der Fehler liegt da, wo z.b. das empfangene word in die neue Variable übertragen wird also in_Word -> digitale_Eingänge oder in_Word -> analoge_Eingänge 

Kann da mal einer drüber sehen?
Anhang anzeigen Slave_12.zip

Tobi


----------



## exchange (26 September 2013)

Hallo Tobi,
ich hatte mir dein Programm auch mal runtergeladen und wollte es mit einer Wago 750-880 ausprobieren. Leider hat das nicht funktioniert also musste ich mich ans selbst basteln geben.
Anfangs habe ich deine Timer-Lösung gehabt und konnte alle Digitalen Ausgänge schalten ABER er hat nichts eingelesen. Ich denke, dass ich dabei zu schnell durch die Modbus Bausteine gehuscht bin und der die Rückmeldung nicht abgearbeitet hat. also habe ich das jetzt so gemacht, dass er wartet bis xSend wieder von True auf False zurückgefallen ist. Damit funktioniert es einwandfrei. Die digitalen Eingänge habe ich als Byte eingelsen und schreibe diese auch als Byte. Analog als Word.

Digital:
Output: ARRAY [0..2] OF BYTE;
Output[0].0 := M_Pokey_Output1;

Analog:
Analog:ARRAY [0..6] OF WORD;
Test1: REAL;
Test1 := ROUND(Analog[0] * (3.3 / 4096), 2);

Anscheinend kann der Pokeys nur eine Modbus Verbindung. Das ist ein wenig schade, da ich gerne die Aufgaben schneller abwarbeiten würde. Habe die Modbus-Geschichte in einen eigenen Task gepackt. Ein Durchlauf dauert ca. 2 Sekunden bei einem Task von 100ms.

Muss mir noch was bauen um die Ausgänge mal abwechselnd zu beschreiben und die Zeiten am Oszi zu messen.

Ich hoffe, dass es Dir weiterhilft.

Gruß
Heiko


----------



## stfan1409 (27 September 2013)

Hallo Heiko,
in meinem 2ten Beispiel wartet das Programm auch bis xSend auf False schaltet. Aber mein Fehler scheint noch woanders zu sein.
Könntest du dein Programm mal hochladen, damit ich mir das im Zusammenhang mal ansehen kann? Vielleicht hast du ja eine andere Reihenfolge oder so...

Die Daten wollte ich dann auf der SD Card speichern und später bestimmte Werte als "Trend" anzeigen - aber das kommt später.
Gruß Tobi


----------



## exchange (28 September 2013)

Hallo,
nach Rücksprache mit dem Hersteller habe ich jetzt den Task alle 5ms laufen und das Teil kann leider nur eine Modbus Verbindung. Angeblich kann man bis auf 1ms runter, aber so schnell benötige ich es nicht.
Der Code ist in ST, komme mit dem Kästchengedöns nicht klar 

Gruß
Heiko


----------



## stfan1409 (29 September 2013)

Hallo Heiko,
danke für den Code. Benutzt du 4 Bausteine - also für jede funktion eine?
(IF NOT MODBUS_Digital_Input1.xCONNECT AND NOT MODBUS_Digital_Input2.xCONNECT AND NOT MODBUS_Analog_Input.xCONNECT AND NOT MODBUS_Digital_Output.xCONNECT THEN)

Das hatte ich ja versucht zu umgehen, damit ich nicht immer die Verbindung trennen und neu verbinden muss.
---
Ich habe alles aus meinem Programm rausgenommen, was ich nicht für den Bus zum testen benötige....trozdem manchmal dieser Fehler das Zustände falsch ankommen...
Was hast du für die Taskeigenschaften eingestellt? Also z.b. wie oft wird das Programm (der Task) ausgeführt? Ich habe jetzt 10ms. Wenn ich freilaufend einstelle geht´s.
Ich frage mich nur wieviele Slaves ich dann abfragen kann?

Ich denke ich bleibe bei der Lösung für jede Funktion(d.h. digitale Eingänge lesen, analoge eingänge lesen, digitale Ausgänge schreiben) einen Baustein. Im schlimmsten Fall gehen Signale verlohren. Schlimmer wäre es, wenn Signale falsch zugeordnet werden!


----------



## stfan1409 (29 September 2013)

Hallo Heiko,
nun läuft es...aber mit mehreren Bausteinen pro Slave. In den Taskeigenschaften habe ich 10ms eingestellt.

ganz grob: 
-wenn alle xSend auf 0 sind, wird eine Variable hochgezählt
-abhängig vom Zähler wird der entsprechende Baustein(xConnect) und die xSendVariable auf 1 gesetzt

Anhang anzeigen Wago.rar


gruß, Tobi


----------



## exchange (29 September 2013)

Hallo Tobi,
vermutlich hat die Wago die alten Variablen in den Bausteinen gehalten. Ich habe aktuell 5ms und bin sehr zufrieden mit der Performance.
Diese lange If Zeile verhindert genau das manuelle eingreifen (beim Initialisieren). Ich habe den PoKeys auch manchmal aus und der Wago macht das nichts (dank Multitasking).

Sobald ich das Teil einschalte dauert es keine 2 Sekunden und die gründe Lampe spielt.

Task steht bei mir auf zyklisch.

Ich finde beides eine Katastrophe. Es dürfen weder Signale abhanden kommen, noch welche dazukommen. Ich wollte damit eine Torsteuerung realisieren aber mit dem PoBlocks komme ich nicht so ganz zurecht (Bausteine sind nicht meine Welt). Daher lass ich das Programm in der Wago laufen. Da sind dann auch alle Verriegelungen mit im Programm und da kann ich launische Signale nicht gebrauchen 
Daher auch die schnelle Tasklaufzeit, da ich die Inputs einlesen muss und das sind Taster.

Sobald meine Platine von der Entwicklung da ist, kann ich alles einbauen...

Gruß
Heiko


----------

