CODESYS - the IEC 61131-3 automation software

Welcome to the official CODESYS Forum
Deutsche Version English version russian version 
It is currently Thu Nov 23, 2017 10:27 am

All times are UTC+01:00




Post new topic  Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Thu Sep 21, 2017 4:23 pm 
Offline

Joined: Wed Sep 13, 2017 4:17 pm
Posts: 2
Hello. I'm having an issue with UDPPeer. The instrument I'm trying to communicate with sends one response packet per request (until I request streaming data, which I haven't gotten that far yet). Using the code below, I can send and receive the first packet, but only the first one. It won't send a 2nd packet. Using Wireshark, I can see that the 2nd packet never leaves the PLC. I noticed that UDPSend.XDone always stays high after the first send. I tried changing up the code to disable and re-enable the UDPPeer connection for every send/receive, but that didn't help.

Please excuse my primitive coding skills.

Thanks,
Jim

Code:
FUNCTION_BLOCK FB_Instrument
VAR_INPUT
   sInstrumentIP: STRING := '192.168.12.80'; // IP address of Instrument
   arrbyInstrumentSendData : ARRAY [0..17] OF BYTE := [16#AB, 16#CD, 16#0, 15(16#0)];
   xInstrumentSendNow : BOOL;
   xInstrumentInit: BOOL;
END_VAR
VAR_OUTPUT
   arrbyInstrumentReceiveData : ARRAY [0..87] OF BYTE := [88(16#0)];
   xInstrumentSndRcvComplete : BOOL := FALSE;
   xInstrumentSndRcvError : BOOL := FALSE;
   eInstrumentSndRcvErrorCode: STRING;
   iInstrumentPacketsReceived: CAA.COUNT;
END_VAR
VAR
   iState: INT:= 0;
   IPAddress : NBS.IP_ADDR; (* IP Address *)
   uiPort : UINT; (* Port No. *)
   ctRecAnswers : CAA.COUNT; (* No. of received messages *)
   UDPPeer : NBS.UDP_Peer; (* FB UDP Peer *)
   XUDPPeer : NBS.UDP_Peer; (* FB UDP Peer *)
   UDPSend : NBS.UDP_Send; (* FB UDP Send *)
   UDPReceive : NBS.UDP_Receive; (* FB UDP Receive *)
   Peer : CAA.HANDLE; (* Handle to the peer connection *)
   xEnable : BOOL;
   sUDPData :STRING;
   uiRcvSize: UINT;
   iErrorCode : INT := 0;
   TON_WatchdogReceive: TON;
END_VARIF xInstrumentInit THEN
   iState := 0;
END_IF;

CASE iState OF

0: // Initialize the connection
   
   IPAddress.sAddr := sInstrumentIP; // IP address of Instrument
   uiPort := 50000;
   xInstrumentInit := FALSE;
   TON_WatchdogReceive.PT := T#500MS;
   TON_WatchdogReceive.IN := FALSE;
   xInstrumentSndRcvComplete:= FALSE;
   xInstrumentSndRcvError:= FALSE;
   xEnable := TRUE; // Used for send case and for UDPPeer function call
   iState := 10;
   
10: // Wait for Send

   IF xEnable AND UDPPeer.xActive THEN
      IF xInstrumentSendNow THEN
         // Clear variables for new send
         xInstrumentSndRcvComplete:= FALSE;
         xInstrumentSndRcvError:= FALSE;
   
         UDPsend (
            xExecute   := TRUE,
            ipAddr   := IPAddress,
            uiPort   := uiPort,
            hPeer   := UdpPeer.hPeer,
            szSize   := 18,
            pData   := ADR(arrbyInstrumentSendData),
            udiTimeOut   := 1000000, (* usec *)
            );
         xInstrumentSendNow   := FALSE;
         iState:= 15;
      ELSE
         iState:= 10; // nothing to send, come back here
      END_IF;
   END_IF;
      
15: // Wait for send to complete or error
   IF UdpSend.xDone THEN
      UdpSend.xExecute := FALSE;      
      CASE arrbyInstrumentSendData[3] OF // Determine receive size based on Opcode request sent
         0..15: // Opcodes 16#0-16#F - Configuration data
            uiRcvSize := 18;
         16: // Opcode 16#10 - Stream Measurement Data
            uiRcvSize := 88;
         32: // Opcode 16#20 - Information
            uiRcvSize := 88;
      END_CASE
      // Start listening
      IF UDPPeer.xActive THEN
         UDPReceive(
            xEnable:= TRUE,
            hPeer:= Peer,
            szSize:= uiRcvSize,
            pData:= ADR(arrbyInstrumentReceiveData)
            );
      END_IF;
      iState:= 20; // Wait for data
      TON_WatchdogReceive.IN := TRUE; // Start watchdog
   END_IF;
   IF UdpSend.xError THEN
      UdpSend.xExecute := FALSE;
      iState:= 30; // Error state
   END_IF;
      
20: // Wait for data
   IF UDPReceive.xReady THEN
      UDPReceive.xEnable := FALSE;
      ctRecAnswers := ctRecAnswers + 1; // Number of UDP calls
      iState:= 10; // Data received, go back to wait to send
      xInstrumentSndRcvComplete := TRUE;
      TON_WatchdogReceive.IN := FALSE;
      iInstrumentPacketsReceived := ctRecAnswers;
   ELSIF UDPReceive.xError THEN
      UDPReceive.xEnable := FALSE;
      TON_WatchdogReceive.IN := FALSE;
      iErrorCode := UDPReceive.eError;
      iState:= 30; // Error state
   ELSIF TON_WatchdogReceive.Q THEN
      UDPReceive.xEnable := FALSE;
      xInstrumentSndRcvComplete := TRUE;
      TON_WatchdogReceive.IN := FALSE;
      iState:= 10; // Go back to wait for now. Improve handling later.
   END_IF;

30: // Error
   xInstrumentSndRcvError := TRUE;
   xInstrumentSndRcvComplete := FALSE;
   
40: // Exit

END_CASE

// Call the CAA FUNCTION
UDPPeer(xEnable:= xEnable, ipAddr:= IPAddress, uiPort:= uiPort, hPeer=> Peer);


Top
   
PostPosted: Thu Sep 21, 2017 6:24 pm 
Offline

Joined: Tue Dec 03, 2013 11:52 pm
Posts: 42
To me it looks like you never call the function block UDPsend when you have execute set to false so it never registers the falling trigger. After you set UdpSend.xExecute := FALSE; you then need to call UDPsend(); before you go back into case statement 10 where it gets set back to TRUE.

For example:
Code:
15: // Wait for send to complete or error
   IF UdpSend.xDone THEN
      UdpSend.xExecute := FALSE;
      UDPsend();  (*********************** This is added *****************************)     
      CASE arrbyInstrumentSendData[3] OF // Determine receive size based on Opcode request sent
         0..15: // Opcodes 16#0-16#F - Configuration data
            uiRcvSize := 18;
         16: // Opcode 16#10 - Stream Measurement Data
            uiRcvSize := 88;
         32: // Opcode 16#20 - Information
            uiRcvSize := 88;
      END_CASE
      // Start listening
      IF UDPPeer.xActive THEN
         UDPReceive(
            xEnable:= TRUE,
            hPeer:= Peer,
            szSize:= uiRcvSize,
            pData:= ADR(arrbyInstrumentReceiveData)
            );
      END_IF;
      iState:= 20; // Wait for data
      TON_WatchdogReceive.IN := TRUE; // Start watchdog
   END_IF;
   IF UdpSend.xError THEN
      UdpSend.xExecute := FALSE;
      UDPsend();  (*********************** This is added *****************************)
      iState:= 30; // Error state
   END_IF;


Top
   
PostPosted: Thu Sep 21, 2017 6:35 pm 
Offline

Joined: Wed Sep 13, 2017 4:17 pm
Posts: 2
That fixed it. Thank you.

I knew it was something block-headed like that.


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

All times are UTC+01:00


Who is online

Users browsing this forum: No registered users and 3 guests


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