前言:组态软件和现场的Modbus设备通信缓慢、丢包,这个是大家多多少少都会遇到的问题。产生问题的原因千奇百怪,今天和大家分享一个前些天遇到的挺有意思的一次故障排查。
A.故障现象:
有个朋友在厂里做FMCS厂务监控系统的项目,需要对YORK空调面板上的一些参数进行采集和设置,上位机软件采用Intouch2014R2SP1。现场有百余个YORK的面板,面板上带有RS-485ModbusRTU协议接口,通过MOXA的MB3180网关分为多路把ModbusRTU转为ModbusTCP协议供上位机采集。现场每个MB3180下大约有20个面板需要采集。网络拓扑示意如下:

在调试中,用户发现在Intouch上虽然可以读取到所有面板上的数据,也能通过Intouch修改面板上的设定参数,但是数据更新非常缓慢,一般都在20秒以上,而且有时通过Intouch下发的控制命令会有丢失。用户现场排查过物理链路,均采用120欧姆特征阻抗屏蔽双绞通信电缆,RS485网络没有星型节点,网络两端有120欧姆终端电阻。
B.思路:
在电话里听到朋友描述时,感觉上像是干扰造成的485通信故障,然而到现场后,发现朋友已经可以在办公室复现这个问题。他使用1个MB3180连接了4台面板,面板ModbusID从1到4,9600波特率,ODD/8/1,在办公室里使用笔记本上的Intouch工程仍可重现通信缓慢的问题。这是一个非常好的消息,意味着我们不用再去现场检查物理线路的问题。

于是,笔者先找他要了这个面板的手册,下面是大致要采集和控制的数据内容。(当天时间较紧,忘记拍照了,而且也没找到这个电子版手册,下图是从别的渠道获取的地址数据。)

由上图可知,获取的数据比较简单,但是像TempSP,Fan_Mode,Status,Mode这些参数都是在保持型寄存器中,上位机会进行读/写操作。所以,笔者有了第一个猜想:
1.会不会是上位机写入的数据超过了这些参数的范围?
在以往的工程经验中,见过很多由于Modbus主站向下写入的数据超过从站变量数据范围导致的通信问题。比如,向某变频器发送整数7表示启动,发送15表示停止,如果你发了一个16,但变频器里没有对应的动作,如果变频器协议机制比较完善,它会返回主站一个功能码为0x83的异常响应报文,主站也就知道是自己发的数据超出了从站该变量的范围。但是,如果从站设备的软件编写不够严谨或者存在问题,它有可能不会回复主站。由于Modbus在大多数情况下是主站对配置数据逐条轮询,并设有超时时间和重试次数,如果对某一参数写入失败且设备没有返回异常响应报文,主站会等到超时时间后再重发本次数据(即重试Retry),如果重试几次之后仍未收到正确的从站响应报文,主站才会跳过执行下一条或者放弃该从站转到另一从站ID进行数据轮询。在超时等待和重试中,会浪费大量时间。再者,极其个别的设备,如果写入了超过范围的数据,可能会造成设备通信程序甚至整机的死机或重启。判断通信缓慢是不是由这个造成的也很简单,把软体里的写入操作全部屏蔽掉,看看还有没有这个问题。如果没有了,仔细研究从站手册,看看哪些参数会有此问题。如果看不出来,则把屏蔽掉的写入操作逐条恢复,直到发现问题再仔细甄别数据范围。不过,在屏蔽了对上述所有变量的写入操作后,通信仍未改善,看来不是这里的问题,于是笔者有了第二个猜想:
2.会不会是上位机软件组包导致的?
在组态软件中,为了提高读写效率,一般会对数据进行组包。比如在本例中,当读取以下5个数据时,如果组态软件的组包长度比较大,比如100,那么组态软件一般会使用03功能码直接读取从40003开始的连续10个字来获取数据。如果组包长度设的比较小,比如设成5,那么组态软件会分成2次03功能码操作分别读取从40003开始的连续4个字和从40012开始的1个字。

