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

UDP Multicast empfangen - wie geht es wirklich?

skynet
2019-11-29
2020-01-10
  • skynet - 2019-11-29

    Hallo zusammen,

    ich habe im Netz und hier im Forum nach einem Tipp oder einem Codebeispiel für den Empfang von UDP-Multicast-Datagrammen gesucht. Viele Links führen leider mittlerweile ins Leere.

    An einem Beispiel habe ich versucht, einen Empfang zu prüfen, aber ich denke, dass die Initialisierung von

    UDPPeer(xEnable:= xEnable, uiPort:= uiPort, ipAddr := IPAddress ,hPeer=> Peer);
    

    falsch ist. Hier gibt es ja auch den Parameter ipMulticast, aber ich habe alle Varinaten versucht, damit scheitert schon die Initialisierung ich bekomme kein handle (hPeer).

    Hat jemand eine Idee oder Vorschlag für mich?

    Vielen Dank im Voraus!
    Nico

    PROGRAM PLC_PRG
    VAR
      eState: INT:= 0;
     
      IPAddress : NBS.IP_ADDR; (* IP Address *)
      uiPort : UINT; (* Port No. *)
      sReceived : STRING; (* Holds the received message *)
      ctRecAnswers : CL2.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 : CL2.CAA.HANDLE; (* Handle to the peer connection *)
     
      xEnable : BOOL;
     
      udpData :STRING;
    END_VAR
    UDPPeer(xEnable:= xEnable, uiPort:= uiPort, ipAddr := IPAddress ,hPeer=> Peer);
    CASE eState OF
    0: // Init
    IPAddress.sAddr:= '239.12.255.254';                // IP Adress where Codesys application is running
    uiPort:= 9522;
    xEnable:= TRUE;
    eSTATE := 10;
    10: // Start listening
    IF UDPPeer.xActive THEN
      UDPReceive(xEnable:= TRUE, hPeer:= Peer, szSize:= SIZEOF(sReceived), pData:= ADR(sReceived));
      IF UDPReceive.xReady THEN
        udpData := sReceived; // Data from UDP-stream
        ctRecAnswers := ctRecAnswers + 1; // Number of UDP calls
      ELSIF UDPReceive.xError THEN
        eState:= 20;
      END_IF
    ELSE
      eState:= 20;
    END_IF
    20:
    // Error
    END_CASE
    
     
  • Chris.O - 2019-12-02

    Hi,

    mit Multicast habe ich das noch nicht probiert... aber UDP auf eine bestimmte IP habe ich schon mal gemacht:

    VAR_INPUT
       xEnable:BOOL;               //Connect to other system (only at first block)
       xSendData:BOOL;               //Allow to send Data 
       xReadData:BOOL;               //Allow to read Data
       tSendIntervall:TIME:=T#100MS;    // send intervall: standard is 200ms interval
       udiStartAddr:UDINT;            // Start address of Sync-List to Slave
       udiEndAddr:UDINT;            // End address of Sync-List to Slave
       sOtherIPAdr:STRING;            //IP-address of other System
       sOwnIPAdr:STRING;            //IP-address of own System
       uiport: UINT;                //port number for comunication
    END_VAR
    VAR_OUTPUT
       xConnectionDone:BOOL;         // Output = TRUE if Connection is established
       xConnectionBusy:BOOL;         // Output = TRUE if there it try to establish the Connection
       xConnectionError:BOOL;         // Output = TRUE if there is a connection error
       xSendDone:BOOL;               // Output = TRUE if data were send
       xSendBusy:BOOL;               // Output = TRUE if data exchange is in progress
       xSendError:BOOL;            // Output = TRUE if data exchange failed
       eSendError:NBS.ERROR;         // Defined Errors of Struct in NBS.ERROR
       xReceiveBusy:BOOL;            // Receive currently active
       xReceiveError:BOOL;            // Receive error
       eReceiveError:NBS.ERROR;      // Defined Errors of Struct in NBS.ERROR
       xReceiveReady:BOOL;            // When data was read successfully
    END_VAR
    VAR
       myUDP_Peer:NBS.UDP_Peer;       //to connect to other System
       myUDP_Receive:NBS.UDP_Receive;    // to receive data from other System
       myUDP_Send:NBS.UDP_Send;       //to send data to other System
       other_ip_Addr: NBS.IP_ADDR;    // to set IP-Address of other System
       own_ip_Addr: NBS.IP_ADDR;       // to set IP-Address of own System
       myBlink:BLINK;                //to define send-interval
       tTimeIntervall:TIME;         //Time interval to send data
       peerHandle: NBS.CAA.HANDLE;    // to identify other System
       xEnableReceive:BOOL   ;         // Enable to receive Data
    END_VAR
    
    (*--------------------*)
    (*Data synchronisation*)
    (*--------------------*)
    //Get IP from other system
    other_ip_Addr.sAddr:=sOtherIPAdr;
    own_ip_Addr.sAddr:=sOwnIPAdr;
    //Connect via UDP
    myUDP_Peer(xEnable:=xEnable, 
             ipAddr:=own_ip_Addr, 
             uiPort:=uiport, 
             xDone=>xConnectionDone, 
             xBusy=>xConnectionBusy, 
             xError=>xConnectionError);
             
    //save peerHandle
    peerHandle:=myUDP_Peer.hPeer;
    IF xEnable AND xConnectionBusy AND xSendData THEN
       //UDP send
       //Send interval (Input have to be devided because Low-Time +High-Time = intervall 
       tTimeIntervall:=tSendIntervall/2;
       myBLink(Enable:=TRUE, TimeLow:=tTimeIntervall, TimeHigh:=tTimeIntervall);
       myUDP_Send(xExecute:=myBLink.OUT, 
                udiTimeOut:=100000, 
                hPeer:=peerHandle, 
                ipAddr:=other_ip_Addr, 
                uiPort:=uiport, 
                szSize:=(udiEndAddr-udiStartAddr(*+SIZEOF(udiEnd)*)), //+SIZEOF ist auskommentiert, da sonst mehr mitgeschickt wird als gewollt => so wird lediglich das "End-Bool" nicht mitgeschickt.
                pData:= udiStartAddr, 
                xDone=>xSendDone, 
                xBusy=>xSendBusy, 
                xError=>xSendError, 
                eError=>eSendError);
    END_IF   
       
    IF xEnable AND xConnectionBusy AND xReadData THEN   
       //UDP receive
       //Bei fehler neu starten
       IF xReceiveError THEN
          xEnableReceive:=FALSE;
       ELSE
          xEnableReceive:=TRUE;
       END_IF
       
       myUDP_Receive(xEnable:=xEnableReceive, 
                hPeer:=peerHandle, 
                szSize:=(udiEndAddr-udiStartAddr(*+SIZEOF(udiEnd)*)),
                pData:=udiStartAddr, 
                xBusy=> xReceiveBusy, 
                xError => xReceiveError, 
                eError=>eReceiveError, 
                xReady=>xReceiveReady);
    END_IF
    

    Kannst ja mal versuchen, ob du damit weiter kommst.

     
  • skynet - 2019-12-03

    Danke Chris, ich veruche es einmal.

    Viele Grüße!
    Nico

     
  • Chris.O - 2020-01-10

    Und hats geklappt?

     
  • skynet - 2020-01-10

    Hallo,

    ja...es hat geklappt. Wichtig war jedoch: der UDP Port muss im TouchTerminal aktiviert werden

    Vielen Dank!

     

Log in to post a comment.