Modbus在综合监控系统应用中常见问题探讨
1. 引言 >
目前我国城市轨道交通正进入建设高峰期,综合监控系统(ISCS)作为新技术之一,其实现资源共享、各专业协同工作的优势,使其越来越受重视,已成为新建线路必不可少的自动化系统。
综合监控系统通常集成与互联以下系统:火灾自动报警系统(FAS)、环境与设备监控系统(BAS)、电力监控系统(PSCADA)、综合安防系统(ISDS)、乘客资讯系统(PIS)、自动售检票系统(AFC)、通信系统综合网管系统(TEL)、广播系统(PA)、屏蔽门系统(PSD)、信号系统(SIG)、不间断电源(UPS)、时钟系统(CLK)等等。
Modbus协议以其侦错能力强、数据传输量大、实时性好、实现简单和应用普遍等特点成为ISCS系统集成与互联的主要通讯协议。
2. Modbus简介 2.1 Modbus协议
Modbus协议是MODICOM公司开发的一个为很多厂商支持的应用于串口通讯上的通用语言和标准,定义了一个通用的消息结构,描述了主机控制器访问其它设备的过程,如何回应请求,以及怎样侦测错误并记录。
Modbus使用主从查询通讯方式,即仅主站能初始化传输,从站根据主站提供的查询请求做出相应应答。ISCS集成平台常做主站,子系统为从站。主站可单独和从站通信,也可以广播给所有从站。如果单独通信,则从站必须响应,如果主站广播,则从站不作任何回应。MODBUS RTU常用功能码如表1所示,帧格式如表2和表3所示。
表1 MODBUS协议常用功能码
功能码 | 功能描述 | 读写属性 | 备注 | |
0x01 0x02 | 按位读取多个开关量状态 | 读 | 8个开关量合并为1个Byte | |
0x03 0x04 | 读取多个寄存器数值 | 读 | 1个寄存器占2个Byte,高字节在前,低字节在后 | |
0x05 | 写入1个开关量状态 | 写 |
| |
0x06 | 写入1个寄存器数值 | 写 |
| |
0x0F | 按位写入多个开关量状态 | 写 | 8个开关量合并为1个Byte | |
0x10 | 写入多个寄存器数值 | 写 | 1个寄存器占2个Byte,高字节在前,低字节在后 | |
表2 MODBUS RTU读数据帧格式
请求帧 | 设备地址 | 功能码 | 寄存器起始地址 | 寄存器数量 | CRC检验位 |
1Byte | 1Byte | 2个Byte, 高在前,低在后 | 2个Byte, 高在前,低在后 | 2个Byte, 高在前,低在后 | |
响应帧 | 设备地址 | 功能码 | 数据长度 | 数据区 | CRC检验位 |
1Byte | 1Byte | 1Byte | n个Byte, 高在前,低在后 | 2个Byte, 高在前,低在后 |
表3 MODBUS RTU写数据帧格式
请求帧 | 设备 地址 | 功能码 | 寄存器 起始地址 | 寄存器数量 | 数据 长度 | 数据区 | CRC检验位 |
1Byte | 1Byte | 2个Byte, 高在前,低在后 | 2个Byte, 高在前,低在后 | 1Byte | n个Byte, 高在前,低在后 | 2个Byte, 高在前,低在后 | |
响应帧 | 设备 地址 | 功能码 | 寄存器 起始地址 | 寄存器数量 |
|
| CRC检验位 |
1Byte | 1Byte | 2个Byte, 高在前,低在后 | 2个Byte, 高在前,低在后 |
MODBUS TCP具有MODBUS不具备的优点:通讯速率提高到GB水平,稳定性好;从站可以多主站访问;主站可以访问的从站数量大幅增加;方便接入现有局域网等。该协议已经得到越来越广泛的应用。
3. Modbus协议在ISCS应用中的常见问题
3.1 从站限制主站每次请求的寄存器数量
在ISCS与互联系统通讯中,ISCS系统常规配置为Modbus主站,互联系统设为从站。双方在通讯测试前,通常就已经约定好所有通讯内容,例如:ISCS系统监视车站公共区的乘客资讯显示屏运行状态,假设共有16块显示屏,‘1’表示运行正常,‘0’表示关机,即:ISCS主站可以通过1条请求指令将16块显示屏运行状态一次读取完成,因此开发人员在接口软件中只完成了对这条指令的响应,但到了现场却不能正常通讯。
这往往由于忽略了如下问题所致:大多数上位监控SCADA软件通过Modbus协议访问1个设备时,首先请求第一个寄存器以判断双方的通讯链路是否保持畅通。如果主站得到设备的正确应答,则再次请求其余多个寄存器;否则主站认为设备不在线或者通讯故障,不再请求其他数据。因此上述例子中,从站设备只对1次请求16个寄存器的请求帧作出应答而对请求第一个或者其他寄存器的请求回复“请求报文错误”响应或不做应答,上位SCADA监控软件始终认为设备不在线而无法正常通讯。这就要求从站设备能完全实现Modbus协议的读/写功能码,不限制主站每次请求的寄存器数量。
3.2 高低位字节定义不一致
Modbus协议规定数据帧中字的发送顺序为:高字节在前,低字节在后。但在实际应用中,由于开发工具或者操作系统对字的定义有所不同,经常导致数据帧中高字节和低字节顺序与Modbus协议规定不符合。
这种情况下,只需要在开发功能模块时调整寄存器高低字节顺序即可。
3.3 浮点表示方法不一致
Modbus协议中未对浮点数的发送方式作出明确约定,在实际应用中经常出现主站和从站对浮点数处理方式不一致的情况,目前通常采用如下2种方式处理浮点数:
(1) 采用2个寄存器保存1个浮点数:将浮点数的整数位保存在1个寄存器中,按照实际工况对小数位数的精度要求将小数位扩大n整数倍后保存在下一个寄存器中。主站获得这2个寄存器数据后,再通过适当计算得到实际的浮点数。这种方式从站实现简单,但增加了主站工作量。
(2) 按照IEEE 754标准表示浮点数,即:在单精度时,V=(-1)^s*2^(E-127)*M;在双精度时,V=(-1)^s*2^(E-1023)*M。符号定义如表5所示:
表5 IEEE 754标准浮点数定义
类型 | 数符(s) | 阶码(E) | 尾数(M) | 总位数 | 十六进制偏移值 | 十进制偏移值 |
单精度 | 1位 | 8位 | 23位 | 32位 | 0x7FH | +127 |
双精度 | 1位 | 11 位 | 52位 | 64位 | 0x3FFH | +1023 |
单精度浮点数为4字节占2个寄存器,双精度浮点数为8字节占4个寄存器。目前已有的操作系统和绝大多数开发工具均已实现IEEE 754浮点数表示方式,即:Modbus工程人员不必通过代码实现IEEE 754标准,只需要调用浮点数的系统内存表示即可。因此建议Modbus通讯双方均按照此标准表示浮点数,避免自定义浮点表示方法。
3.4 Modbus TCP/IP的出现
Modbus协议是运行在RS485或者RS232总线上的串口协议,在实际应用中由于接口计算机的串口数量限制,不能接入多条串口总线,因此经常需要使用串口以太网转换设备将多条RS485总线汇集转换成1路以太网后再接入主站网络接口。由此物理链路上的变化导致很多新接触Modbus协议的工程师误认为:通过RS485总线转以太网设备后,即实现了Modbus TCP协议。
其实,RS485总线转以太网设备的功能只是遵循TCP/IP协议规范将RS485总线上的Modbus数据帧增加了TCP数据帧头和帧尾后发送至主站网络接口,通常称这种数据格式为Modbus TCP/IP,其有效数据仍是满足表2或者表3的数据格式,即:这种数据包不满足Modbus TCP协议规范,而正确的Modbus TCP数据帧应满足表4的数据格式。这种错误也是由于对协议概念理解不够所致。
3.5 将保持和输入寄存器定义为字节数据
Modbus协议中,1个保持或输入寄存器用2个字节表示。在实际工程应用中有些互联系统为了数据表示的方便或者节省网络流量,将保持和输入寄存器长度定义为1字节或者4字节,这与规范相背,并且不通用。即使有些互联系统可以通过外部配置灵活修改寄存器长度,笔者也不推荐这种方式。
协议即为标准则需遵循。这种方式不仅违背了Modbus协议,也增加了接口调试难度,更不利于标准在行业内的推广应用和普及。
3.6 将报文地址作为应用层寄存器地址
应用Modbus协议时,另外一个常见问题是将报文地址和应用层寄存器地址混淆。
在数据报文中,所有的Modbus地址都是从0开始,也就是首次出现的数据项在报文中的地址为0。比如:“线圈1”在Modbus报文的地址域中的地址为0x0000;“线圈127”的报文地址为0x007E(十进制的126);保持寄存器40001的报文地址为0x0000;保持寄存器40108的报文地址为0x006B(十进制107)。
在应用层面,上位SCADA组态软件的地址设置一般是从地址1开始,连续若干个。在数据报文层面,寄存器起始地址从0开始。例如从设备17读40001开始的2个寄存器数据的请求报文为:
设备地址 | 功能码 | 寄存器起始地址 | 寄存器数量 | CRC检验位 |
0x11 | 0x03 | 0x0000 | 0x0002 | 0xC69B |
因此在Modbus协议应用过程中,应当注意报文地址和寄存器地址的差异,避免出现从站响应报文中寄存器数据与主站实际请求的寄存器地址不对应的情况。
3.7 SCADA软件与设备写寄存器命令的不匹配
常用Modbus寄存器有:线圈(Coil)、输入(Input)、保持寄存器(Holding Registers)和输入寄存器(Input Registers)。
从Modbus设备角度看,输入是上位机采集Modbus设备的信息,即这些寄存器是只读的,所以,Modbus协议没有写输入(对应Modbus设备的开关量输入DI)和输入寄存器(对应Modbus设备的模拟量输入AI)的命令。线圈是状态量,对应Modbus设备的开关量输出(DO);保持寄存器是模拟量,对应Modbus设备模拟量输出(AO),这些寄存器需要主站上位机进行设置,也就是这些寄存器是主站可写的寄存器。
在Modbus协议中,写线圈和保持寄存器都有两种写命令:
(1) 写单个寄存器:强制单线圈,功能码0x05;写单个寄存器,功能码0x06;
(2) 写多个寄存器:写多线圈,功能码0x0F;写多个寄存器,功能码0x10。
在ISCS系统实际调试过程中,测试发现某些互联系统支持写操作不全面,例如针对保持寄存器,只支持0x06功能码或者只支持0x10功能码,这样上位主站就不能根据需要灵活选择功能码。因此从站设备必须全面实现Modbus协议的写操作。
另外一个常见问题是:从站收到主站的写命令后不返回应答报文,这样主站上位机就不能确定这次写操作是否成功。因此从站设备必须严格按照Modbus规范的约定对主站的命令均作出响应,不论是读命令还是写命令。
4. 结束语
ISCS互联系统主要通过现场控制设备(PLC、网关等)或者接口计算机提供Modbus功能接口,其实现方式大多为针对项目的现场开发,是出问题最多的环节。笔者遇到的问题也多是在这个环节发现。本文通过对项目实施中常见问题归纳、分析,以期对综合监控系统从业者以帮助。
提交
超越传统直觉,MATLAB/Simulink助力重型机械的智能化转型
新大陆自动识别精彩亮相2024华南国际工业博览会
派拓网络被Forrester评为XDR领域领导者
智能工控,存储强基 | 海康威视带来精彩主题演讲
展会|Lubeworks路博流体供料系统精彩亮相AMTS展会