# Mit Codesys TCP Verbindung aufbauen



## J4CK (15 September 2010)

Hey Leute,
ich brauch mal wieder eure Hilfe. Ich soll eine Wago SPS mit Codesys so Programmieren, dass sie die von einem Sensor über TCP gesendete Daten empfängt und aufarbeitet. Ich habe es inzwischen hinbekommen, dass ich den vom Sensor gesendeten String bei telnet in der Konsole bekomme.
Die SPS soll jetzt die Daten empfangen, den String aufteilen und die Werte in verschiedene Variablen speichern. 
Ich kriegs nur nicht mal hin, dass die SPS ne Verbindung zum Sensor aufbaut. 
Wenn ihr helfen könntet oder jemand allgmeinen Krams hat, der mir helfen könnte, wäre das super.
Vielen Dank,
Gruß J4CK


----------



## MasterOhh (15 September 2010)

Hast du eine Bibo mit TCP/IP Funktionen? Keine Ahnung wie das bei Codesys aussieht, aber bei Beckhoff muss man diese Bibliothek extra kaufen, da sind dann alle Bausteine drin die man für die TCP Kommunikation braucht.


----------



## J4CK (16 September 2010)

Also ich habe die SysLabSockets.lib, die Ethernet.lib und die WagoSysSockets.lib. Alle drei sehen so aus, als könnten sie nützlich sein. Haben funktionen wie Connect, Create, Close, Send, Listen...
Für die SysLabSockets hab ich sogar ne Doku, allerdings verstehe ich schon nicht, wie ich einen neuen Socket erstelle. Was ist eine Adressfamilie (dint) und was für ein Protocol (dint) muss ich nehmen...


----------



## J4CK (16 September 2010)

So, gute Nachricht. Habs geschafft. Jedenfalls den Verbindungsaufbau.
Falls das mal jemand sucht, hab ich den Code mal am Ende eingefügt.

Ich hab nur noch ein Problem. Ich muss ein Triggerbefehl an den Sensor schicken (0001t) das funktioniert noch nicht. Ich weiß nicht, ob das an diesem diFlag zusammenhängt oder der den String irgendwie umkonvertiert und der Sensor darauf nicht mehr reagiert. Wenn einer von euch weiter weiß...

Vielen Dank,
Gruß J4CK




```
--- bei mir Global ---
VAR_GLOBAL
 addressPointer:POINTER TO SOCKADDRESS;
 address:SOCKADDRESS;
 ip:STRING:='192.168.1.5';
 send:STRING:='0001t';
 receive:STRING;
 port: WORD:=50010;
 objectArray:ARRAY[0..6] OF REAL;
END_VAR
 
--- Programmvariablen ---
VAR
 result: BOOL;
 socketId: DINT;
 terminate: BOOL;
END_VAR
 
--- Das Programm ---
address.sin_addr:=SysSockInetAddr(ip);
address.sin_family:=SOCKET_AF_INET;
address.sin_port:=SysSockHtons(port);
addressPointer:=ADR(address);
IF socketId =0 AND terminate = FALSE THEN (* Verbindung aufbauen *)
  socketId := SysSockCreate(SOCKET_AF_INET,SOCKET_STREAM,0);
  result := SysSockConnect(socketId,addressPointer,SIZEOF(address));
ELSE
 IF terminate = TRUE THEN (* Verbindung abbauen *)
  SysSockClose(socketId);
  socketId := 0;
  result := FALSE;
 END_IF (* Verbunden *)
 (* SysSockSend(socketId,ADR(send),SIZEOF(send),1); *)     <--- das da geht noch nicht
 SysSockRecv(socketId,ADR(receive),SIZEOF(receive),1);
 objectArray := split(receive); 
END_IF
 
--- Splitfunktionsvariablendefinition ---
FUNCTION split :ARRAY[0..6] OF REAL
VAR_INPUT
 input:STRING;
END_VAR
VAR
 inputSize: INT;
 rest: STRING;
 restSize: INT;
 i: INT;
 findR: INT;
 detail: STRING;
 detailSize: INT;
 detailArray:ARRAY[0..6] OF REAL;
END_VAR
 
--- Und die Funktion ---
inputSize := LEN(input);
rest := MID(input,inputSize-9,10);
FOR i := 0 TO 6 DO
 findR := FIND(rest,'#');
 detail := MID(rest,findR-1,1);
 restSize := LEN(rest);
 detailSize := LEN(detail);
 rest := MID(rest,restSize-detailSize,detailSize+2);
 detailArray[i] := STRING_TO_REAL(detail);
 IF i = 0 AND detail = 'PASS' THEN
  detailArray[i] := 1;
 END_IF
 IF i = 0 AND detail = 'FAIL' THEN
  detailArray[i] := 0;
 END_IF
END_FOR
split:=detailArray;
```


----------



## gravieren (16 September 2010)

Hi

Mal eine dumme Frage.


Wie läßt du den Code   "Das Programm"    ablaufen  ?


Ist dieser Code wie abgebildet unter z.b.  plc_prog  geschrieben und wird permanent durchlaufen  ?


Falls ja,   eine SPS ist KEIN "Von Neumann" - Rechner.

Für diese anweisungen solltest du dir eine Art "Sate"-Maschine schreiben.


Gruß Karl


----------



## J4CK (17 September 2010)

Hey Karl,

ich schäme mich ja fast das zu sagen, aber ja. Ich hab das an einer Beispieldatei, die ich im 3S-Forum gefunden habe, orientiert. Könntest du mir kurz den Unterschied zwischen SPS und von-Neumann erklären (is mehr ne Interessenfrage)!?
Wie baue ich eine State-Machine? Gibt ja noch AWL oder wie das heißt, meinste das? Also quasi Strart -> Verbindung herstellen -> result is Übergangsbedingung zu -> Verbindung hergestellt, empfangsbereit...

