基于CAA NBS的TCP CLIENT从通讯示例

阔奥智能

基于CAA NBS的TCP CLIENT从通讯示例

TCP RAW SOCKET是最常用的非标通讯,我们demo工程中有TCP主站,本文介绍TCP从站。

1、简介:

TCP协议是非标通讯常用的方式,扫码设备、高速测量设备、非标自动化设备中都大量用到。相对于Modbus TCP来说,TCP更简单,更适用于C# 或通用化的通讯场合。
我们DEMO中有PLC作为TCP服务器的示例代码,本文介绍PLC作为TCP客户端的示例代码。

2、准备工作:

在CODESYS中,TCP有两个库,分别是官方的Net Base Services和CAA Net Base Services。我个人推荐CAA库。在库管理器里添加库,搜索TCP_Write即可看到,注意右上角加号要点上。

虽然TCP是“流”的概念而不是UDP的“包”,但在实际应用中,我们一般倾向于把它当成包来处理(除非数据量较大牵涉到粘包拆包)。

在本示例中,我们假设单个数据包内容为{0,0,0,0}这种格式,收发数据均为DINT类型,一个包4个数据。

3、代码:

话不多说,直接看代码:

PROGRAM PLC_PRG
VAR
    client:NBS.TCP_Client;
    ip:NBS.IP_ADDR:=(sAddr:='192.168.2.100');
    read:NBS.TCP_Read;
    write:NBS.TCP_Write;
    strRead:STRING(99);
    strWrite:STRING(99);
    xWriteEnable: BOOL;
    iCount:INT;
    tonDelay:TON;
    tCyclicDelay:TIME:=T#10MS;
    sTemp:STRING;
    arOutput:ARRAY[0..3] OF DINT;
    arInput:ARRAY[0..3] OF DINT;
    i:INT;
    xStartCyclic:BOOL:=TRUE;
    ton_LostConnect:TON;
END_VAR



//Client
client(xEnable:=NOT ton_LostConnect.Q ,ipAddr:=ip ,uiPort:=1000);

//Lost Connect
IF NOT client.xActive OR write.xError THEN
    IF ton_LostConnect.Q THEN
        ton_LostConnect(IN:=FALSE);
    END_IF
    ton_LostConnect(IN:=TRUE,PT:=T#2000MS);
END_IF
//Read  
read(xEnable:=client.xActive ,hConnection:=client.hConnection , szSize:=SIZEOF(strRead) , pData:=ADR(strRead));
IF read.szCount > 0 THEN
    //Got data, split it
    strRead:=left(strRead, ULINT_TO_INT(read.szCount));//only keep actual data
    sTemp:=RIGHT(strRead, LEN(strRead)-1);//remove '{' symbol
    arInput[0]:=STRING_TO_DINT(LEFT(sTemp, FIND(sTemp, ',')-1));//get first data
    sTemp:=RIGHT(sTemp, LEN(sTemp)-FIND(sTemp, ','));//remove first data on string
    arInput[1]:=STRING_TO_DINT(LEFT(sTemp, FIND(sTemp, ',')-1));//get second data
    sTemp:=RIGHT(sTemp, LEN(sTemp)-FIND(sTemp, ','));//remove second data on string
    arInput[2]:=STRING_TO_DINT(LEFT(sTemp, FIND(sTemp, ',')-1));//get 3rd data
    sTemp:=RIGHT(sTemp, LEN(sTemp)-FIND(sTemp, ','));//remove 3rd data on string
    arInput[3]:=STRING_TO_DINT(LEFT(sTemp, LEN(sTemp)-1));//get last one data
END_IF
iCount:=ULINT_TO_INT(read.szCount);//just for traceable

//Prepare senddata
strWrite:='{';
FOR i:=0 TO 3 DO
    strWrite:=CONCAT(strWrite,DINT_TO_STRING(arOutput[i]));
    IF i<3 THEN
        strWrite:=CONCAT(strWrite,',');
    END_IF;
END_FOR
strWrite:=CONCAT(strWrite,'}');
//Write
write(xExecute:=xWriteEnable , hConnection:=client.hConnection , szSize:=LEN(strWrite) , pData:=ADR(strWrite));

tonDelay(IN:=xStartCyclic,PT:=tCyclicDelay);
xWriteEnable:=FALSE;
IF tonDelay.Q THEN
    tonDelay(IN:=FALSE);
    xWriteEnable:=TRUE;
END_IF

4、解释

网页中的代码可能不直观,建议复制到CODESYS中查看。
这段代码实现了TCP CLIENT通讯,自动重连,读取、拆分数据,打包、发送数据及周期通讯的功能。

由于CAA库是CODESYS自带的,所以这段代码在汇川、禾川、施耐德等PLC上也可以运行。稍作修改也可以在倍福上运行。

No Comments

Add your comment