1009【万泉河】体验MODBUS TCP全双工通讯
经常被问起以太网通讯的MODBUS TCP和485通讯的MODBUS RTU有什么区别。
除了报文本身的区别,当然最终导致的是通讯功能块不同之外, 还有一个重大的区别是TCP通讯是全双工的,而RTU通讯只能是半双工。
何为全双工和半双工?其实在这两者之前, 还有一个更低级的单工通讯方案。网络搜索其定义如下:
一、单工通信(simplex)
单工通信只支持信号在一个方向上传输(正向或反向),任何时候不能改变信号的传输方向。
为保证正确传送数据信号,接收端要对接收的数据进行校验,若校验出错,则通过监控信道发
送请求重发的信号。
此种方式适用于数据收集系统,如气象数据的收集、电话费的集中计算等。
例如计算机和打印机之间的通信是单工模式,因为只有计算机向打印机传输数据,而没有相反
方向的数据传输。还有在某些通信信道中,如单工无线发送等。
二、半双工通信(half-duplex)
半双工通信允许信号在两个方向上传输,但某一时刻只允许信号在一个信道上单向传输。
因此,半双工通信实际上是一种可切换方向的单工通信。
此种方式适用于问讯、检索、科学计算等数据通信系统;
传统的对讲机使用的就是半双工通信方式。由于对讲机传送及接收使用相同的频率,不允许同
时进行。因此一方讲完后,需设法告知另一方讲话结束(例如讲完后加上’OVER’),另一方
才知道可以开始讲话。
三、全双工(full-duplex)
全双工通信允许数据同时在两个方向上传输,即有两个信道,因此允许同时进行双向传输。
全双工通信是两个单工通信方式的结合,要求收发双方都有独立的接收和发送能力。
全双工通信效率高,控制简单,但造价高。
计算机之间的通信是全双工方式。一般的电话、手机也是全双工的系统,因为在讲话时可以听到对方的声音
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/iningwei/article/details/100134783
对应到MODBUS TCP通讯,可以同时实现数据收发,不需要等待线路空载。那么照理应当可以多个MODBUS 通讯任务同时执行,而不需要像RTU工况下的任务逐个轮询。 然而还有个但是,就是这个但是的条件, 又导致了事实上即便是MODBUS TCP通讯,往往也不能简单全双工多任务同时通讯,即便是MODBUS TCP通讯,也需要通过轮询来实现对多个站点的数据访问,如我在GML 优雅MODBUS 通讯库中实现的那样。
“但是”条件包括:
1, MODBUS TCP通讯需要占用PLC的TCP通讯资源,而西门子PLC给TCP通讯预留的通讯资源数量是有限的。 而且这个数量通常比较小。 比如比较高端的CPU1515,也仅仅不过64或者128,具体可以通过查询手册参数获得。 而如果低端的CPU, 数量会更少。 比如CPU1214,则只有8个。 我们来做一种通讯方案设计,肯定是要对低端系统更兼容,所以我会更关注低端的1200的数量限制,对高端的1500的具体数值反而不太关心了。
2, MODBUS的通讯读数据和写数据要分开算做2个通讯任务,而一些具体的设备,如果要实现的通讯管理功能较多,或者所提供的数据区地址比较分散,那么即便只是读,也需要多个通讯任务才能完成。
3, 按照官方资料的说法, 每一个IP通讯对象,必须使用唯一通讯资源ID。那么除非对这个设备只有单个任务读或者写,才可以全双工不轮询,然而实际应用中这种情况非常少。
4, 即便无上面条件限制,对于比如S7-1200来说,顶多8个链接也太受限制了。 哪怕每个设备的通讯只需要一个ID, 那么8台以上,也资源耗尽了。
所以才有了GML MODBUS库,在实现了RTU轮询之后,又做了升级,在TCP环境下也做了实现。
然而,始终心有不甘。
比如,就有学员讲,我设备的通讯对象少啊, 就只有1个或者2个需要通讯的站,就顶多2*2=4个通讯任务,能不能全双工并行通讯,不做轮询?当然,还有更多的搞非标自动化设备的同行,还根本没机会用到MODBUS通讯, 处于无感状态。希望能有更简单的入手MODBUS的方式。
于是,对MODBUS TCP到底能做多少个并行通讯做了研究。
首先,我对手册中约定的每个IP只能有一个链接是不相信的。 对于PLC做客户端, 发起TCP连接时,只要服务侧不拒绝, 建立多个链接也理应完全没有问题。 就像电脑上的即时通信类软件,跟服务器都是同时建立了多个链接的, 不同的链接掌管了不同的通信任务。 而且不管是QQ还是微信,也都还可以同时在一台电脑上运行多个账号,那么在服务侧看来,分明就是一个IP地址连过来的多个TCP链接。
所以,首先验证了客户端2个ID跟同一个IP分别发起MODE=0读操作和MODE=1写操作的请求,当然,不管读还是写,都是要完整的请求和返回的双向通讯的过程。 在服务端使用MODSIM的情况下,验证结果是可以访问的。
于是测试了S7-1200作为MODBUS TCP CLIENT客户端, 重复访问一个MODSIM模拟的SERVER的情况,其中任务1读取40001的值,读取长度为1, 而后面的任务2,3,4,5….15,16则把读到的数值分别写回到4002,4003,4004….40015, 40016
那么我们只要在MODSIM中模拟4001的数据增长, 在通讯成功的情况下,就会看到后面的数据也同步增长。
然后可以发现, 不仅仅8个可以成功,而且可以最多到14个。
然后我们倒回去查看系统资源:
S7-1214可以有开放式用户通信8个,而系统动态资源6个,这样加起来正好是14个。 果不欺我。
调用失败的任务,报错状态为16#8087
查阅系统帮助手册,这个故障码不在MODBUS通讯部分,而在TCP通讯中可以找到:
8087:已达到最大连接数,无法建立更多连接。
无需多言,解释已经够清清楚楚了。
我这里对系统通讯库MB_CLIENT做了一个简单的封装, 主要实现了2部分功能:
1, 将IP地址集约到一个管脚,字符串的形式输入。避免了参数过多而显得繁琐。
2, 通过程序自动分配了连接资源需要的CONNID。而不是手动输入。
CONNID可以设置区间为1-4096, 所有任务之间不可以重复。所以必须唯一。 而如果我们的通讯将来要内嵌于某个设备,比如某个变频器,那么CONNID就会变得非常棘手, 每一台变频器实例都要分配不同的ID,而如果多个任务使用了不同的ID,也都还要另外分配。 就相当麻烦。 这里做了一个函数来实现。当然,是从GML中直接搬过来的。
这个例子我会随文章放到烟台方法知识星球上,星球的会员随时可以下载借鉴学习。 有人问我加入星球如何保证物超所值?嗯,据我了解,所有运营星球的知识博主更关心的是会员在一年门票满期后的重复续费的比例。所以都会尽其所能的不断充实星球的知识。
而我自己,既然运营了烟台方法知识星球作为知识资料库,我就会源源不断把我手头多年积累的各种资源工具都给逐步放到星球上去。 直到有一天假如我不存在了,星球会永久陪伴着大家。 这里会成为我给行业贡献的知识遗产聚集地。
一定要注意,我这里测试的服务器对象是MODSIM, 而如果是其它的服务器端, 变频器,MODBUS TCP/RTU网关等,具体每一种设备可以支持多少并发的通讯连接, 还要取决于对方的性能。
比如,我还使用SMART 200模拟作为MODBUS TCP SERVER, 同样的S7-1200的程序,测试结果是只有一个任务可以运行成功。
所以,不需要顾虑轮询的全双工通讯, 只限于设备数量少于8个, 且每个设备对象(IP)只有1个通讯任务(要么读数据要么写数据)的情况。 而只要稍微需求再复杂些,还是要用具备轮询功能的GML库。
当然, GML V4库这些我也已经放在星球上了。 星球居民都是可以随时得到的。
我此次研究全双工通讯的目的,是为了对GML升级到V5.0做准备。 在V4之前,都专门设置了一个SUBNET的概念,需要使用者临时部署SUBNET号,每个IP对应一个子网号。使用起来还是有些不方便。 我打算的是在摸清楚了全双工极致之后,在尽量多使用全双工并行通讯资源的情况下,再合理调度不重要的站点做轮询 。
轮询既包括同一个IP内多个任务之间的调度轮询, 也还包括多个IP的不同任务在同一个ID资源的轮询。而最终的调用接口都是如图中所示的简单调用,地址信息都在接口上直接输入。