Modbus RTU通信调试经验整理

1、前言

这次的项目采用西门子SMART S7-200 SMART,其中涉及到通过RS485串口,用Modbus RTU通信协议与外设通信,在此记录一下学习到的内容。已经了解Modbus RTU协议的话可以直接看调试问题和解决办法。
关于通信实例可以查看这篇博客:S7-200PLC采用modbus RTU轮询和读写信息

2、Modbus RTU通信协议介绍

2.1 Modbus介绍

Modbus是一种串行通信协议,是工业电子设备之间常用的连接方式。
优点:
1.公开发表并且无版权要求
2. 易于部署和维护
3. 对供应商来说,修改移动本地的比特或字节没有很多限制

Modbus协议是一个master/slave架构的协议。有一个节点是master节点,其他使用Modbus协议参与通信的节点是slave节点。每一个slave设备都有一个唯一的地址。在串行和MB+网络中,只有被指定为主节点的节点可以启动一个命令。

一个ModBus命令包含了打算执行的设备的Modbus地址。所有设备都会收到命令,但只有指定位置的设备会执行及回应指令(地址0例外,指定地址0的指令是广播指令,所有收到指令的设备都会运行,不过不回应指令)。所有的Modbus命令包含了检查码,以确定到达的命令没有被破坏。基本的ModBus命令能指令一个RTU改变它的寄存器的某个值,控制或者读取一个I/O端口,以及指挥设备回送一个或者多个其寄存器中的数据。

2.2 Modbus RTU(远程终端模式)模式通信

MODBUS RTU信息帧
在这里插入图片描述在这里插入图片描述
整个报文帧必须以连续的字符流发送。
两个字符之间的停顿时间间隔超过1.5个字符时,信息帧认为不完整,接收方不接收此信息帧。

MODBUS RTU CRC校验
在RTU模式包含一个对全部报文内容执行的,基于循环冗余校验(CRC)算法的错误检测域。
CRC域检查整个报文的内容,不管报文有无奇偶校验,均执行此校验。CRC域包含由两个8位字节组成的一个16位值。采用CRC16校验。低字节在前,高字节在后。

3、Modbus调试出现的问题以及解决办法

3.1硬件连接

我采用的是RS485串口通信,两线制连接,通信协议采用Modbus RTU,。硬件连接就是将RS485网络上的设备并联在一起。这种接线方式为总线式拓朴结构在同一总线上最多可以挂接32个结点。
在这里插入图片描述
由于我做的项目需要的连接距离非常短,而且也只是在实验室进行研发设计,所以只连接了A线和B线,用细导线简单并联在一起就可以了,用不到中继器(有些外设就只给了RS485A线和B线,没有地线。)
如果是长距离的传输的话,对于接线的要求比较高,可以参考下面的文档。
VC2L_RS485总线设备布线规范

硬件连接出现的问题:A,B线接错

RS485连接有交叉连接和直连的区别。直连就是RS485 A接A,B接B。而交叉连接就是RS485 A接B,B接A。之所以有这种区分,是不同厂家对于信号线的正负定义不同。
RS485接口由两根线组成:信号正(+)和信号负(-)。通常,信号正(+)被称为A线,信号负(-)被称为B线。但有例外,比如,西门子产品中,RS485中的B线是信号正(+),A线是信号负(-),要注意区分。
西门子PLC与其他设备通过RS485连接,通常都是交叉连接的,在我知晓这一点之前,浪费了不少时间排查通信故障。

解决方法:
1、交换A,B线连接,看问题是否解决
2、如果问题没有解决,就采用Modbus主站/从站设备模拟工具来检查发送或收到的信号是否正常。
推荐Modbus Poll和Modbus Slave。
在这里插入图片描述
以Moudus poll为例子,设定连接参数
在这里插入图片描述
设定从站地址,功能,数量
在这里插入图片描述
设备的通信记录。可用来观察发送和收到的未经过解析处理的信息。
在这里插入图片描述

3.2参数设置出现的问题

检查硬件连接没有问题之后,就检查参数设置,例如波特率,数据位位数,数据校验方式,停止位位数,通信设备地址,寄存器地址,长度,读写方式。
1、确认通信设备地址,一般查询手册里出厂的默认设备地址。
2、寄存器地址注意转换。寄存器地址从0开始,而PLC地址从1开始,十进制,并且在最高位需要加一个代表寄存器属性的数值。例如读取保持寄存器,手册给出的寄存器地址是0(十进制),那么对应的PLC地址是40001(十进制),首位的4代表这是保持寄存器。例如读取保持寄存器,手册给出的0x3000的寄存器地址,那么对应的PLC地址是412289(十进制)。总结下来就是:转换为十进制,加一,加前缀。
3、注意功能码的选择,写单寄存器和写多重存储器的功能码是不同的。而西门子的Modbus库模块是自动根据数据长度选择写单存储器和多重存储器的功能码,但是也会碰到例外情况。我这次项目就遇到一个设备,明明要写的寄存器数量只有1,但是偏偏功能码要求0x10(写多重存储器),PLC按照写单存储器发送的命令它不接受,必须用0x10的功能码来写单寄存器。后来检查了一下,那个地址后面连着的一个寄存器它不使用,就将写寄存器的数量改为2,修改了一下发送的数据,解决了这个问题。

3.3Modbus编程出现的问题

我是用西门子Smart 200 PLC的Modbus RTU库来编程的。关于编程出现的常见问题和解决方法可以查阅S7-200 SMART PLUS,里面有详细的例子和说明。可以查看错误代码,确定可能的错误原因,常见的错误代码6是同时激活了多条Modbus_MSG指令导致的,建议按照示例来写,不容易出错。如果是错误代码3,建议检查硬件和参数设置,参考前两节。
另外,设置的等待时间不要太短,时间太短的话从站来不及相应,也会出错。

3.4读取到的数据转化

PLC读取到的数据如果乱码,那可能是需要转换字节序,需要查看厂家对于设备字节序的设置。例如这次项目里的外设1,读取连着两个寄存器里的浮点数,读取到的数据必须前后两个字调换一下位置,才是正确的浮点数格式。而这次项目里的外设2,也是读取两个连着的寄存器里的浮点数,读取到的数据必须将4个字节的顺序颠倒一下,才是正确的浮点数格式。
建议遇到这种情况,查询手册看有没有说明,或者是看有没有寄存器存放常数,读取寄存器内的常数,和这个常数转化成的HEX码比较一下顺序,或者就换着顺序试试看能不能读出正常的值。


版权声明:本文为weixin_42165647原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。