Quick Start (PLC / UDP)
The sample implements an “echo service”: A UDP server is started on a port (default: 10000). If this server receives a UDP packet, it returns the content to the sender (with same IP and same port).
The sample is also available for download under Sample 02. In addition to the Quick Start, the download contains extended code, which does not affect the basic functionality.
Implementation of the UDP echo server in a PLC project
- A TwinCAT solution was generated
- 1. If no PLC project exists in the TwinCAT solution, you have to create one.
- 2. A function block is generated, which implements the interface "ItcIoUdpProtocolRecv". This creates a method, which is called when UDP packets arrive.
By right-clicking on the node "POU" in the PLC project you can allocate names in the Popup window, activate "SampleUdpEchoServer" and "Implements" by ticking, and select the interface mentioned with the button "…":
The declaration part of the function block contains several variables in the declaration:
- Oid: Configurable reference to the TCP/UDP RT module
- ipUdp: Interface pointer to the UdpProtocol, which is implemented by the TCP/UDP RT module
- udpPort: Port used for receiving
- 3. The declaration part is created in this way:
{attribute 'c++_compatible'}
FUNCTION_BLOCK SampleUdpEchoServer IMPLEMENTS ITcIoUdpProtocolRecv
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
{attribute 'TcInitSymbol'}
oid: OTCID;
ipUdp: ITcIoUdpProtocol;
nUdpPort: UINT := 10000;
nReceivedPakets: UINT;
hrInit : HRESULT;
hrSend : HRESULT;
END_VAR
The CheckReceive() method of the TCP/UDP RT module must be called in the body of the function block.
- 4. The body is created in this way:
IF ipUdp <> 0 THEN
ipUdp.CheckReceived();
END_IF
The method "ReceiveData", which was created through implementation of the interface, will be called repeatedly via "CheckReceived": one call for each packet received in the meantime.
- 5. The method has both sender information and data as input parameters. In this sample, the "SendData" method returns an incoming packet as response (with sender/receiver reversed). The implementation is done as follows:
nReceivedPakets := nReceivedPakets+1;
IF ipUdp <> 0 THEN
hrSend := ipUdp.SendData(ipAddr, udpSrcPort, udpDestPort, nData, pData, TRUE, 0); // send data back
END_IF
During start and finish, a reference to the "UdpProtocol" interface must be set from the configured OID; corresponding approvals should be taken care of during shutdown.
- 6. The function block requires the methods "FB_init", "FB_reinit" and "FB_exit", which can be created by right-clicking on the function block "Add…" method:
Appropriate signatures are generated automatically, so that only the actual body has to be realized. Of particular significance is the "RegisterReceiver" call, which opens a UDP port for reception.
- 7. The "FB_init" method requires two local variables:
VAR
ipSrv: ITComObjectServer;
END_VAR
- 8. The "FB_init" method is implemented as follows:
IF NOT bInCopyCode THEN // no online change
IF ipUdp = 0 AND oid <> 0 THEN
hrInit := FW_ObjMgr_GetObjectInstance(oid:=oid, iid:=TC_GLOBAL_IID_LIST.IID_ITcIoUdpProtocol, pipUnk:=ADR(ipUdp) );
IF SUCCEEDED(hrInit) THEN
IF SUCCEEDED(ipUdp.RegisterReceiver(nUdpPort, THIS^)) THEN //open port
FB_init := TRUE;
ELSE
FB_init := FALSE;
FW_SafeRelease(ADR(ipUdp));
END_IF
END_IF
ELSIF oid = 0 THEN
FB_init := FALSE;
hrInit := ERR_INVALID_PARAM;
END_IF
END_IF
In the "FB_reinit" method, which is executed during an OnlineChange, the TCP/UDP RT object must be supplied with the new address for the callbacks.
- 9. The "FB_reinit" method is implemented as follows:
IF (ipUdp <> 0) THEN
ipUdp.RegisterReceiver(nUpdPort, THIS^);
FB_reinit := TRUE:
END_IF
The port must be closed again during shutdown (but not during OnlineChange, cf. bInCopyCode).
- 10. The "FB_exit" method is implemented as follows:
IF (NOT bInCopyCode AND ipUdp <> 0) THEN //Shutdown
ipUdp.UnregisterReceiver(nUpdPort);
FW_SafeRelease(ADR(ipUdp));
FB_exit := TRUE;
ELSE
FB_exit := FALSE;
END_IF
- 11. Finally, the function block must be called:
PROGRAM MAIN
VAR
udp1 : SampleUdpEchoServer;
END_VAR
udp1();
“TCP/UDP RT” module configuration
- 1. Create the “TCP/UDP RT” module under the RT Ethernet adapter by selecting “Add Object(s)…” in the context menu.
- 2. Then select the “TCP/UDP RT” module:
- The TCP/UDP RT object is created under the adapter.
- 3. Parameterize the previously created instance of the module (here: Module1) under “Interface Pointer” “TcpProt” with the OID of the created “TCP/UDP RT” object:
- 4. For PLC projects this configuration is also done at the instance, under the tab “Symbol Initialization”:
- The configuration is thus completed
Disconnection by the operating system in Promiscuous mode If Promiscuous mode is active at the RT Ethernet adapter in the “Adapter” tab, any TCP connection attempts are blocked by the operating system, since it does not recognize a port opened in the TCP/UDP RT object. |
Testing
Once the configuration has been activated, a UDP packet can be sent to the PLC via the UDP Sample Client. It can be observed that each call increments the counter. The client displays the returned packets at the top.
No local communication The UDP sample client must run on a different computer than the PLC with the TCP/UDP RT object, because no local communication between the Windows operating system and the real-time is available. |