故事作者:老兵veteran

最近创作

看看TA的故事

【晒帖Go】MODBUS-RTU通讯有小坑,但可以迈过去

已锁定

老兵veteran

  • 帖子

    9991
  • 精华

    506
  • 被关注

    574

论坛等级:至圣

注册时间:2004-03-11

钻石 钻石 如何晋级?

【晒帖Go】MODBUS-RTU通讯有小坑,但可以迈过去

4188

21

2023-06-14 17:04:20

     在Profinet等一众基于工业以太网技术的通讯标准大行其道时,我本以为串口通讯,尤其是modbus-rtu这种通讯已经没有什么市场了。但是,在疫情严重的去年,却与Modbus-RTU不期而遇。

      一个很小的控制系统:S7-200SMART CR60控制两台第三方的变频器(去年,西家的变频器货期及价格都让人瞠目)。虽然S7-200SMART CR60本身带PN通讯接口,但是囿于芯片缺乏,第三方的变频器的PN通讯卡也无法保证货期;幸好变频器本身是标配了支持MODBUS-RTU通讯的串行接口的。于是也只能测试MODBUS-RTU通讯了。

         这种通讯方式,我以前是没有接触过的,于是准备好S7-200SMART的手册及第三方变频器的手册,从零开始测试。

         首先定义通讯口,波特率,奇偶校验等,在下面的例子中,定义波特率为115200BPS,偶校验,PLC集成的RS485通讯口,溢出时间1000ms。

    然后,右键点击“程序块”,在弹出的菜单中点击“库存储器……”,再在弹出的画面中分配VB缓冲区给MODBUS-RTU通讯用。这里可以用系统建议的地址。需要286个字节。

 

如下:

        


       

       在这里,重要的是定义”MBUS_MSG”中的Addr。如果子站也是西门子的PLC,则按手册中的I/0对应就可以。

       但是,我用的是某川的MD480变频器,则这个地址需要读取的是S7-200SMART中描述的保持寄存器地址,即40001-49999;400001-465535。而且,这里面有个规则 ,40001及400001分别是两个缓冲区的起启地址,比如,某川MD480中的状态字为3000H,则对应的地址为3000H转换成的十进制数:12288,这个数,如果+40001,则大于49999,所以,不能用40001做起始地址,要用400001,所以,如上图所示,某川MD480内的3000H地址,对应到S7-200Smart,则为400001+12288=412289。

同理,如果是某川中变频器中的2000H(控制字),则对应S7-200SMART中的地址为8192+40001=48193。

         这里,有一个问题,因为某川MD480变频器的控制字的有效状态为1~7,如果超出这个范围,比如设置为0,则在PLC侧写入这个值时,会返回一个”103”的代码,表示:从站不支持数据类型:从站设备不支持“地址”(Addr) 类型“。实际上,这个代码的含义应该是写入从站不认识的内容。

       另外,200SMART与从站用MODBUS_RTU通讯时,一定要用轮询的方式编程,也就是说下一条读/写指令一定要在上一条读/写指令完成以后才能启动。这里的轮询不能用定时,因为每次读写的时间周期是不固定的。

       也就是说,要用当前读/写完成的那个状态位去复位本读/写使能指令,并去启动下一条读/写指令。

      具体可看西门子官方提供的程序。Modbus_Master_Test.smart

        在具体测试时发现,波特率并不是越高越好。高波特率对EMC及通讯介质的要求都比较高,否则会丢包,导致轮询的时间过长。实际测试,两个从站,6条读写指令,用115200的波特率,轮询一周期的时间从32ms到1300ms不等。而把波特率降到9600时,则轮询时间基本在130ms.。最终,在两个从站6条读写的情况下,个人感觉19200波特率比较合适,轮询一周的时间可以稳定的保持在100ms之内。

        对于令牌轮询这种方式,还有一个最大的问题是当一个站丢失时,会导致轮询周期大大增加。还以上面的案例测试,当一个站丢失时,轮询周期高达9秒多。这是不可忍受的。所以,这种通讯方式,真的不好。解决的方案好像也只能是用程序判断:如果发现有从站丢失,就只能把这个站屏蔽点。但这并不是解决的好办法。

         后来,查找西门子官方的一个关于200SMART的各种疑难问答,提到可以在符号表中找到mModbusRetries这个变量所对应的地址(路径如下:符号表--à库--àModbus RTU Master(v2.0)),这个变量的意思是在从站不应答的情况下,重试的次数,默认值是2。把这个值改成0后,按以上的条件实测,轮询周期基本上是3073ms。后来,又看到紧邻这个变量的下一个变量是mModbusRxTimeout,这个变量的注释很简单:message timeout (word),默认值是1000,感觉单位是ms,试着把这个值改成100后,轮询周期就变成375ms上下了。再改成50,轮询周期就保持在220ms上下了。这基本能满足要求。

        但是,这样还有一个问题,那就是当重试次数改成0,溢出时间改成50ms后,监控发现在对从站进行写操作时,会有写不成功的现象。而且还比较频繁。

        后来,发现把重试次数改成1,溢出监控时间改成20,在人为去掉一个从站的情况下,轮询监控周期最大为280ms,也算差强人意。

        而在所有从站都在线的情况下,没有丢从站的现象发现,最大轮询周期为130ms(大部分情况下,在100ms之内),算是最优组合吧。

 

 

      结束语:对于响应要求不高的系统来说,MODBUS-RTU无疑是一种物美价廉的解决方案,整个流程认真测试下来,有坑,但不大,可以接受。


【晒帖Go】MODBUS-RTU通讯有小坑,但可以迈过去 已锁定
编辑推荐: 关闭

请填写推广理由:

本版热门话题

网友专栏

共有3364条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

  • 分享

  • 只看
    楼主

top
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。