Modbus 通讯专题
工控领域最通用、最绕不开的协议。本专题把零散的教程、在线工具和软件按 「认知 → 报文 → 数据解析 → 编程 → 调试 → 工程化」 串成一条可照着走的路径,不堆手册,只讲现场真正用得上的部分。
一条路径走完 Modbus(六个阶段)
- 01
先建立整体认知:Modbus 到底是什么、在协议栈哪一层
先别急着写代码。搞清楚主从关系、RTU 与 TCP 的差别、四种寄存器和功能码,后面所有问题都是这些基础的组合。
- 主从(Client/Server)模型:一个主站轮询多个从站,从站不主动发数据
- Modbus RTU 走 RS485/232 串口、二进制 + CRC16;Modbus TCP 走以太网、用 MBAP 头替代 CRC
- 四类数据区:线圈(0x)、离散输入(1x)、保持寄存器(4x)、输入寄存器(3x)
- 02
看懂并亲手拼出一帧报文:功能码与 CRC16
调试 Modbus 90% 的问题都能在报文层面定位。学会读「站号 + 功能码 + 地址 + 数量 + CRC」,并用工具验证。
- 常用功能码:03 读保持寄存器、04 读输入寄存器、06 写单个、16(0x10) 写多个
- 异常响应 = 功能码最高位置 1(如 03→83)+ 异常码,先学会识别
- RTU 帧尾 CRC16(低字节在前),算错一个字节整帧丢弃
配套工具: Modbus CRC16 校验与报文工具 → - 03
读懂寄存器里的数:字节序、浮点与数据类型
一个 32 位浮点数占两个 16 位寄存器,不同 PLC 排列顺序不同——这就是「数值明显不对、大得离谱」的根源。
- 32 位数据存在 ABCD / CDAB / BADC / DCBA 四种字节序,与 PLC 侧对齐即可
- 16 位整数还要分清有符号/无符号,模拟量常见
- 字符串、32 位整型同理,按字节拼回
配套工具: IEEE754 浮点 / 字节序转换 → - 04
写代码稳定读写:合并地址、批量读取与轮询优化
真正做项目,别一个点一个点地读。把连续地址合并成一次请求、按变化快慢分组轮询,通讯效率差几倍。
- 连续地址用一次 03/04 批量读,避免几十次往返
- 非连续地址做分组与「读最大区间后本地取点」的取舍
- 轮询节奏:快变量高频、慢变量低频,留出余量
- 05
现场调试与抓包:先用主站工具证明「设备是好的」
上位机连不上时,先别怀疑自己的代码。用标准主站工具直连、用抓包看线上到底发了什么,快速界定是设备、接线还是程序问题。
- Modbus Poll 当主站直连从站,验证地址、功能码、字节序
- QModMaster 是开源替代;从站侧可用仿真器自测
- Wireshark 抓 TCP/串口转以太网报文,看超时、异常码、重传
- 06
工程化落地:断线重连、多协议驱动与规模化采集
从「能连上」到「长期稳定跑」,要解决断线恢复、协议扩展和几十上百台设备的架构问题——这正是工程经验的分水岭。
- 心跳 + 超时重试 + 指数退避重连,区分设备故障与链路中断,恢复后补读
- 用「驱动工厂」隔离协议,新增 Modbus/MC/S7 不改主程序
- 设备多、协议杂时,用边缘网关/低代码采集替代手写,分层解耦
边学边用:两个免费在线工具
Modbus 相关软件选型(按用途分组)
Modbus 常见问题
Modbus RTU 和 Modbus TCP 有什么区别,新项目怎么选?
RTU 走 RS485/232 串口,报文二进制、帧尾带 CRC16 校验,一主多从、成本低、布线距离远但速率有限;TCP 走以太网,用 7 字节 MBAP 头替代 CRC,速度快、可跨网段、并发能力强。新设备联网、上位机采集优先选 TCP;现场老旧设备、总线布线用 RTU;两者可用网关做 RTU↔TCP 转换,上层统一按 TCP 采集。
03、04、06、16 这些功能码分别是做什么的?
03 读保持寄存器(4x,可读写区,最常用)、04 读输入寄存器(3x,只读采集区);01 读线圈、02 读离散输入对应位操作。写操作里 06 写单个保持寄存器,16(十六进制 0x10)写多个保持寄存器;05 写单个线圈、15 写多个线圈。做模拟量采集主要用 03/04,下参数用 06/16。
为什么读出来的浮点数是乱的、数值大得离谱?
一个 32 位 IEEE754 浮点数要占两个连续的 16 位寄存器,两个寄存器的先后、以及每个寄存器内部两字节的先后组合起来有 ABCD/CDAB/BADC/DCBA 四种字节序。上位机默认顺序和 PLC 不一致就会得到乱数。用本站的 IEEE754 工具把四种排列都算一遍,对上现场量程的那个就是正确字节序,之后固定即可。
轮询周期设多少合适?一个主站能带多少从站?
取决于物理层速率、单帧长度和从站数量。RTU 在 9600bps 下一轮读写通常要几十到上百毫秒,从站越多周期越长,不要无间隔连续发帧;TCP 快得多但也要给设备处理留余量。工程上按数据变化快慢分组轮询(关键量高频、统计量低频),并把连续地址合并成一次批量读取,比逐点读取效率高很多。
Modbus 经常超时、时断时续,怎么从根上解决?
先分层定位:接线/终端电阻/波特率奇偶校验(RTU)、IP 和端口(TCP)、站号与功能码是否正确。程序层面要设合理超时与有限重试、失败后指数退避重连、用心跳判断在线状态,并区分「单个设备故障」和「整条链路中断」,链路恢复后自动补读。本站「断线重连机制」教程有完整设计。
应该自己写代码对接,还是用网关/组态软件?
设备少、协议单一、需要把通讯深度嵌进自有上位机,用 libmodbus、Apache PLC4X 这类开发库;设备多、品牌协议杂、想快速落地和少维护,用 Node-RED、Neuron、ThingsGateway、Kepware 这类配置化采集网关。无论哪种方案,联调阶段都建议先用 Modbus Poll 标准主站 + Wireshark 抓包把设备侧验证清楚。
Modbus 安全吗?能不能直接连公网?
Modbus 协议本身没有认证、没有加密,是为可信内网设计的,绝不能直接暴露到公网。应把采集网放在隔离内网、用防火墙做 IP/端口白名单;需要远程访问时走 VPN 或专线;对安全和跨平台互操作要求更高的场景,可在 Modbus 之上叠加 OPC UA。
继续往深走
Modbus 解决「怎么把数据读上来」,放到完整系统里,还要回答协议怎么选、数据怎么存、系统怎么分层: