目录
高速数据采集要保证速度,也要保证时刻的准确性。在Windows系统里,时间稳定性是个很难的问题。如果PLC发送的数据里带有时间信息,则可以由PLC来保证采样周期的稳定性。
从V2.12版本开始,PLC-Recorder软件可以处理发送电文里的时间戳(并有时钟校准等高级功能),有网友用0.24ms的速度外发,软件也能够稳定接收并精确确定数据的时刻。
本文向大家展示一下倍福TC3 PLC通过UDP快速通信的实现方法。
一、测试条件
测试条件如下:
- 通信协议:UDP。
- 编程软件和系统:TcXaeShell
- PLC的IP地址:192.168.20.17
- PLC-Recorder所在电脑的IP地址:192.168.20.20。
- PLC的主任务设置成1ms的循环(最小可以设置为0.25ms,实际周期与平台有关,本文是用软PLC测试,实际周期是1ms左右,所以此处将周期设置为1ms)。
二、测试结论
本次测试采用了连续循环,每两个周期发送一次(上升沿触发)。理论发送周期:2ms
三、PLC的发送程序
1、报文数据结构
TYPE DUT_MSG :
STRUCT
stamp:UDINT:=0;//时间戳,单位是微秒
seq:UINT:=0;//电文序号
sysWord:INT:=50;
D_A:INT:=1;
D_B:DINT:=2;
D_C:REAL:=3.1;
D_D:INT;
END_STRUCT
END_TYPE
2、主程序的局部变量
VAR
fbSocketUdpCreate : FB_SocketUdpCreate;(*UDP建立连接的功能块*)
fbSocketUdpSendTo : FB_SocketUdpSendTo;(* UDP发送功能块*)
fbSocketUdpReceiveFrom : FB_SocketUdpReceiveFrom;(* UDP写入的功能块*)
fbSocketClose : FB_SocketClose;(* UDP关闭建立连接的功能块*)
bExecute : BOOL;(* UDP建立连接的执行位*)
bSocketConnectBusy : BOOL;
hSocket : T_HSOCKET;(*UDP的句柄*)
bSend : BOOL;(*UDP发送的执行位*)
bSocketSendbBusy : BOOL;
bRecieve : BOOL;(*UDP接收的执行位*)
bSocketReceivebBusy : BOOL;
bSocketReceivenRecBytes : UDINT;
bClose : BOOL;(*UDP关闭连接的执行位*)
fbSocketTcpCreate : FB_Socketconnect;(*TCP建立连接的功能块*)
fbSocketTcpSendTo : FB_Socketsend;(* TCP发送功能块*)
fbSocketTcpReceiveFrom : FB_Socketreceive;(* TCP写入的功能块*)
fbSocketClose_tcp : FB_SocketClose;(* TCP关闭建立连接的功能块*)
bExecute_tcp : BOOL;(* TCP建立连接的执行位*)
bSocketConnectBusy_tcp : BOOL;
hSocket_tcp : T_HSOCKET;(*TCP的句柄*)
bSend_tcp : BOOL;(*TCP发送的执行位*)
bSocketSendbBusy_tcp : BOOL;
bRecieve_tcp : BOOL;(*TCP接收的执行位*)
bSocketReceivebBusy_tcp : BOOL;
bSocketReceivenRecBytes_tcp : UDINT;
bClose_tcp : BOOL;(*TCP关闭连接的执行位*)
TON1:TON;
send_trig: BOOL;
getsystemTime:NT_GetTime;
startGet:BOOL;
getTimeBusy:BOOL;
getTimeError:BOOL;
getTimeErrorInfor:UDINT;
gvl1: INT;
localtime: INT;
cyclecounter: INT;
sendPluse: BOOL;
b_tcp_creadt_error: UDINT;
stamp:UDINT;
sendPluse_tcp: BOOL;
arrSendData: DUT_MSG;
fbCpuCounter : FW_GetCpuCounter;
lowTime : UDINT;
highTime : UDINT;
fbSystemTime : GETSYSTEMTIME;
fileTime : T_FILETIME;
dtTime : DT; // DATE_AND_TIME 格式
getTime : NT_GetTime;
timeStruct : TIMESTRUCT;
startTrigger : BOOL := FALSE;
err : BOOL;
bFirstScanDone : BOOL := FALSE;
bIsFirstScan : BOOL;
startStamp:UDINT;
timeNowULIntStart:UDINT;
timeNowULIntDif:UDINT;
bSend1: BOOL:=TRUE;//启动发送
END_VAR
3、PLC程序
cyclecounter:=cyclecounter+1;
IF
cyclecounter>1 AND bSend1 //每2个周期发送一次报文。bSend1是启动变量,如果需要上电自动启动通信,则初始值设置为TRUE
THEN
sendPluse:=TRUE;
cyclecounter:=0;
bExecute:=TRUE;//启动通信
ELSE
sendPluse:=FALSE;
END_IF
arrSendData.D_A:=arrSendData.D_A+1; //数据循环累加
bIsFirstScan := NOT bFirstScanDone; // 首次扫描时为 TRUE
bFirstScanDone := TRUE; // 第一次执行后永久置为 TRUE
IF bIsFirstScan THEN
STARTSTAMP:=Lowtime;
// 第一个扫描周期执行的代码
END_IF
fbCpuCounter(
dwCpuCntLo => lowTime, // 低 32 位
dwCpuCntHi => highTime // 高 32 位
);
IF sendPluse THEN
arrSendData.seq:=arrSendData.seq+1;//电文序号+1
timeNowULIntDif:=(lowTime-STARTSTAMP)/10;//时间戳单位转换成微秒,并计算出时间偏差
arrSendData.stamp:=timeNowULIntDif;
END_IF
fbSocketUdpCreate(
sSrvNetId:= ,
sLocalHost:='192.168.20.17' ,
nLocalPort:=5011,
bExecute:= bExecute,
tTimeout:= ,
bBusy=> bSocketConnectBusy,
bError=> ,
nErrId=> ,
hSocket=>hSocket );
fbSocketUdpSendTo(
sSrvNetId:= ,
hSocket:=hSocket ,
sRemoteHost:='192.168.20.20' , //PLC-Recorder所在的电脑IP地址。
nRemotePort:=5011 ,
cbLen:=SIZEOF(arrSendData) , //发送的长度
pSrc:=ADR (arrSendData) ,
bExecute:=sendpluse,
tTimeout:= ,
bBusy=>bSocketSendbBusy ,
bError=> ,
nErrId=> );
4、时间戳计算
读取PLC的CPU脉冲计数,单位是0.1微秒,转换成微秒。
定义:
fbCpuCounter : FW_GetCpuCounter;
计算:
fbCpuCounter(
dwCpuCntLo => lowTime, // 低 32 位
dwCpuCntHi => highTime // 高 32 位
);
IF sendPluse THEN
arrSendData.seq:=arrSendData.seq+1;//电文序号+1
timeNowULIntDif:=(lowTime-STARTSTAMP)/10;//时间戳单位转换成微秒,并计算出时间偏差
arrSendData.stamp:=timeNowULIntDif;
END_IF
四、PLC-Recorder侧的通信设置
请用收听通道,并选择时间戳单位为us。需要配置来源的IP地址及本机收听的端口号。
五、PLC-Recorder的通道配置
此处虽然配置了采集周期,但在高速模式下不再使用该周期,以收到信息的时刻为准。
六、PLC-Recorder的变量配置
UDP报文结构简单,只需要定义自己需要提取的变量即可。起始地址为0的变量就是PLC里定义的时间戳。第二个变量是电文序号。
七、数据记录情况
这是用离线分析软件Ana打开的历史数据文件。
发现在启用时间戳功能时,实际采集周期是2.9ms,电文序号有波动。
而不启用时间戳功能时,实际采集周期是2.1ms,此处的stamp变量是两个扫描周期之间的时间戳差值(专门用于分析的,不是上面给出的程序),可以看出时间戳波动比较大,最小0.04ms,最大1.744ms,平均是1.01ms,因此,这个软PLC里时钟是不稳定的(声明:此处仅为测试系统的表现,不代表倍福实际产品的状态)。
八、小结
采集的速度越快,需要的技术越复杂,代价也越大。PLC-Recorder的主动采集模式,基本只需要在PLC-Recorder里配置变量,不需要在PLC做什么复杂工作,这种方式很便捷,但是速度也有限(最快20ms)。高速模式,就需要在PLC里配置通信,组织数据,然后调用通信语句,才能够实现,因此,对于PLC工程师也有了一点要求。
高速模式采用标准以太网通信协议,这也是大部分PLC都具备的能力,因此,