基于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