设置较大的组包数值可以让软件减少一个轮询周期内的会话次数,提高通信效率和速度。但可能会有两个潜在的问题:一是某些设备因为软件限制不能处理超过一定长度的Modbus报文,比如设备可能最大只能处理数据域不超过10个字的报文,但是你发了一个读连续50个字的报文,设备可能会不回复或者出各种问题。二是如果在连续数据包中,比如上面从40003开始到40012这10个地址,在从站设备中只存在表上列出的5个,中间40007-40011这些不存在,则设备响应也可能会有问题。
这种问题判断很简单,使用Modscan或者ModbusPoll这类工具软件,尝试读取连续数据看看有没有问题就行。如果发现是此问题,可以缩小组态软件的组包长度进行解决。

可是,在用Modscan做了几组对上面的不同寄存器进行的读写测试后,发现数据读写都很正常,一点问题都没有。但是我们发现了一些有意思的现象,在只连接Modscan的时候,4个实验设备读写完全正常,一次无效应答都不存在。可是如果换成Intouch,通信立刻就出现了问题。有啥区别?ModScan轮询速度慢,是1秒钟才读取一次数据,可Intouch快了很多。于是第三个猜想涌上心头:
3.会不会是报文间隔时间太小导致的?
“在之前的工作中,笔者遇到过一些从站设备对通信的处理能力比较弱,或者是程序编制不完善,当485总线繁忙时,由于其处理器计算能力或者程序编制不合理,出现较总线不繁忙时通讯响应迟缓,设备动作卡顿,通讯中断,甚至设备重启等情况。仅在今年,笔者就遇到过一个特气集控器,主站03报文询问过快之后设备显示器停滞不刷新数据;某家电一线品牌的中央空调集控器,速度快后不定时通讯中断,必须重启设备才可恢复;某模拟量模块,速度快后模拟量读数失真;某压力表,速度快后直接重启。
想到这里,笔者在PLC主站的轮询逻辑中增加了100ms的延迟时间,即当主站收到从站的正确响应后,等100ms之后再发送下一条请求。验证,问题得到解决。”(见作者在剑指工控之前发的文章《流量积算仪Modbus通信的一些小问题》)。考虑到上述情况,笔者拿了一个随身带的HORNERXLE控制器做了个测试。在XLE里配置了4台温控器后,如果使用默认的SlaveSpeedFast,XLE会在收到从站设备响应后只等待3½个字符时间后,就会进行下一次数据请求,此时监控XLE的通信状态,会发现从站出现了很多无效报文返回,数据交互异常缓慢,和Intouch故障现象相同;在把XLE的响应速度设为Slow后,XLE会在收到报文后等待100ms才发送下一组报文,此时通信状态就完全正常了。


在基本确认问题后,剩下的就是如何在Intouch的轮询中增加这个延迟时间。笔者对Intouch不是专家,在查询手册和咨询了几位朋友后,也没在Intouch中找到在哪里能增加这个报文间隔时间,所以就只能把目光盯向了Intouch和设备之间的MB3180网关。

在查询了网关的说明书后,发现其有如下参数-帧间延迟(Inter-frameDelay),其说明如下:InModbusRTUslavemode,usercandeterminethetime-deltto0.即在RTU模式下,用户可以修改此参数设定MB3180网关转发从站响应报文的延迟时间.默认情况下该参数为0,这里我们把它修改成100.然后测试,问题得到解决。

C.后记:
现场通信缓慢是个非常令人头疼的问题,除了软件因素,硬件问题如终端电阻不接/接错位置,屏蔽层触碰数据线,通信接头接触不良等都可能造成类似的故障现象。不过,再复杂的问题,只要有心,一步一步假设、试验、排除,终归是可以解决的。
免责声明:本文章如果文章侵权,请联系我们处理,本站仅提供信息存储空间服务如因作品内容、版权和其他问题请于本站联系