Gruß J4CK


----------



## gravieren (17 September 2010)

Hi


J4CK schrieb:


> ich schäme mich ja fast das zu sagen, aber ja.
> Ich hab das an einer Beispieldatei, die ich im 3S-Forum gefunden habe, orientiert.


Ich such dir mal was raus.

Derzeit habe ich keine Zeit.


Grundsätzlich:
Das öffnen macht du in jeden SPS-Zyklus.

So sollte es sein.
Öffnen von TCP-Zugriff.
Warten auf das Ergebnis.
Zugriff erfolgreich --> Daten lesen und schreiben.

Öffnen NICHT mehr aufrufen  ! ! !


Wenn alles erledigt ist, Handle schliessen.
Wieder nur einmalig  !
NIcht jeden Zyklus neu  !


Also mit einer State-Maschine.



Ich werde dir mal bei gelegenheit einen Code raussuchen.







J4CK schrieb:


> Könntest du mir kurz den Unterschied zwischen SPS und von-Neumann erklären (is mehr ne Interessenfrage)!?
> 
> Wie baue ich eine State-Machine? Gibt ja noch AWL oder wie das heißt,  meinste das? Also quasi Strart -> Verbindung herstellen -> result  is Übergangsbedingung zu -> Verbindung hergestellt, empfangsbereit...
> 
> Gruß J4CK









J4CK schrieb:


> Könntest du mir kurz den Unterschied zwischen SPS und von-Neumann erklären (is mehr ne Interessenfrage)!?


Siehe hier.
http://de.wikipedia.org/wiki/Von-Neumann-Architektur

Von Prinzip her wartet der Rechner bis er den Befehl erfolgreich abgearbeitet hat.

Möglicherweise benötigt er z.b.   2 Sekunden um ein Ethernetverbindung aufzubauen.
In diesen 2 Sekunden würden die Abfrage des nachfolgenden Befehls NICHT mehr abgearbeitet werden.


Für einen Rechner O.K.

Für eine SPS ein NoGo.   !





J4CK schrieb:


> Wie baue ich eine State-Machine? Gibt ja noch AWL oder wie das heißt,  meinste das? Also quasi Strart -> Verbindung herstellen -> result  is Übergangsbedingung zu -> Verbindung hergestellt, empfangsbereit...



So in etwa.
Zum Grundgedanken.

Zyklus der SPS hat als Beispiel 100 ms


1. Es kommt der TCP-öffnen Befehl.   
   (Diesr kann mehrere Zyklen benötigen)
2. Lesen der ankommenden Informationen 
   (Möglicherweise noch gar nicht  verbunden)
3. Schreiben der Informationen
   (Möglicherweise noch gar nicht verbunden)
4. Zyklus ende nach 100 ms  --> Mache weiter mit   1.



Jetzt weisst du was ich meine  ?

P.S:
Auch beim Dateizugriff hast du das selbe Problem.
Insofern deine Hardware das erlaubt.



Gruß Karl


----------



## J4CK (17 September 2010)

Danke für die ausführliche Antwort.

Ich dachte eig, dass ich das mehrmalige öffnen durch die Abfrage, ob die SocketId = 0 ist, verhindere. Wie könnte ich das denn sonst machen, wenn der Verbindungsaufbau länger als ein Zyklus dauert (SocketId ist ja erst != 0 wenn die Verbindung steht). Sollte ich noch ein Timeouttimer oder so etwas mit einbauen, so dass min. 5 Sek vergehen müssen, bevor die SPS den create-Befehl wieder ausführt!?

Hast du zufällig eine Ahnung, warum der Sensor nicht auf das gesendete reagiert!? Ich hab da gerade sonne Befürchtung, dass das auch mit der Zykluszeit zusammen hängt und der Sensor gar nicht zum auswerten kommt. Mh, muss ich Montag auf Arbeit mal ausprobieren :-/

Danke, Gruß J4CK


----------



## ChristianIN (10 Februar 2021)

Hallo Zusammen, ich bin auf der Suche nach einer Möglichkeit in Codesys  3.5 eine TCP Kommunikation zu einem Drucker aufzubausen und 256 Bytes zu  senden und auch 256 Bytes zu empfangen, da ich aus der Klicki Bunti  Siemens Welt komme und für sowas bisland den TSEND_C Baustein verwenden  konnte tue ich mich leider etwas schwer dies jetzt in Codesys zum laufen  zu bringen.

vielen Dank schonmal, Gruß Christian


----------



## oliver.tonn (10 Februar 2021)

Hallo Christian,
bitte nicht böse sein, aber unterlasst doch bitte das kapern von Threads, dass nimmt in letzter Zeit überhand hier, zumindest habe ich so den Eindruck. Es ist Dir niemand böse, wenn Du einen neuen Thread aufmachst, im Gegenteil.
Zu Deinem Problem schau Dir mal die Codesys Hilfe im Bereich SysSocket an. Mit SysSockCreate musst Du erst einen Socket erstellen und mit SysSockConnect Dich dann mit dem Server/Drucker verbinden. Mit SysSockRecv kannst Du Daten empfangen und mit SysSockSend welche senden.


----------



## Azrael666 (11 Februar 2021)

Schau dir mal die OSCAT Network Bibliothek an. Dort findest du schon einen fertigen Baustein IP_CONTROL

https://store.codesys.com/oscat-network.html


----------



## HausSPSler (13 Februar 2021)

vielleicht mal dieses Beisppiel anschauen:
https://forge.codesys.com/prj/codesys-example/plc-chat/home/Home/


----------

