Modbus 是什么,会在哪些设备上遇到
Modbus 是 1979 年 Modicon 为自家 PLC 定的一套主从式通信协议, 因为规范公开、实现简单,后来成了工业现场事实上的通用语言。 它的数据模型只有四个区:线圈(可读写位)、离散输入(只读位)、 保持寄存器(可读写 16 位字)、输入寄存器(只读 16 位字), 对应功能码 01/02/03/04 读,05/06/0F/10 写。整个协议没有数据类型、没有单位、 没有变量名——这既是它简单的原因,也是所有现场问题的根源。
在数采项目里,几乎每个现场都会遇到 Modbus 设备:
国产 PLC(汇川、信捷、台达、禾川等)多数把它作为默认的对外接口;
变频器与伺服驱动器用它读电流、转矩、频率与报警字;
温控表、称重仪表、压力/流量变送器、气体检测仪、环境监测模块基本只有 Modbus;
智能电表除了 DL/T 645 也常提供 Modbus;
还有大量国产的智能仪表与传感器模块,铭牌上写的通信方式就是 RS485 Modbus-RTU。
敏洽 SCADA 数采软件
为 Modbus 提供了 modbus_tcp、modbus_rtu、
modbus_rtu_over_tcp、modbus_ascii、modbus_udp
五个独立驱动,串口类驱动自动独占线程,避免多个实例抢同一个串口。
五种变体怎么选
| 驱动 | 承载与校验 | 什么时候用它 |
|---|---|---|
modbus_tcp | TCP/502,MBAP 帧头,无 CRC | 设备有网口且明确支持 Modbus TCP。首选,最省事 |
modbus_rtu | RS485/RS232,CRC16 | 设备只有串口,且采集端(工控机或网关)就在柜内或附近 |
modbus_rtu_over_tcp | TCP 透传 RTU 原始帧,保留 CRC | 485 设备经串口服务器接到以太网。老站改造最常用 |
modbus_ascii | 串口,ASCII 编码,LRC 校验 | 部分早期温控表与称重仪表只支持 ASCII 模式 |
modbus_udp | UDP 承载 | 少数设备只开 UDP;对时延敏感且能容忍偶发丢包的场合 |
最容易配错的是 RTU over TCP 与 Modbus TCP:
两者都是「往 TCP 连接里发 Modbus」,但帧格式不同——
前者是带 CRC 的 RTU 帧,后者是带 MBAP 头不带 CRC 的 TCP 帧。
串口服务器工作在透传模式时给出的是 RTU 帧,必须用 modbus_rtu_over_tcp;
部分串口服务器有「协议转换」模式,能把 Modbus TCP 翻成 RTU,
这时候采集侧才用 modbus_tcp。配错的现象是连接能建立、发出去没有正确应答,
很容易被误判成设备不通。
实际会遇到的几个坑
1. 地址基准:4xxxx 编号与报文偏移量差 1
手册写 40001,报文里发的是 0。这套 4xxxx 编号来自早期 Modicon 文档, 4 表示保持寄存器区,后面五位从 1 开始编号;而协议报文传的是从 0 开始的偏移量。 各家手册在这一点上写法不统一,甚至同一份手册前后不一致。 症状是所有数据整体错开一个位置, 如果相邻地址的数据类型相同,读出来的数看着都合理,能一路错到验收。 判断动作:找一个已知会变的点(产量计数器最好用), 让设备动作一次,看变化落在哪个地址上,以此校准整张点表的基准。
2. 寄存器区选错:03 码与 04 码
保持寄存器(功能码 03)与输入寄存器(功能码 04)是两个独立的地址空间, 地址 100 在两个区里是完全不同的数据。很多仪表把测量值放在输入寄存器、 把参数放在保持寄存器,手册里只写「寄存器 30001」这类编号, 3xxxx 才是输入寄存器区,4xxxx 是保持寄存器区。选错的表现分两种: 设备严格实现协议时返回非法数据地址异常(异常码 02),比较好查; 设备实现得松散时直接把另一个区的值给你,就变成上一条那种「不报错但数值不对」。 同理还有线圈(01)与离散输入(02)这一对。
3. 32 位数与浮点数的字序有四种排列
Modbus 的寄存器是 16 位,32 位整数与单精度浮点占两个寄存器, 但协议没规定哪个寄存器放高位,加上寄存器内字节序也可能翻转, 实际会遇到四种排列。症状是数值的数量级完全不对,或者小数点位置离谱, 有时甚至读出 NaN。 正确做法是用一个已知值反推: 把计数器置到 1000,或者读一个已知量程的模拟量,四种排列各算一遍, 能对上的那一种就是设备的字序。确认后必须写进点表, 同一台设备上不同厂家的模块字序还可能不一样。 同类问题还有有符号与无符号:温度这类可能为负的量按无符号解析, 零下就变成六万多。
4. 一次读多少:单次请求的寄存器上限与批量读
Modbus 单次读保持/输入寄存器最多 125 个(读位最多 2000 个), 超出会返回非法数据数量异常。更实际的问题是请求次数: 如果点表里的地址东一个西一个,采集侧就得发很多次请求, 485 上每次请求都要等应答,节拍立刻上去了。 解决办法是在项目初期就要求设备厂 把需要外发的数据整理到一段连续的寄存器区, 采集侧一次批量读完再在本地拆分。这属于设备厂改 PLC 程序的工作量, 要在接口确认阶段提出来,不能等联调时才说。 另外有些设备虽然协议上支持 125 个,实际读超过一定数量就超时, 这种只能实测找出安全值。
5. 485 总线的物理问题:接反、无终端电阻、与动力线同槽
串口类 Modbus 的故障里,相当一部分根本不在协议层。 A/B 两根线接反是最高频的,现象是完全没有应答, 不报错也不返回错帧,和线没接一样,不确定就直接对调试一次。 其次是拓扑:485 必须手拉手串接,不能星形分叉; 总线两端各需一个 120Ω 终端电阻,距离长、波特率高时缺电阻会造成随机误码; 屏蔽层单端接地。最难查的是与动力线、变频器输出线同槽走线, 表现是平时好用、大功率设备启停时集中报错, 这种「时好时坏」几乎总被先怀疑成软件问题。
6. 从站地址、波特率与帧参数四件套不匹配
串口 Modbus 需要从站地址(1~247)、波特率、数据位、停止位、校验位全部一致, 任何一项不对都是没有应答。这里的坑是: 设备铭牌上的资产编号不是从站地址, 从站地址往往要在设备面板菜单里查或改; 一条总线上两个设备用了同一个从站地址时, 两台会同时应答造成帧冲突,现象是间歇性 CRC 错误, 比完全不通更难查。上线前应该逐台确认地址唯一。
7. 瞬时值与件级结果:必须有锁存和握手
采集端按周期轮询,寄存器里的值随时在变。 如果要的是件级数据(这一件的测量值、这一件的判定结果), 直接轮询瞬时寄存器一定会漏件或读到中间态,节拍快的工站尤其明显。 正确做法是让 PLC 在每件完成时把结果 锁存到固定寄存器,同时把一个序号或握手位加一, 采集侧监视序号变化再读结果区,读完回写确认。 这套机制要写进接口文档,由设备厂电控工程师在 PLC 程序里实现。
接入方式与硬件条件
| 项目 | 要求与说明 |
|---|---|
| 首选接法 | 设备支持 Modbus TCP:网线直接接入,驱动用 modbus_tcp,端口默认 502 |
| 串口接法 | 485 直连采集端用 modbus_rtu;经串口服务器透传用 modbus_rtu_over_tcp |
| 串口参数 | 从站地址、波特率、数据位、停止位、校验位五项须与设备一致,且总线内地址唯一 |
| 485 布线 | 手拉手串接、屏蔽双绞线、两端 120Ω 终端电阻、屏蔽层单端接地、与动力线分槽 |
| 寄存器规划 | 要求设备厂把外发数据集中到连续区,单次读不超过 125 个寄存器 |
| 并发限制 | 485 只允许一个主站;Modbus TCP 需确认设备并发连接数上限,建议只保留一路采集 |
| 件级结果 | 需 PLC 侧锁存 + 序号/握手位,采集侧按序号变化触发读取并回写确认 |
| 点表必备字段 | 名称、功能码/寄存器区、地址(注明是否 4xxxx 基准)、数据类型、字序、缩放系数、单位、位与枚举含义、更新频率 |
需要客户或设备厂准备的硬件是:设备侧的通信口(可能要加通信扩展模块)、 串口服务器(485 转以太网方案)、以及交换机端口与 IP 规划。 串口服务器与网关型号敏洽可以给建议, PLC 程序侧的寄存器规划与握手逻辑由设备厂的电控工程师实现。
相关交付情况
Modbus 现场的经验是:协议本身几乎不花时间, 全部工作量在点表质量与总线条件上。 所以敏洽的做法是项目一开始先发一份点表模板, 把功能码、地址基准、字序、缩放系数、位含义这些容易漏的列预置好, 由设备厂填完再评估工作量。 带调试面板的驱动可以在软件里直接发原始报文、看返回字节、逐点核对, 不需要另外准备第三方调试工具,联调阶段能省掉不少来回。
国产 PLC 的软元件与 Modbus 地址映射差异见 汇川、信捷、台达 PLC 采集; 只有串口甚至没有接口的老设备见 老旧设备联网; 读不到数据的排查顺序见 数据取不出来怎么排查。
常见问题
有具体设备清单或工件样品,可以直接给判断
提供设备型号、PLC 品牌与需要采集的数据项,或提供被检工件照片与精度要求,敏洽可先给出可行性判断与硬件前置条件,再谈软件工作量与报价。