Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched.
Close
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
FUNCTION_BLOCKFB_InstrumentVAR_INPUT
  sInstrumentIP: STRING :='192.168.12.80'; // IP address of Instrument
  arrbyInstrumentSendData : ARRAY [0..17] OFBYTE := [16#AB, 16#CD, 16#0, 15(16#0)];
  xInstrumentSendNow : BOOL;
  xInstrumentInit: BOOL;END_VARVAR_OUTPUT
  arrbyInstrumentReceiveData : ARRAY [0..87] OFBYTE := [88(16#0)];
  xInstrumentSndRcvComplete : BOOL :=FALSE;
  xInstrumentSndRcvError : BOOL :=FALSE;
  eInstrumentSndRcvErrorCode: STRING;
  iInstrumentPacketsReceived: CAA.COUNT;END_VARVAR
  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_VARIFxInstrumentInitTHEN
  iState :=0;END_IF;CASEiStateOF0: //Initializetheconnection
 Â
  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: //WaitforSend
  IFxEnableANDUDPPeer.xActiveTHEN
    IFxInstrumentSendNowTHEN
      //Clearvariablesfornewsend
      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: //Waitforsendtocompleteorerror
  IFUdpSend.xDoneTHEN
    UdpSend.xExecute :=FALSE;   Â
    CASEarrbyInstrumentSendData[3] OF//DeterminereceivesizebasedonOpcoderequestsent
      0..15: //Opcodes16#0-16#F-Configurationdata
        uiRcvSize :=18;
      16: //Opcode16#10-StreamMeasurementData
        uiRcvSize :=88;
      32: //Opcode16#20-Information
        uiRcvSize :=88;
    END_CASE
    //Startlistening
    IFUDPPeer.xActiveTHEN
      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;
  IFUdpSend.xErrorTHEN
    UdpSend.xExecute :=FALSE;
    iState:=30; // Error state
  END_IF;
   Â
20: //Waitfordata
  IFUDPReceive.xReadyTHEN
    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;
  ELSIFUDPReceive.xErrorTHEN
    UDPReceive.xEnable :=FALSE;
    TON_WatchdogReceive.IN :=FALSE;
    iErrorCode :=UDPReceive.eError;
    iState:=30; // Error state
  ELSIFTON_WatchdogReceive.QTHEN
    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: //ExitEND_CASE//CalltheCAAFUNCTIONUDPPeer(xEnable:=xEnable, ipAddr:=IPAddress, uiPort:=uiPort, hPeer=>Peer);
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:
15: //Waitforsendtocompleteorerror
  IFUdpSend.xDoneTHEN
   UdpSend.xExecute :=FALSE;
   UDPsend(); (*********************** This is added *****************************)  Â
   CASEarrbyInstrumentSendData[3] OF//DeterminereceivesizebasedonOpcoderequestsent
     0..15: //Opcodes16#0-16#F-Configurationdata
      uiRcvSize :=18;
     16: //Opcode16#10-StreamMeasurementData
      uiRcvSize :=88;
     32: //Opcode16#20-Information
      uiRcvSize :=88;
   END_CASE
   //Startlistening
   IFUDPPeer.xActiveTHEN
     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;
  IFUdpSend.xErrorTHEN
   UdpSend.xExecute :=FALSE;
   UDPsend(); (*********************** This is added *****************************)
   iState:=30; // Error state
  END_IF;
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
Related
Talk.ru: 3
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:
That fixed it. Thank you.
I knew it was something block-headed like that.