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



  • 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:


    Implementierung

    TcpServer();
    TcpClient();

  • Load the project to the controller and start it.



  • No labels