Modbus的核心工作机制非常简单,采用的是主从通信模式。
主设备 (Master):通常是PLC、工控机或网关,是整个通信过程的发起者。它负责向特定的从设备发送请求命令。
从设备 (Slave):一般是传感器、变频器、仪表等现场设备。它们时刻监听着总线上的消息,只有当收到的消息中的地址与自己相符时,才会执行相应的操作,并回复一个响应消息。
整个过程就像老师(主设备)点名提问,被点到的学生(从设备)才站起来回答问题,其他学生则继续保持安静。这种一问一答的确定性模式,保证了工业通信的稳定有序。
Modbus协议操作的是设备内部的数据,这些数据被抽象为四种简单的表格,理解这个模型是掌握功能码的基础。
| 数据类型 | 对象类型 | 访问权限 | 物理含义举例 |
|---|---|---|---|
| 线圈 (Coils) | 位 (1 bit) | 可读可写 | 继电器输出、电磁阀开关、指示灯状态 |
| 离散输入 (Discrete Inputs) | 位 (1 bit) | 只读 | 限位开关、按钮、光电传感器的状态 |
| 输入寄存器 (Input Registers) | 字 (16 bits) | 只读 | 模拟量输入(如温度、压力传感器采集的数值) |
| 保持寄存器 (Holding Registers) | 字 (16 bits) | 可读可写 | 设备参数(如PID系数、运行阈值)、累计值 |
一个Modbus报文(无论是请求还是响应),就像一封装了指令的信。根据传输方式的不同,信封的“格式”略有差异,但核心内容是一致的。
所有Modus变体都共享一个简单的协议数据单元(PDU):
功能码 (1字节):告诉从设备要做什么(例如,功能码03代表“读保持寄存器”)。
数据 (N字节):是功能码的参数或结果。例如,对于“读保持寄存器”的请求,这里会包含要读取的起始地址和寄存器数量。
PDU被“包装”上不同的报头,以适应不同的网络环境,就形成了应用数据单元(ADU)。
| 特性 | Modbus RTU (串行通信) | Modbus TCP (以太网通信) |
|---|---|---|
| 物理层 | RS-232 / RS-485 | 以太网 |
| 报文结构 | 从站地址 + PDU (功能码+数据) + CRC校验 |
MBAP报头(7字节) + PDU (功能码+数据) |
| 寻址方式 | 从站地址 (1-247) | IP地址 + 单元标识符 (Unit ID) |
| 错误校验 | CRC-16 (报文自带) | 由TCP/IP协议栈保证 (报文中无校验) |
| 帧界定 | 通过3.5字符静默时间来区分帧的起始和结束 | 基于TCP连接,数据流本身就是完整的帧 |
| 典型端口 | - | 502 |
让我们通过一个最常用的例子,看看“读取保持寄存器”这个操作是如何完成的:
场景:主设备想要读取地址为01的从设备上,起始地址为0x006B(对应Modbus地址40108)的连续3个保持寄存器的值。
1. 主设备发送请求
根据不同的模式,主设备会构造并发送以下报文:
RTU模式请求帧:**01 03 00 6B 00 03** **F8 7D**
01: 从站地址
03: 功能码 (读保持寄存器)
00 6B: 起始寄存器地址 (高字节在前)
00 03: 要读取的寄存器数量
F8 7D: CRC校验码
TCP模式请求帧:**00 01 00 00 00 06 01** **03 00 6B 00 03**
00 01: 事务标识符 (用于匹配请求和响应)
00 00: 协议标识符 (固定为0,表示Modbus)
00 06: 后续字节长度 (从单元标识符开始算起,共6个字节)
01: 单元标识符 (相当于RTU的从站地址)
03 00 6B 00 03: 这部分就是PDU,和RTU中完全一致
2. 从设备执行操作并响应
地址为01的从设备收到请求后,从其保持寄存器40108、40109、40110中读出数值(假设分别为0x022B, 0x0064, 0x007F),然后构造响应报文发回给主设备。
RTU模式响应帧:**01 03 06 02 2B 00 64 00 7F** **F8 7D**
01: 从站地址
03: 功能码 (与请求一致)
06: 后续数据的字节数 (3个寄存器 × 2字节 = 6字节)
02 2B 00 64 00 7F: 三个寄存器的值 (0x022B, 0x0064, 0x007F)
F8 7D: CRC校验码
TCP模式响应帧:**00 01 00 00 00 07 01 03 06 02 2B 00 64 00 7F**
00 01: 事务标识符 (与请求中的匹配)
00 00: 协议标识符
00 07: 后续字节长度 (7个字节)
01: 单元标识符
03 06 02 2B 00 64 00 7F: PDU部分
功能码是Modbus指令的核心。这里列出最常见的几个:
01 (0x01): 读线圈
02 (0x02): 读离散输入
03 (0x03): 读保持寄存器
04 (0x04): 读输入寄存器
05 (0x05): 写单个线圈
06 (0x06): 写单个寄存器
15 (0x0F): 写多个线圈
16 (0x10): 写多个寄存器二、Modbus协议底层的工作原理
在谈论功能码和报文之前,数据首先得变成能够在导线上传播的物理信号。
这是Modbus RTU/ASCII最常用的物理层标准。
工作原理:使用差分信号。数据通过两根线(A和B)的电压差来传输。
逻辑"1":A线电压高于B线。
逻辑"0":A线电压低于B线。
为什么这么设计:因为传输的是电压差,外界电磁干扰对两根线的影响几乎是相同的,所以"差值"保持不变。这让RS-485具有很强的抗干扰能力和长距离传输(可达1200米以上)能力。
工作原理:使用单端信号。数据通过一根信号线与地线之间的电压来传输。
通常,-3V到-15V表示逻辑"1",+3V到+15V表示逻辑"0"。
特点:结构简单,但抗干扰性差,传输距离短(通常15米以内)。
Modbus总线上的所有设备都"听"得到主设备发出的信号,但如何确保只有正确的设备回应?
地址过滤:每个从设备在配置时都被赋予了一个唯一的地址(1-247)。从设备的物理层芯片接收所有数据,但只有当地址匹配时,其协议栈才会处理这个请求。地址0是一个特殊的广播地址,所有从设备都会接收但不回应。
这是Modbus RTU模式最核心、最微妙的工作原理。由于RS-485是半双工且没有时钟线,设备必须知道"从哪里开始读"以及"到哪里结束"。
Modbus RTU不依赖于特定的起始字符或结束字符(如ASCII模式使用:和CR/LF),而是依赖于时间。
T1.5 定时器:字符间超时
当一个从设备开始接收一帧数据时,它内部启动一个1.5字符时间的定时器。
如果在接收当前字符和接收下一个字符之间的时间间隔超过了T1.5,从设备会认为这一帧数据不完整(可能是主设备发送中断或受到干扰),它会立即丢弃已收到的部分数据,并准备接收下一帧。
T3.5 定时器:帧结束与帧开始
结束:当从设备接收完一个字符后,如果在3.5字符时间内没有再接收到新的字符,它就认为这一帧已经结束,并对已收到的完整报文进行解析处理。
开始:主设备在发送一帧数据前,必须先监听总线,确保总线空闲时间至少达到3.5字符时间,然后才能开始发送新的一帧。
为什么要有这个机制?
如果没有严格的T3.5间隔,如果两条报文连在一起,接收方无法判断报文A的最后一个字节和报文B的第一个字节,会当作一条错误报文处理。
在传输过程中,如果某个比特因为干扰从"0"变成了"1",接收方如何知道数据错了?RTU模式依靠报文末尾的2字节CRC-16。
发送方:将整个报文(地址+功能码+数据)视为一串二进制数,通过一个特定的多项式(0x8005的变体)进行循环冗余校验计算。
附加:计算出的2字节结果(CRC校验码)被附加在报文末尾发送出去。
接收方:收到报文(包含地址到CRC的所有字节)后,用同样的多项式对整串数据(包含CRC本身)再进行一次运算。
如果传输过程中没有错误,接收方计算出的余数应该是0。
如果余数不为0,说明数据在传输过程中被污染了,从设备将忽略这条报文,并且不返回任何响应(除非配置了特殊处理)。
这是一个数据从网线/串口线进入从设备CPU的完整路径:
物理层接收:RS-485芯片将总线上的差分电压转换为TTL电平的"0"和"1"数字比特流。
串口/UART处理:UART将比特流组装成字节(包含起始位、数据位、停止位),并存入接收缓冲区。
定时器监控:MCU的定时器持续监控字节间的时间间隔(T1.5和T3.5),一旦T3.5触发,通知协议栈"一帧数据收完了"。
CRC验证:协议栈对缓冲区内的数据进行CRC计算验证。
地址比对:验证通过后,取出第一个字节(地址),与自身地址比对。
功能码解析:如果地址匹配,解析功能码。如果功能码存在且参数有效,则执行操作(如读取寄存器)。
响应构造:将结果按照报文格式打包(包含地址、功能码、数据)。
物理层发送:通过UART将响应字节流转换成电压信号,发送回总线。
Modbus的工作原理也定义了"出错"的情况。如果从设备无法执行请求(例如请求读取一个不存在的寄存器),它不会直接忽略,而是返回一个异常码。
正常响应:功能码与请求一致(如03)。
异常响应:从设备将功能码的最高位设置为1(如0x83或131),然后在数据段返回一个异常码(如02表示非法数据地址)。
三、Modbus实战
根据你的需求——将一台带有多传感器、通过Modbus控制的设备接入互联网,并通过网关将数据上报至云服务器进行分析,我为你整理了一份详细的业务流程和解决方案。
┌─────────────────────────────────────────────────────────────────────────────┐
│ Modbus设备数据上云业务流程 │
└─────────────────────────────────────────────────────────────────────────────┘
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ │ │ │ │ │ │ │
│ 现场设备层 │ ──▶│ 边缘网关层 │ ──▶│ 云平台层 │ ──▶│ 应用层 │
│ │ │ │ │ │ │ │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ Step 1: 硬件连接 Step 3: 协议转换 Step 5: 数据存储 │
│ • 传感器通过继电器 • Modbus RTU/TCP • 时序数据库 │
│ 连接设备 • 转MQTT/HTTP • 设备影子 │
│ • 设备RS485接口 • 数据语义化 • 对象存储 │
│ 连接网关 (寄存器地址→物理量) │
│ • 本地缓存 Step 6: 数据可视化 │
│ Step 2: 网关配置 (断网续传) • 实时监控仪表板 │
│ • 网络接入(4G/以太网) • 设备状态看板 │
│ • Modbus主站配置 Step 4: 边缘计算 • 历史数据分析 │
│ • 采集周期设置 • 数据清洗 │
│ • 阈值告警 Step 7: 业务应用 │
│ • 聚合计算 • 异常预警 │
│ • 仅上报变化值 • 远程控制 │
│ • 预测性维护 │
└─────────────────────────────────────────────────────────────────────────────┘
你的设备通过继电器控制多个传感器,这些传感器应该都支持Modbus协议。你需要:
| 连接对象 | 连接方式 | 说明 |
|---|---|---|
| 传感器 ↔ 设备 | 继电器 | 设备通过继电器对传感器进行供电或信号控制 |
| 设备 ↔ 网关 | RS485总线 | 将设备的Modbus接口连接到边缘网关的RS485串口 |
| 网关 ↔ 互联网 | 4G/以太网/WiFi | 根据现场网络条件选择 |
关键注意事项:
RS485总线两端需接120Ω终端电阻,防止信号反射
网关与强电设备保持30cm以上距离,减少电磁干扰
网关是整个系统的核心,需要完成以下配置:
Modbus主站设置:
配置采集周期(如100ms/次)
设置Modbus从站地址(与你设备地址一致)
配置寄存器地址映射表
网络连接配置:
设置4G APN参数(如使用蜂窝网络)
或配置以太网IP地址
DNS服务器配置
这是最关键的一步。Modbus协议只传输原始寄存器值(如1024),需要转换成有物理含义的数据:
| 原始数据 | 映射规则 | 转换后数据 |
|---|---|---|
寄存器40001=1024 |
量程0-100℃,精度0.01℃ | 10.24℃ |
线圈00001=1 |
继电器状态映射 | "继电器1": "闭合" |
需要准备的映射信息:
每个传感器的Modbus寄存器地址
数据类型(16位整数、浮点数、布尔值等)
量程转换公式
采集频率
在网关上完成数据预处理,可以大幅降低云端压力和带宽成本:
| 处理类型 | 实现方式 | 效果 |
|---|---|---|
| 数据清洗 | 滑动窗口去重 | 剔除连续重复数据,只保留变化值 |
| 异常检测 | 阈值判断 | 超限数据本地标记或告警 |
| 数据聚合 | 计算均值/最值 | 5分钟聚合上传,带宽降低60%以上 |
| 本地缓存 | 2G存储空间 | 断网续传,保障数据完整性 |
网关将处理后的数据通过MQTT协议上报云端:
MQTT报文示例 (JSON格式):
{
"deviceId": "sensor_001",
"timestamp": "2026-03-10T14:30:00Z",
"data": {
"temperature": 23.5,
"pressure": 1.2,
"relay1_status": "on"
}
}
支持的云平台:
阿里云IoT
AWS IoT
华为云
私有云/自建平台
数据到达云端后,构建完整的业务应用:
实时监控仪表板:
设备状态总览
传感器实时数值
告警信息展示
数据存储:
时序数据库(如InfluxDB)存储历史数据
关系型数据库存储设备元数据
业务逻辑:
异常预警:温度骤升超过阈值时短信/邮件通知
远程控制:通过云端反向控制继电器
预测性维护:基于历史数据分析设备健康趋势
| 功能需求 | 推荐配置 | 说明 |
|---|---|---|
| 网关接口 | ≥1路RS485 + 1路以太网 | 连接Modbus设备 |
| 网络制式 | 4G全网通/5G可选 | 适应不同现场网络 |
| IO接口 | DI/DO点位数 | 若需本地控制继电器 |
| 存储空间 | ≥2GB | 断网缓存 |
| 工业防护 | 宽温(-20~60℃)、EMC3级 | 适应工业环境 |
准备阶段
整理传感器Modbus寄存器映射表
确认现场网络条件(有线/4G)
选择云平台并创建账号
配置阶段
网关网络配置上线
云端创建产品和设备
网关Modbus通道配置
数据映射规则配置
测试阶段
单点数据采集测试
断网续传功能验证
云端数据接收验证
上线运行
部署正式运行
配置告警规则
搭建监控仪表板
扫描上方二维码,关注撼动科技