PPI通信功能的实现
实现PPI的关键是帧格式。由于PPI协议并不公开,我们只能从网上查找资料并自己动手实验,确定某几个功能的帧格式。这也是我们只实现了9个函数的原因。
本文的均以十六进制表示数据,但一个帧中的字节流的下标是十进制。
读V区的数据时,如下表所示:
注意:PPI通信时,先发送低地址上的字节。例如,数据个数为1时,上表第24、25字节是01 00,而不是00 01。但地址偏移量却是高位在前。
将以上字节流发送给PLC后,PLC将首先返送一个字节E5,表示接收成功,等待主机确认。这时主机应该发送确认帧:
10, 02, 00, 5C, 5E, 16
注意:收到E5后 ,主机应当延时一定时间后再发送确认帧,这个时间大概是10ms以上(上限未测),否则PLC很可能由于处理速度等原因出错,造成通信失败。
收到确认帧后,PLC将返回包含结果的帧。帧长度根据您读的数据的长度而变。但帧格式还是统一的,只是“结果值”占用的空间不同而已。结果帧如下表所示。主机程序应当对结果帧进行严格的校验,避免假读或内存越界。
注意:主机地址和PLC地址与读 命令时倒了过来。
注意:我们常常需要把结果里的字节流转化成整形、浮点数等等。注意,结果字节流是低地址在前。这可能和主机上的字节顺序是反的。如果是这样,需要将顺序倒过来。
写V区的一个数据时,写命令的前面22个字节如表所示:
之后的字节流 ,因数据类型不同而长度不同
注意:值里,低地址在前。这可能和主机上的字节顺序是反的。如果是这样,需要将短整形、整形、浮点数等的字节顺序倒过来,在写入命令里。
将以上字节流发送给PLC后,PLC返回一个字节E5,表示接收成功,等待主机确认。这时主机应该发送确认帧:
10, 02, 00, 5C, 5E, 16
注意:收到E5后 ,主机应当延时一定时间后再发送确认帧,这个时间大概是10ms以上(上限未测),否则PLC很可能由于处理速度等原因出错,造成通信失败。
如果写命令被成功执行,PLC将返回给主机一个长度为24的帧
注意:如果未能接收到以上的返回帧——写命令失败了,但是否就此可以确认:写命令没有对PLC造成任何影响呢?这就不得而知了。建议在PLC程序以及主机程序里,都要充分考虑到这种情况,避免事故的发生。
注意:若主机采取“阻塞读”模式,此时PLC未必会返回24个字节(因写失败了),那么主机程序会被无限阻塞下去。最好不要采取阻塞模式。
附加的注意:
注意:由于用户很可能需要循环读取数据,OCOTCS PPI在每个函数的一开始就进行了延迟。发送确认帧前又进行了延时。从此,通信变得非常稳定。
注意:网络上流行着很多PPI协议解析,它们比本文要全面得多,读者很可能需要它们。但它们多多少少会有些错误。我就使用了很多个版本,而每个版本多少都有些错误。特别是对于延迟这一点,根本没有提及。而延迟对于通信成功是至关重要的,否则几乎必定失败。建议读者多读几个版本,用“组态王”等这样有完整PPI通信功能的软件进行一下监听。现附上几个网上常见的错误:
(1)“一次写一个Double Word类型的数据,写命令是40个字节,其余为38个字节”。这是错误的。
(2)没有注意到读写时,第17个字节有不同的值
(3)写命令里,没有注意到第16个字节会因数据类型不同而不同。尽管它与第34个字节似乎是冗余的。
注意:请关注本文那些没有进行注解的字节,它们并不是无关紧要的。