CODESYS - the IEC 61131-3 automation software

Welcome to the official CODESYS Forum by 3S-Smart Software Solutions GmbH | A member of the CODESYS Group
Deutsche Version English version russian version 
It is currently Mon Jan 27, 2020 3:40 am

All times are UTC+01:00




Post new topic  Reply to topic  [ 2 posts ] 
Author Message
PostPosted: Mon Dec 09, 2019 9:17 am 
Offline

Joined: Thu Jul 30, 2015 11:06 pm
Posts: 4
Hello,

I am running a wago PFC200 PLC and try to drive a equipment using ethernet TCP protocol under Codesys V2.3. I am able to create and connect a socket, send data and close the socket. Yet each time I want to receive data, that I know to be send by the equipment the connexion got stuck and I just have to switch on and of the equipment and restart my PLC.

When I check if the equipement is ready to send back data using SysSockSelect, it returns 0, meaning that it is not ready to talk although it does send data. If I don't use the SysSockSelect and go straight to SysSockRecv then the program got stuck.

Does anyone have an idea ?

Thank for your help.

Michel



PROGRAM PLC_PRG
VAR

sendBt:BOOL;
recvBT:BOOL;


strLec:STRING(100);
strEcr:STRING(100):=':FREQ:21.2345MHz';

openSocket:BOOL;
closeSocket:BOOL;


diSocket : DINT := -1;
iPort : INT:=9760;
stDestIPAddress : STRING := '192.168.9.47';

bySend : STRING(12) := ':IDN?';
byRecv : STRING(128);
xx:INT;
yy:DINT;
nbS:INT:=64;
nbR:INT:=128;


END_VAR

IF openSocket THEN
openSocket:=FALSE;
IF(diSocket=-1) THEN
diSocket := TcpClientOpenSocket(iPort, stDestIPAddress, 1000);
END_IF
END_IF



IF recvBt THEN
IF diSocket <> -1 THEN
TcpReceiveData(diSocket, ADR(byRecv), SIZEOF(byRecv), 2);
END_IF
recvBt:=FALSE;
END_IF


IF sendBt THEN
IF diSocket <> -1 THEN
TcpSendData(diSocket, ADR(bySend), SIZEOF(bySend), 2);
END_IF
sendBt:=FALSE;
END_IF



IF closeSocket THEN
closeSocket := FALSE;
SysSockClose(diSocket:=diSocket);
diSocket := -1;
END_IF



(***********************************************)
FUNCTION TcpClientOpenSocket : DINT
(* Open TCP client socket to connect to server.
Return: Socket-Id for connection session
*)
VAR_INPUT
iPort:INT; (* Port number of TCP socket to open *)
stIPAddress:STRING; (* IP-Address of server to connect to *)
diMaxDataSize:DINT; (* Max size of data to transmitt; if size = 0 default values are used *)
END_VAR
VAR
diSocket:DINT;
bOptNoDelay:BOOL;
lOptLinger:SOCKET_LINGER;
bResult:BOOL;
sa:SOCKADDRESS;
END_VAR



diSocket:=SysSockCreate(SOCKET_AF_INET, SOCKET_STREAM, 0);

IF diSocket <> SOCKET_INVALID THEN

SysSockSetOption(diSocket, SOCKET_SOL, SOCKET_SO_SNDBUF, ADR(diMaxDataSize), SIZEOF(diMaxDataSize));
SysSockSetOption(diSocket, SOCKET_SOL, SOCKET_SO_RCVBUF, ADR(diMaxDataSize), SIZEOF(diMaxDataSize));
lOptLinger.l_onoff:=0;
lOptLinger.l_linger:=0;
SysSockSetOption(diSocket, SOCKET_SOL, SOCKET_SO_LINGER, ADR(lOptLinger), SIZEOF(lOptLinger));
bOptNoDelay:=TRUE;
SysSockSetOption(diSocket, SOCKET_IPPROTO_TCP, SOCKET_TCP_NODELAY, ADR(bOptNoDelay), SIZEOF(bOptNoDelay));

sa.sin_family:=SOCKET_AF_INET;
sa.sin_addr:=GetIPAddress(stIPAddress);
IF sa.sin_addr <> SOCKET_INADDR_NONE THEN
sa.sin_port:=SysSockHtons(iPort);
IF SysSockConnect(diSocket, ADR(sa), SIZEOF(sa)) = FALSE THEN
SysSockClose(diSocket);
diSocket:=SOCKET_INVALID;
END_IF
ELSE
SysSockClose(diSocket);
diSocket:=SOCKET_INVALID;
END_IF
END_IF
TcpClientOpenSocket:=diSocket;
(***********************************************)
FUNCTION TcpReceiveData : DINT
(* Receive data from a tcp socket.
Return: Number of bytes received
*)
VAR_INPUT
diSocket:DINT; (* Socket Id *)
pbyData:DWORD; (* Address of data buffer *)
diDataSize:DINT; (* Size of data to send *)
diTImeout : DINT; (* Timeout in seconds *)
END_VAR
VAR
fdRead:SOCKET_FD_SET;
tvTimeout:SOCKET_TIMEVAL;
rr:DINT;

END_VAR

tvTimeout.tv_usec := 0;
fdRead.fd_count := 1;
fdRead.fd_array[0] := diSocket;

IF (SysSockSelect(SOCKET_FD_SETSIZE, ADR(fdRead), 0, 0, ADR(tvTimeout)) > 0) THEN
TcpReceiveData:=SysSockRecv(diSocket, pbyData, diDataSize, 0);
END_IF

(***********************************************)
FUNCTION TcpSendData : DINT
(* Send data via TCP socket.
Return: Number of bytes sent
*)
VAR_INPUT
diSocket:DINT; (* Socket Id *)
pbyData:DWORD; (* Address of data buffer *)
diDataSize:DINT; (* Size of data to send *)
diTImeout : DINT; (* Timeout in seconds *)
END_VAR
VAR
fdWrite:SOCKET_FD_SET;
tvTimeout:SOCKET_TIMEVAL;
END_VAR
tvTimeout.tv_sec := diTimeout ;
tvTimeout.tv_usec := 0;
fdWrite.fd_count := 1;
fdWrite.fd_array[0] := diSocket;
IF (SysSockSelect(SOCKET_FD_SETSIZE, 0, ADR(fdWrite), 0, ADR(tvTimeout)) > 0) THEN
TcpSendData:=SysSockSend(diSocket, pbyData, diDataSize, 0);
END_IF

(***********************************************)


Top
   
PostPosted: Thu Dec 12, 2019 6:44 pm 
Offline

Joined: Thu Jul 30, 2015 11:06 pm
Posts: 4
Hello
Me again
Actually I have found where the problem came from. The code was ok but the format of the command I used was missing a new line character at the end (what was not said in the notice).
I have managed to see that using Wireshark a freeware that allows tcp frame inspection on the net. There I saw that the '0a' character was missing compared to the utility software provided by the manufacturer.
Though nobody answered I have thought It might be usefull to some of you to have a clue on how to debug this kind of problem.
Michel


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 2 posts ] 

All times are UTC+01:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited