• Create a "Standard project" and select CODESYS Control Win V3 as the device.
  • Define the target system by means of the Network scan.





As of SP16:

  • Open the Library Manager and add the following libraries:
    Net Base Services
    SysTypes2 interfaces
    SysTimeRtc
    Util





  • Create a global variable list named gvlSetting and define the following variables:



    Declaration

    VAR_GLOBAL CONSTANT
    	gc_wMaxTelegram	: INT := 15;
    	gc_uiPort		: UINT := 50001;
    END_VAR
    VAR_GLOBAL
    	gc_stIpAddr		: String(19) := '192.168.99.109';
    END_VAR




    Adapt the IP address and the port to your system.


  • Create a new POU named TcpServer and adapt it as follows:



    Declaration

    VAR CONSTANT
    	c_wMaxTelegram	: INT := 15;
    END_VAR
    VAR
    	ipAddress		: NBS.IPv4Address;
    	fbTcpConnection	: NBS.TCP_Connection;
    	fbTcpServer		: NBS.TCP_Server;
    	fbTcpRead		: NBS.TCP_Read;
    	fbTcpWrite		: NBS.TCP_Write;
    	
    	
    	abyRx			: ARRAY [0..gvlSetting.gc_wMaxTelegram] OF BYTE;
    	abyTx			: ARRAY [0..gvlSetting.gc_wMaxTelegram] OF BYTE;
    	
    	iIndex			: INT;
    	xRead			: BOOL := TRUE;
    	xWrite			: BOOL := TRUE;
    	xAckTelegram	: BOOL;
    	xBlockAck		: BOOL;
    	udiRead			: DINT;
    END_VAR




    Implementation

    IF fbTcpRead.xReady THEN
    	IF (fbTcpRead.udiCount = (gvlSetting.gc_wMaxTelegram + 1)) THEN	
    		IF ((abyRx[0] = 87) AND  (abyRx[1] = 68) AND (abyRx[2] = 58) AND (abyRx[3] = 32)) THEN // 'WD: ' = Watchdog-Telegram
    			FOR iIndex := 0 TO c_wMaxTelegram DO
    				abyTx[iIndex] := 0;	 
    			END_FOR
    			// 'ACK: ' = Acknowledge-Telegram
    			abyTx[0] := 65;
    			abyTx[1] := 67;
    			abyTx[2] := 75;
    			abyTx[3] := 58;
    			abyTx[4] := 32;
    			// Receive-Counter
    			abyTx[5] := abyRx[4];
    			abyTx[6] := abyRx[5];
    			abyTx[7] := abyRx[6];
    			abyTx[8] := abyRx[7]; 
    			xWrite := TRUE;
    		END_IF
    		xWrite := TRUE;
    	END_IF
    ELSIF fbTcpRead.xError THEN
    	xRead := FALSE;
    END_IF
    
    
    fbTcpWrite(xExecute := xWrite AND NOT xBlockAck, itfConnection := fbTcpConnection, udiSize := SIZEOF(abyTx), pData := ADR(abyTx),  udiTimeOut := 0);
    IF fbTcpWrite.xDone OR fbTcpWrite.xError THEN
    	xWrite := FALSE;
    END_IF





  • Create a new POU named TcpClient and adapt it as follows:



    Declaration

    VAR CONSTANT
    	c_tInterval		: TIME := T#1S;
    	c_udiInterval	: UDINT := 3 * TIME_TO_UDINT(c_tInterval)/1000;
    END_VAR
    VAR
    	ipAddress		: NBS.IPv4Address;
    	fbTcpClient		: NBS.TCP_Client;
    	fbTcpRead		: NBS.TCP_Read;
    	fbTcpWrite		: NBS.TCP_Write;
    	
    	abyTx			: ARRAY [0..gvlSetting.gc_wMaxTelegram] OF BYTE;
    	abyRx			: ARRAY [0..gvlSetting.gc_wMaxTelegram] OF BYTE;
    	
    	fbBlink			: BLINK := (TIMELOW := c_tInterval, TIMEHIGH := c_tInterval);		
    	xBlink			: BOOL; // Memory of the last state of PLC_PRG.fbBlink
    	
    	udiVal			: UDINT;
    	pudiVal			: POINTER TO BYTE;
    	iIndex			: INT;
    	xConnect		: BOOL;
    	
    	xRead			: BOOL;
    	xMissingAck		: BOOL;
    	udiResult 		: UDINT;
    	udiLastAck		: UDINT;
    	udiNow			: UDINT;
    	udiRead			: UDINT;
    	eRErrorID 		: NBS.ERROR;
    	eWErrorID 		: NBS.ERROR;
    END_VAR




    Implementation

    IF NOT fbTcpClient.xActive THEN
    	ipAddress.SetInitialValue(ipAddress := gvlSetting.gc_stIpAddr);
    END_IF
    fbTcpClient(xEnable := xConnect, itfIPAddress := ipAddress, uiPort := gvlSetting.gc_uiPort, udiTimeOut := 0);
    
    fbBlink(ENABLE := TRUE);
    IF (fbBlink.OUT AND (xBlink <> fbBlink.OUT) ) THEN
    	udiVal := udiVal + 1;
    	FOR iIndex := 0 TO gvlSetting.gc_wMaxTelegram DO
    		abyTx[iIndex] := 0;
    	END_FOR
    	// 'WD: ' = Watchdog-Telegram
    	abyTx[0] := 87;
    	abyTx[1] := 68;
    	abyTx[2] := 58;
    	abyTx[3] := 32;
    	// Counter
    	pudiVal := ADR(udiVal);
    	abyTx[4] := pudiVal^;
    	pudiVal := pudiVal + 1;
    	abyTx[5] := pudiVal^;
    	pudiVal := pudiVal + 1;
    	abyTx[6] := pudiVal^;
    	pudiVal := pudiVal + 1;
    	abyTx[7] := pudiVal^;
    	fbTcpWrite(xExecute := xConnect,itfConnection := fbTcpClient.itfConnection, udiTimeOut := 0, udiSize := SIZEOF(abyTx), pData := ADR(abyTx));
    ELSE
    	fbTcpWrite(xExecute := FALSE);
    END_IF
    
    xBlink := fbBlink.OUT;
    
    fbTcpRead(xEnable := xRead AND xConnect, itfConnection := fbTcpClient.itfConnection, udiSize := SIZEOF(abyRx), pData := ADR(abyRx), udiCount => udiRead);
    
    IF fbTcpRead.xReady THEN
    	IF (fbTcpRead.udiCount = (gvlSetting.gc_wMaxTelegram + 1)) THEN
    		IF ((abyRx[0] = 65) AND  (abyRx[1] = 67) AND (abyRx[2] = 75) AND (abyRx[3] = 58) AND (abyRx[4] = 32)) THEN // 'WD: ' = Watchdog-Telegram
    			udiLastAck := SysTimeRtc.SysTimeRtcGet(udiResult);
    		END_IF
    	END_IF
    ELSIF fbTcpRead.xError THEN
    	fbTcpRead(xEnable := FALSE);
    END_IF
    
    
    IF NOT fbTcpClient.xActive AND NOT fbTcpClient.xBusy AND NOT fbTcpClient.xDone THEN
    	xConnect := TRUE;
    ELSIF fbTcpClient.xDone THEN
    	xConnect := FALSE;
    END_IF
    
    udiNow := SysTimeRtc.SysTimeRtcGet(udiResult);
    
    IF (udiNow > (udiLastAck + c_udiInterval)) THEN  
    	xMissingAck := TRUE;
    ELSE
    	xMissingAck := FALSE;
    END_IF







  • Adapt the POU PLC_PRG as follows:



    Implementation

    TcpServer();
    TcpClient();






  • Load the project to the controller and start it. Set The variable TcpClient.xRead to TRUE.


Up to SP16:

  • Open the Library Manager and add the following libraries:
    CAA Net Base Services
    SysTypes2 interfaces
    SysTimeRtc
    Util




  • Create a global variable named gvlSetting.

    Adapt gvlSetting as follows:



    Declaration

    {attribute 'qualified_only'}
    VAR_GLOBAL CONSTANT
        gc_uiPort        : UINT := 50001;
        gc_stIpAddr      : NBS.IP_ADDR := (sAddr := '192.168.99.74');
        
        gc_wMaxTelegram  : INT := 15; // Length o the telegram
    END_VAR




    Adapt the IP address and the port to your system.



  • Create a new POU named TcpServer and adapt it as follows:



    Declaration

    VAR CONSTANT
        c_wMaxTelegram  : INT := 15;
    END_VAR
    VAR
        fbTcpConnection : NBS.TCP_Connection;
        fbTcpServer     : NBS.TCP_Server;
        fbTcpRead       : NBS.TCP_Read;
        fbTcpWrite      : NBS.TCP_Write;
    
        abyRx           : ARRAY [0..gvlSetting.gc_wMaxTelegram] OF BYTE;
        abyTx           : ARRAY [0..gvlSetting.gc_wMaxTelegram] OF BYTE;
    
        iIndex          : INT;
        xRead           : BOOL := TRUE;
        xWrite          : BOOL := TRUE;
        xAckTelegram    : BOOL;
        xBlockAck       : BOOL;
        udiRead         : UDINT;
    END_VAR




    Implementation

    fbTcpServer(xEnable := TRUE, ipAddr := gvlSetting.gc_stIpAddr, uiPort := gvlSetting.gc_uiPort);
    fbTcpConnection(xEnable := fbTcpServer.xBusy, hServer := fbTcpServer.hServer);
    
    fbTcpRead(xEnable := fbTcpConnection.xActive, hConnection := fbTcpConnection.hConnection, szSize := SIZEOF(abyRx), pData := ADR(abyRx), szCount => udiRead);    
    
    IF fbTcpRead.xReady THEN
        IF (fbTcpRead.szCount = (gvlSetting.gc_wMaxTelegram + 1)) THEN    
            IF ((abyRx[0] = 87) AND  (abyRx[1] = 68) AND (abyRx[2] = 58) AND (abyRx[3] = 32)) THEN // 'WD: ' = Watchdog-Telegram
                FOR iIndex := 0 TO c_wMaxTelegram DO
                    abyTx[iIndex] := 0;     
                END_FOR
                // 'ACK: ' = Acknowledge-Telegram
                abyTx[0] := 65;
                abyTx[1] := 67;
                abyTx[2] := 75;
                abyTx[3] := 58;
                abyTx[4] := 32;
                // Receive-Counter
                abyTx[5] := abyRx[4];
                abyTx[6] := abyRx[5];
                abyTx[7] := abyRx[6];
                abyTx[8] := abyRx[7]; 
                xWrite := TRUE;
            END_IF
            xWrite := TRUE;
        END_IF
    ELSIF fbTcpRead.xError THEN
        xRead := FALSE;
    END_IF
    
    fbTcpWrite(xExecute := xWrite AND NOT xBlockAck, hConnection := fbTcpConnection.hConnection, szSize := SIZEOF(abyTx), pData := ADR(abyTx),  udiTimeOut := 0);
    IF fbTcpWrite.xDone OR fbTcpWrite.xError THEN
        xWrite := FALSE;
    END_IF





  • Create a new POU named TcpClient and adapt it as follows:


    Declaration

    VAR CONSTANT
        c_tInterval   : TIME := T#1S;
        c_udiInterval : UDINT := 3 * TIME_TO_UDINT(c_tInterval)/1000;
    END_VAR
    VAR
        fbTcpClient   : NBS.TCP_Client;
        fbTcpRead     : NBS.TCP_Read;
        fbTcpWrite    : NBS.TCP_Write;
    
        abyTx         : ARRAY [0..gvlSetting.gc_wMaxTelegram] OF BYTE;
        abyRx         : ARRAY [0..gvlSetting.gc_wMaxTelegram] OF BYTE;
    
        fbBlink       : BLINK := (TIMELOW := c_tInterval, TIMEHIGH := c_tInterval);        
        xBlink        : BOOL; // Memory of the last state of PLC_PRG.fbBlink
    
        udiVal        : UDINT;
        pudiVal       : POINTER TO BYTE;
        iIndex        : INT;
        xConnect      : BOOL;
    
        xRead         : BOOL := TRUE;
        xMissingAck   : BOOL;
        udiResult     : UDINT;
        udiLastAck    : UDINT;
        udiNow        : UDINT;
        udiRead       : UDINT;
    END_VAR

    Implementation

    fbTcpClient(xEnable := xConnect, ipAddr := gvlSetting.gc_stIpAddr, uiPort := gvlSetting.gc_uiPort, udiTimeOut := 0);
    
    fbBlink(ENABLE := TRUE);
    IF (fbBlink.OUT AND (xBlink <> fbBlink.OUT) ) THEN
        udiVal := udiVal + 1;
        FOR iIndex := 0 TO gvlSetting.gc_wMaxTelegram DO
            abyTx[iIndex] := 0;
        END_FOR
        // 'WD: ' = Watchdog-Telegram
        abyTx[0] := 87;
        abyTx[1] := 68;
        abyTx[2] := 58;
        abyTx[3] := 32;
        // Counter
        pudiVal := ADR(udiVal);
        abyTx[4] := pudiVal^;
        pudiVal := pudiVal + 1;
        abyTx[5] := pudiVal^;
        pudiVal := pudiVal + 1;
        abyTx[6] := pudiVal^;
        pudiVal := pudiVal + 1;
        abyTx[7] := pudiVal^;
        fbTcpWrite(xExecute := xConnect,hConnection := fbTcpClient.hConnection, udiTimeOut := 0, szSize := SIZEOF(abyTx), pData := ADR(abyTx));
    ELSE
        fbTcpWrite(xExecute := FALSE);
    END_IF
    
    xBlink := fbBlink.OUT;
    
    fbTcpRead(xEnable := xRead AND xConnect, hConnection := fbTcpClient.hConnection, szSize := SIZEOF(abyRx), pData := ADR(abyRx), szCount => udiRead);
    
    IF fbTcpRead.xReady THEN
        IF (fbTcpRead.szCount = (gvlSetting.gc_wMaxTelegram + 1)) THEN
            IF ((abyRx[0] = 65) AND  (abyRx[1] = 67) AND (abyRx[2] = 75) AND (abyRx[3] = 58) AND (abyRx[4] = 32)) THEN // 'WD: ' = Watchdog-Telegram
                udiLastAck := SysTimeRtc.SysTimeRtcGet(udiResult);
            END_IF
        END_IF
    ELSIF fbTcpRead.xError THEN
        fbTcpRead(xEnable := FALSE);
    END_IF
    
    IF NOT fbTcpClient.xActive AND NOT fbTcpClient.xBusy AND NOT fbTcpClient.xDone THEN
        xConnect := TRUE;
    ELSIF fbTcpClient.xDone THEN
        xConnect := FALSE;
    END_IF
    
    udiNow := SysTimeRtc.SysTimeRtcGet(udiResult);
    
    IF (udiNow > (udiLastAck + c_udiInterval)) THEN  
        xMissingAck := TRUE;
    ELSE
        xMissingAck := FALSE;
    END_IF

  • Adapt the POU PLC_PRG as follows:


    Implementation

    TcpServer();
    TcpClient();

  • Load the project to the controller and start it.