Modbus RTU 调试控制
Modbus RTU 调试控制
适用于 FastBee IoT Platform — ESP32 固件
默认适配:国产通用型 Modbus RTU 继电器模块(闪开型)
当前版本提示
- 精简版默认保留 Modbus RTU 主站能力,Modbus RTU 配置页面默认启用 RTU;Modbus TCP、HTTP、CoAP、TCP 在精简版中关闭。
- Modbus 子设备编辑、映射和删除操作都在 Web 页面内完成;删除会先弹出确认窗口,确认后再删除。
- 电机类子设备控制面板提供正转、停止、反转等默认按钮样式,适合快速调试方向控制。
- Modbus RTU 配置、子设备和映射保存在
/config/protocol.json,可在“设备配置 > 高级配置 > 配置导入/导出”中按“通信协议”单独备份或恢复。 - 导入
protocol.json后建议重启设备,确保串口、主站任务和子设备映射从新配置重新初始化。
Modbus 调试主要在“通信协议 / Modbus RTU”页面完成;涉及联动时,再到“外设执行”页面创建轮询或控制规则。


调试时建议先让主站稳定读到单个从站,再扩展到多从站轮询;涉及控制动作时,再接入外设执行规则并观察日志。
遇到超时或异常码时按闭环图逐层排查:先物理层,再串口参数和从站映射,最后才检查外设执行控制动作和业务规则。
配置寄存器前先对照映射地图确认三件事:功能码是否匹配目标数据区,手册地址是显示地址还是协议地址,FastBee API 中的 address 是否需要减 1。多数“读数偏一位”或“能读不能写”都出在这三处。
当你从 Web 面板或 REST API 发起控制时,可用上图快速定位对应功能码和数据区。调试时先确认 API 参数和功能码匹配,再检查地址偏移、串口参数和从站响应。
目录
1. 概述
Modbus 调试与控制面板是 FastBee IoT 平台内置的 Modbus RTU 操作工具,集成在 Web 管理界面的「协议配置 > Modbus RTU」标签页中。
它基于标准 Modbus RTU 功能码实现,并针对国产通用型 Modbus RTU 继电器模块(闪开型)进行了默认适配,支持其原生指令集。同时兼容标准 Modbus RTU 数字量输入输出模块(如中盛科技4路继电器等),支持 FC 0x06 寄存器模式控制。主要功能:
- 继电器模块的线圈开关控制(原生翻转指令 0x5500)
- 闪开延时控制(硬件定时,FC 0x05 地址 0x0200+通道)
- 硬件寄存器延时(FC 0x06 写延时值,设备自动延时翻转)
- 批量开/关/翻转操作(原生全翻转指令 0x5A00 / 寄存器批量控制)
- 离散输入(DI)状态读取
- 从站设备地址管理(广播读取/写入)
- 从站设备波特率配置(FC 0xB0 专有指令 / FC 0x06 寄存器模式)
- 通信调试和设备排查
支持的 Modbus 功能码
| 功能码 | 名称 | 用途 |
|---|---|---|
| FC 0x01 | Read Coils | 读取线圈状态 |
| FC 0x02 | Read Discrete Inputs | 读取离散输入状态 |
| FC 0x03 | Read Holding Registers | 读取保持寄存器(含广播读地址) |
| FC 0x05 | Write Single Coil | 写单个线圈 / 原生翻转 / 闪开延时 |
| FC 0x06 | Write Single Register | 写单个保持寄存器 |
| FC 0x0F | Write Multiple Coils | 写多个线圈(批量开/关) |
| FC 0x10 | Write Multiple Registers | 写多个保持寄存器(含广播写地址) |
| FC 0xB0 | Set Baud Rate (专有) | 修改从站波特率(继电器板专有指令) |
2. 前置条件
2.1 硬件连接
ESP32 Modbus从站设备
┌──────────┐ ┌──────────────┐
│ TX Pin ├───────────→│ RX (A+/B-) │
│ RX Pin ├←───────────│ TX (A+/B-) │
│ DE Pin ├───────────→│ DE (可选) │
│ GND ├────────────│ GND │
└──────────┘ └──────────────┘- RS485 模块:需要连接 DE(方向控制)引脚。如使用自动收发的 RS485 模块,DE 引脚设为
-1即可。 - TTL 直连:适用于 TTL 电平的 Modbus 设备,无需 DE 引脚。
- 供电:确保从站设备与 ESP32 共地。
2.2 软件配置
- 固件已上传至 ESP32,文件系统已同步
- ESP32 已连接 WiFi,可通过浏览器访问 Web 界面
- 在 Web 界面中进入 协议配置 页面
2.3 外设配置
在 Modbus RTU 标签页中,需先选择或配置 UART 外设:
| 参数 | 说明 | 典型值 |
|---|---|---|
| 外设配置选择 | 选择已配置的 UART 外设实例 | 下拉选择 |
| DE 引脚 (RS485) | RS485 方向控制引脚号 | 14(无 DE 设 -1) |
| 超时时间 (ms) | 通信响应超时 | 1000 |
| 传输类型 | JSON 结构化 / 透传原始帧 | JSON |
| 工作模式 | MQTT 指令模式 / 主动轮询模式 | 主动轮询模式 |
重要:配置完基础参数后需点击页面底部的「保存」按钮,然后重启设备使配置生效。
3. Modbus RTU 基础配置
3.1 Master 轮询任务
在「主站轮询任务」表格中可配置周期性数据采集任务:
| 字段 | 说明 | 范围 |
|---|---|---|
| 从站地址 | 目标设备的 Modbus 地址 | 1-247 |
| 功能码 | 读取方式 | 0x01/0x02/0x03/0x04 |
| 起始地址 | 寄存器/线圈起始地址 | 0-65535 |
| 数量 | 读取的寄存器/线圈数量 | 1-125 |
| 间隔(秒) | 轮询周期 | 1-65535 |
| 标签 | 任务可读名称 | 自定义文本 |
| 映射 | 寄存器到传感器的映射数量 | 0-N |
| 启用 | 是否激活此任务 | 勾选 |
3.2 主站运行状态
页面实时显示 Master 模式运行统计:
- 运行状态:当前状态机状态(空闲/发送中/等待响应等)
- 总轮询:累计发起的轮询请求次数
- 成功:收到正确响应的次数
- 失败:通信错误(CRC 错误、异常响应等)
- 超时:从站无响应的次数
4. 调试与控制面板
调试与控制面板位于 Modbus RTU 标签页中的「主站运行状态」区域下方,标题为 「Modbus 调试与控制」。
前提条件:Modbus RTU 必须处于 Master 模式且已初始化成功,否则所有操作将返回错误。
4.1 连接参数
面板顶部是基本的连接参数配置区域,所有控制操作都依赖这些参数:
从站地址 (Slave Address)
- 位置:左上输入框
- 作用:指定当前要操作的 Modbus 从站设备地址
- 范围:1 - 247
- 默认值:1
- 说明:与从站设备出厂或自定义的地址一致。如不确定可使用设备参数配置中的「读取地址」功能(广播读取,无需知道当前地址)。
通道数 (Channel Count)
- 位置:左下下拉菜单
- 作用:设置线圈网格显示的通道数量,同时影响批量操作范围
- 可选值:1 / 2 / 4 / 8(默认)/ 16 / 32
- 说明:应与从站设备实际的线圈/继电器通道数一致。例如 8 路继电器板选 8。
线圈基地址 (Coil Base Address)
- 位置:右上输入框
- 作用:线圈的起始 Modbus 地址偏移
- 范围:0 - 65535
- 默认值:0
- 说明:大多数继电器模块线圈地址从 0 开始。实际操作的线圈地址 =
基地址 + 通道号。例如基地址设为 100,CH0 对应线圈地址 100,CH3 对应 103。
自动刷新 (Auto Refresh)
- 位置:右下复选框
- 作用:开启后每 3 秒自动从从站读取线圈状态并更新网格
- 默认:关闭
- 说明:适合需要实时监控线圈状态的场景。自动刷新过程中如发生通信错误不会弹出提示(静默模式),避免频繁打扰。
4.2 线圈状态网格
连接参数下方是线圈状态网格区域,以卡片方式直观显示每个通道的状态。
界面说明
- 每个通道显示为一个方块卡片,格式为
CHn+ 状态(开/关) - 绿色背景(
coil-on):线圈处于开启(ON)状态 - 灰色背景(
coil-off):线圈处于关闭(OFF)状态 - 操作中的卡片会显示半透明加载效果
操作方法
- 点击任意线圈卡片:执行 toggle(翻转) 操作
- 操作流程:
- 系统通过 FC 0x05 发送原生翻转指令(值 0x5500)到对应线圈地址
- 设备在硬件层面自动翻转该线圈状态
- 系统通过 FC 0x01 回读线圈当前实际状态
- 更新网格显示
- 弹出「操作成功」通知
注意事项
- 首次进入面板时网格中所有线圈默认显示为 OFF(灰色),需点击「刷新状态」或开启「自动刷新」获取真实状态
- 翻转操作使用设备原生指令(0x5500),只需一次写入通信 + 一次回读通信,响应更快
- 原生翻转指令由设备硬件执行,不需要 ESP32 预先读取状态再取反
4.3 批量控制
位于线圈网格下方,提供四个操作按钮:
全部开启 (All ON)
- 功能码:FC 0x0F(Write Multiple Coils)
- 行为:将所有通道的线圈一次性写入 ON 状态
- 参数:受「通道数」和「线圈基地址」控制
全部关闭 (All OFF)
- 功能码:FC 0x0F(Write Multiple Coils)
- 行为:将所有通道的线圈一次性写入 OFF 状态
全部翻转 (Toggle All)
- 功能码:FC 0x05(原生翻转指令)
- 帧格式:
[SlaveAddr, 0x05, 0x00, 0x00, 0x5A, 0x00, CRC] - 行为:
- 通过 FC 0x05 向线圈基地址发送值 0x5A00(全翻转指令)
- 设备硬件自动翻转所有通道状态
- 通过 FC 0x01 回读所有线圈的实际状态
- 更新网格显示
- 优势:只需一次写入通信(原生指令),无需逐个读取再翻转
刷新状态 (Refresh)
- 功能码:FC 0x01(Read Coils)
- 行为:从从站读取所有线圈当前状态,更新网格显示
- 说明:不改变任何线圈状态,纯读取操作
4.4 闪开延时控制
位于批量控制按钮下方,用于实现「开启后自动关闭」的硬件定时操作(闪开/闪断功能)。
重要区别:延时操作由继电器板硬件计时执行,非 ESP32 软件定时器。发送指令后即使 ESP32 断电,继电器板仍会在到时后自动关闭。
操作元素
| 元素 | 说明 |
|---|---|
| 通道下拉菜单 | 选择要操作的通道号(CH0 - CHn) |
| 延时输入框 | 设置自动关闭的等待时间,单位:x100ms |
| 启动延时按钮 | 执行闪开控制操作 |
操作流程
- 从下拉菜单选择目标通道(如 CH3)
- 在输入框设置延时值(如
50,表示 50 x 100ms = 5 秒) - 点击「启动延时」按钮
- 系统执行:
- 通过 FC 0x05 向地址
0x0200 + 通道号写入值(延时值 << 8) - 继电器板收到指令后,立即开启该通道
- 硬件计时到达后,自动关闭该通道
- 通过 FC 0x05 向地址
参数范围
| 参数 | 范围 | 默认值 | 说明 |
|---|---|---|---|
| 通道号 | 0 至(通道数-1) | CH0 | 对应线圈通道 |
| 延时值 | 1 - 255 | 50 | 单位 x100ms |
延时值换算表
| 延时值 | 实际时间 |
|---|---|
| 1 | 100ms |
| 10 | 1 秒 |
| 50 | 5 秒 |
| 100 | 10 秒 |
| 200 | 20 秒 |
| 255 | 25.5 秒(最大) |
技术细节
- 硬件延时:由继电器板内部 MCU 计时,精度高于软件定时
- 帧格式:
[SlaveAddr, 0x05, 0x02, Channel, DelayValue, 0x00, CRC]- 地址 =
0x0200 + channel(高字节 0x02,低字节 = 通道号) - 值 =
(delayUnits << 8) | 0x00(高字节 = 延时值,低字节 = 0x00)
- 地址 =
- 延时期间无需 ESP32 保持在线,继电器板独立执行
- 最大延时 25.5 秒;如需更长延时,需使用其他方案
4.5 设备参数配置
位于面板底部,默认折叠。点击「设备参数配置」标题可展开。用于对从站设备自身的通信参数进行读取和修改。
4.5.1 地址管理
用于读取或修改从站设备的 Modbus 地址。使用广播方式(从站地址 0x00)通信,无需知道设备当前地址。
地址寄存器
- 输入框:指定存储设备地址的保持寄存器地址
- 默认值:
0(即 0x0000) - 说明:国产通用继电器模块默认地址寄存器为 0x0000。不同设备可能不同,需查阅设备手册确认。
读取地址
- 按钮:「读取」
- 功能码:FC 0x03(Read Holding Registers)
- 从站地址:广播地址 0x00(自动使用,无需手动设置)
- 行为:从指定的地址寄存器读取设备当前 Modbus 地址
- 结果:在按钮下方显示
Current: <地址值> - 说明:使用广播读取,总线上只能连接一个从站设备,否则多设备同时响应会导致通信冲突
设置新地址
- 输入框:填写新的 Modbus 地址
- 范围:1 - 255
- 按钮:「设置」
- 功能码:FC 0x10(Write Multiple Registers)
- 从站地址:广播地址 0x00(自动使用)
- 行为:通过广播方式向地址寄存器写入新地址值
- 提示:UI 中显示 "广播写入(FC 0x10),1-255"
警告:修改从站地址后,面板顶部的「从站地址」参数需要同步更新为新地址,否则后续操作将无法通信。
4.5.2 波特率配置
用于修改从站设备的通信波特率。使用FC 0xB0 专有指令,不需要寄存器地址。
操作元素
| 元素 | 说明 |
|---|---|
| 波特率下拉菜单 | 选择目标波特率:1200/2400/4800/9600/19200/115200 |
| 设置按钮 | 执行写入操作 |
功能码
FC 0xB0(继电器板专有指令)
帧格式
[SlaveAddr, 0xB0, 0x00, 0x00, BaudCode, 0x00, CRC]波特率编码映射
| 波特率 | 编码值 |
|---|---|
| 1200 | 0 |
| 2400 | 1 |
| 4800 | 2 |
| 9600 | 3 |
| 19200 | 4 |
| 115200 | 5 |
- 提示:UI 中显示 "FC 0xB0 专有指令"
警告:修改波特率后,需要同步修改 ESP32 的 Modbus RTU 串口配置(外设设置中的波特率),然后保存并重启,否则双方波特率不匹配将无法通信。
4.5.3 离散输入读取
用于读取从站设备的数字输入端口状态。
操作元素
| 元素 | 说明 |
|---|---|
| 输入数量 | 要读取的离散输入数量,范围 1-32 |
| 输入基地址 | 离散输入起始地址,默认 0 |
| 读取按钮 | 执行读取操作 |
功能码
FC 0x02(Read Discrete Inputs)
结果显示
读取成功后,在按钮下方以彩色标签形式显示每个输入的状态:
- 绿色
INn:ON:输入为高电平(有信号) - 灰色
INn:OFF:输入为低电平(无信号)
5. REST API 参考
所有 API 需要登录认证(Bearer Token 或 Session Cookie)。
REST API 章节建议配合这张图阅读:线圈类接口对应 Coils 数据区,寄存器读写接口对应 Holding/Input Registers,设备参数和专有命令可能走私有帧或特定功能码。
5.1 线圈控制 API
POST /api/modbus/coil/control — 单个线圈控制
权限:config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| channel | int | 是 | 通道号 (0-based) |
| coilBase | int | 否 | 线圈基地址,默认 0 |
| action | string | 否 | on/off/toggle,默认 toggle |
toggle 操作说明:使用设备原生翻转指令(FC 0x05, 值 0x5500),然后回读状态。
成功响应:
{
"success": true,
"data": {
"channel": 0,
"coilAddress": 0,
"state": true,
"action": "toggle"
}
}POST /api/modbus/coil/batch — 批量线圈控制
权限:config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| channelCount | int | 是 | 通道数量 (1-32) |
| coilBase | int | 否 | 线圈基地址,默认 0 |
| action | string | 是 | allOn/allOff/allToggle |
allToggle 操作说明:使用设备原生全翻转指令(FC 0x05, 地址=coilBase, 值 0x5A00),然后回读状态。
成功响应:
{
"success": true,
"data": {
"channelCount": 8,
"action": "allOn",
"states": [true, true, true, true, true, true, true, true]
}
}POST /api/modbus/coil/delay — 闪开延时控制
权限:config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| channel | int | 是 | 通道号 (0-based) |
| delayBase | int | 否 | 延时地址基址,默认 0x0200 (512) |
| delayUnits | int | 是 | 延时值 (1-255),单位 x100ms |
| delayMode | int | 否 | 0=FC05闪开(默认), 1=软件延时, 2=硬件寄存器延时 |
| ncMode | bool | 否 | NC常闭模式 |
| coilBase | int | 否 | 线圈基地址 |
| mode | string | 否 | coil/register,控制模式 |
delayMode=0(默认):使用 FC 0x05 闪开指令(继电器板专有),地址=delayBase+channel,值=delayUnits<<8。
delayMode=1:软件延时,先写ON,ESP32软件定时器到期后写OFF。
delayMode=2:硬件寄存器延时,向通道寄存器写入值>1,设备自动延时(N-1)×0.01s后翻转。适用于中盛科技等支持寄存器延时翻转的模块。
当设备配置了
delayMode=2时,API 自动使用硬件寄存器延时模式,无需手动指定 delayMode 参数。
成功响应:
{
"success": true,
"data": {
"channel": 3,
"delayAddress": 515,
"delayUnits": 50,
"delayMs": 5000
}
}说明:
- 实际 Modbus 地址 =
delayBase + channel(如 0x0200 + 3 = 0x0203) - 实际写入值 =
delayUnits << 8(如 50 → 0x3200) - 硬件延时由继电器板执行,ESP32 仅发送指令
GET /api/modbus/coil/status — 查询线圈状态
权限:config.view 或 config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| channelCount | int | 否 | 通道数量,默认 8 |
| coilBase | int | 否 | 线圈基地址,默认 0 |
成功响应:
{
"success": true,
"data": {
"channelCount": 8,
"coilBase": 0,
"states": [false, true, false, false, true, false, false, false]
}
}5.2 设备参数 API
POST /api/modbus/device/address — 读取/设置从站地址
权限:config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 当前从站地址(读取/写入时均使用广播 0x00) |
| addressRegister | int | 否 | 地址寄存器,默认 0 (0x0000) |
| newAddress | int | 否 | 新地址 (1-255)。不填则为读取,填则为设置 |
读取说明:通过广播地址 0x00 发送 FC 0x03 读取地址寄存器。
设置说明:通过广播地址 0x00 发送 FC 0x10 写入新地址到地址寄存器。
读取响应:
{
"success": true,
"data": { "currentAddress": 1, "register": 0 }
}设置响应:
{
"success": true,
"data": { "previousAddress": 1, "newAddress": 5, "register": 0 }
}POST /api/modbus/device/baudrate — 设置波特率
权限:config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| baudRate | int | 是 | 波特率 |
| mode | int | 否 | 0=FC 0xB0专有(默认), 1=FC06写寄存器 |
| baudRateReg | int | 否 | FC06模式波特率寄存器地址(默认0x0033) |
| baudCode | int | 否 | 直接指定波特率编码值 |
mode=0(默认):使用 FC 0xB0 专有指令,帧格式 [SlaveAddr, 0xB0, 0x00, 0x00, BaudCode, 0x00, CRC]。波特率编码:0=1200, 1=2400, 2=4800, 3=9600, 4=19200, 5=115200。
mode=1:使用 FC 0x06 写保持寄存器(标准 Modbus,兼容中盛科技等品牌)。波特率编码:0=4800, 1=9600, 2=14400, 3=19200, 4=38400, 5=56000, 6=57600, 7=115200。
当设备配置了
baudRateMode=1时,API 自动使用 FC06 寄存器模式,无需手动指定 mode 参数。
成功响应:
{
"success": true,
"data": { "baudRate": 9600, "baudCode": 1, "mode": "register", "register": 51 }
}GET /api/modbus/device/inputs — 读取离散输入
权限:config.view 或 config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| inputCount | int | 否 | 输入数量,默认 4 |
| inputBase | int | 否 | 输入基地址,默认 0 |
成功响应:
{
"success": true,
"data": {
"inputCount": 4,
"inputBase": 0,
"states": [false, true, false, true]
}
}5.3 通用寄存器与状态 API
GET /api/modbus/status — 获取 Modbus 运行状态
权限:config.view
返回当前 Modbus 模式、通信统计、任务概览等信息(500ms 内部缓存)。常用于 Web 面板实时状态显示。
成功响应(示例):
{
"success": true,
"data": {
"mode": "master",
"running": true,
"stats": { "txCount": 123, "rxCount": 120, "timeoutCount": 3 },
"tasks": [ /* 主站轮询任务运行态 */ ]
}
}POST /api/modbus/write — 队列写单个保持寄存器(FC 0x06,入队)
权限:config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| regAddress | int | 是 | 寄存器地址 |
| value | int | 是 | 写入值 (0-65535) |
与
/api/modbus/register/write区别:此接口将写请求入队(受 Modbus 调度器排程),适用于非阻塞的主站控制场景;后者走 one-shot 接口直接发送并等待应答。
成功响应:{"success": true, "message": "Write request queued"}
GET /api/modbus/register/read — 读保持/输入寄存器(one-shot)
权限:config.view 或 config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| startAddress | int | 是 | 起始寄存器地址 |
| quantity | int | 是 | 数量 (1-125) |
| functionCode | int | 否 | 3=Holding(默认)/ 4=Input |
成功响应:
{
"success": true,
"data": {
"count": 4,
"startAddress": 0,
"values": [100, 200, 0, 1]
}
}POST /api/modbus/register/write — 写单个保持寄存器(FC 0x06,one-shot)
权限:config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| registerAddress | int | 是 | 寄存器地址 |
| value | int | 是 | 写入值 (0-65535) |
写入成功后,若寄存器落在某个 Modbus 子设备的 coilBase 控制区间内,会自动发布 MQTT 控制上报。
成功响应:
{ "success": true, "data": { "register": 5, "value": 100 } }POST /api/modbus/register/batch-write — 批量写保持寄存器(FC 0x10)
权限:config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| startAddress | int | 是 | 起始寄存器地址 |
| values | string (JSON数组) | 是 | 要写入的值数组,如 "[100,200,300]",长度 1-125 |
成功响应:
{
"success": true,
"data": { "startAddress": 0, "quantity": 3, "values": [100,200,300] }
}5.4 电机控制 API
POST /api/modbus/motor/control — Modbus 电机控制(正反转/停止/调速/脉冲)
权限:config.edit
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slaveAddress | int | 是 | 从站地址 (1-247) |
| action | string | 是 | forward/reverse/stop/setSpeed/setPulse/readStatus |
| value | int | 否 | setSpeed/setPulse 时的写入值 |
| registers | string (JSON数组) | 否 | 覆盖默认寄存器映射 [forward, reverse, stop, speed, pulse](缺省为 [0x0000,0x0001,0x0002,0x0005,0x0007],兼容 YF-53 等) |
优先从设备配置的 motorRegs 读取寄存器映射;若设备未配置,则使用默认或 registers 参数覆盖。readStatus 会读取速度/脉冲寄存器区间用于前端面板状态刷新。
成功响应(forward 示例):
{
"success": true,
"data": { "action": "forward", "register": 0, "value": 1 }
}5.5 错误响应格式
所有 API 在操作失败时返回统一格式:
{
"success": false,
"error": "错误描述",
"errorCode": "TIMEOUT"
}错误码说明:
| errorCode | HTTP 状态码 | 说明 |
|---|---|---|
TIMEOUT | 504 | 从站无响应,检查线路和地址 |
CRC_ERROR | 502 | CRC 校验失败,可能线路干扰 |
EXCEPTION | 502 | 从站返回异常码(附 exceptionCode 字段) |
NOT_INITIALIZED | 503 | Modbus 未初始化或未启用 |
BUSY | 503 | 总线正忙(另一操作进行中),稍后重试 |
Modbus 异常码:
| exceptionCode | 含义 |
|---|---|
| 0x01 | Illegal function — 功能码不受支持 |
| 0x02 | Illegal data address — 地址不存在 |
| 0x03 | Illegal data value — 数据值非法 |
| 0x04 | Slave device failure — 从站内部故障 |
6. Modbus 功能码说明
6.1 FC 0x01 — Read Coils(读线圈)
- 用途:读取从站的线圈(DO 输出)状态
- 本面板使用场景:「刷新状态」、「自动刷新」、翻转操作后的状态回读
- 数据含义:每个线圈 1 bit,0=OFF,1=ON
6.2 FC 0x02 — Read Discrete Inputs(读离散输入)
- 用途:读取从站的数字输入(DI)状态
- 本面板使用场景:设备参数 > 离散输入 > 读取
- 数据含义:每个输入 1 bit,0=OFF,1=ON
6.3 FC 0x03 — Read Holding Registers(读保持寄存器)
- 用途:读取从站的保持寄存器值
- 本面板使用场景:广播读取设备地址(从站地址 0x00,寄存器 0x0000)
- 数据含义:每个寄存器 16 bit 无符号整数
6.4 FC 0x05 — Write Single Coil(写单线圈 / 原生指令载体)
- 用途:控制单个线圈开/关,同时作为继电器板原生指令的载体
- 本面板使用场景:
- 标准开/关:值 0xFF00 = ON,0x0000 = OFF
- 原生翻转:值 0x5500,发送到目标线圈地址,设备自动翻转状态
- 原生全翻转:值 0x5A00,发送到线圈基地址(地址 0),设备翻转所有通道
- 闪开延时:地址 = 0x0200 + 通道号,值 = (延时值 << 8),设备硬件定时开启后关闭
- 帧格式:
[SlaveAddr, 0x05, AddrH, AddrL, ValueH, ValueL, CRC]
6.5 FC 0x06 — Write Single Register(写单寄存器)
- 用途:写入单个保持寄存器
- 本面板使用场景:预留接口(当前 UI 未直接使用)
- 帧格式:
[SlaveAddr, 0x06, AddrH, AddrL, ValueH, ValueL, CRC]
6.6 FC 0x0F — Write Multiple Coils(写多线圈)
- 用途:一次性写入多个线圈
- 本面板使用场景:「全部开启」「全部关闭」
- 特点:一帧完成所有通道的写入,比逐个 FC 0x05 效率更高
6.7 FC 0x10 — Write Multiple Registers(写多寄存器)
- 用途:一次性写入多个保持寄存器
- 本面板使用场景:广播写入设备新地址(从站地址 0x00,寄存器 0x0000)
6.8 FC 0xB0 — Set Baud Rate(专有指令)
- 用途:修改继电器板从站的通信波特率
- 本面板使用场景:设备参数 > 波特率配置 > 设置
- 帧格式:
[SlaveAddr, 0xB0, 0x00, 0x00, BaudCode, 0x00, CRC] - 波特率编码:0=1200, 1=2400, 2=4800, 3=9600, 4=19200, 5=115200
- 说明:这是继电器板的专有指令,不属于标准 Modbus 协议。非此类设备可能不支持。
场景六:控制 4 路标准继电器模块(中盛科技等)
设备:标准 Modbus RTU 4路继电器模块(如中盛科技数字量输入输出系列),默认地址 1,波特率 38400,保持寄存器控制。
设备配置:
| 参数 | 值 | 说明 |
|---|---|---|
| 设备类型 | relay | 继电器 |
| 从站地址 | 1 | 默认地址 |
| 通道数 | 4 | 4路继电器 |
| 线圈基地址 | 0 | 寄存器从0开始 |
| 控制模式 | 寄存器模式 | FC03/FC06 |
| 批量寄存器 | 52 (0x0034) | 全开/全关寄存器 |
| 延时模式 | 2(硬件寄存器) | 设备内置延时功能 |
| 波特率模式 | 1(FC06寄存器) | 标准写寄存器配置波特率 |
| 波特率寄存器 | 51 (0x0033) | 波特率设置寄存器 |
| 地址寄存器 | 50 (0x0032) | 地址设置寄存器 |
保持寄存器功能定义:
| 协议地址 | PLC地址 | 功能描述 |
|---|---|---|
| 0x0000-0x0003 | 40001-40004 | 通道1-4控制(0=关, 1=开, >1=延时翻转) |
| 0x0030 | 40049 | 通讯检测时间(N×0.1秒) |
| 0x0031 | 40050 | 输入口状态主动上传控制 |
| 0x0032 | 40051 | RS485地址/站号(1-255) |
| 0x0033 | 40052 | 波特率设置 |
| 0x0034 | 40053 | 批量控制(0=全关, 1=全开) |
| 0x0035 | 40054 | 按位控制通道1-16 |
| 0x003D | 40062 | 奇偶校验设置(0=无, 1=奇, 2=偶) |
| 0x0096-0x0099 | 40151-40154 | 通道1-4控制模式设置 |
波特率编码映射(寄存器 0x0033):
| 编码值 | 波特率 |
|---|---|
| 0 | 4800 |
| 1 | 9600 |
| 2 | 14400 |
| 3 | 19200 |
| 4 | 38400(出厂默认) |
| 5 | 56000 |
| 6 | 57600 |
| 7 | 115200 |
硬件寄存器延时:
向通道寄存器写入值 > 1,设备自动延时 (N-1)×0.01秒后翻转:
- 写 1:立即开启
- 写 0:立即关闭
- 写 501:延时 (501-1)×0.01 = 5秒后翻转
- 写 1001:延时 (1001-1)×0.01 = 10秒后翻转
操作步骤:
- 在外设管理中将 Modbus RTU 波特率修改为 38400(设备出厂默认)
- 保存配置并重启 ESP32
- 在设备控制页面可看到「4路继电器」控制面板
- 点击继电器卡片即可开关控制
- 延时控制:选择通道和延时值,点击「启动延时」,设备硬件定时自动关闭
场景一:控制 8 路继电器模块
设备:国产通用型 Modbus RTU 8 路继电器板,地址 1,波特率 9600,线圈地址从 0 开始。
操作步骤:
- 确认 Modbus RTU 基础配置已保存并重启
- 在调试与控制面板中设置:
- 从站地址:
1 - 通道数:
8 - 线圈基地址:
0
- 从站地址:
- 点击「刷新状态」→ 网格显示 8 个通道当前状态
- 点击某个灰色的通道卡片 → 该继电器翻转吸合(变绿)
- 再次点击 → 继电器翻转断开(变灰)
场景二:走廊灯闪开延时
需求:按下开关后灯亮 5 秒自动熄灭。
操作步骤:
- 设置闪开延时控制区域:
- 选择目标通道(如 CH0)
- 延时值输入
50(50 x 100ms = 5 秒)
- 点击「启动延时」
- 结果:CH0 继电器立即吸合(灯亮),5 秒后由继电器板硬件自动断开(灯灭)
长延时示例:
- 需要 10 秒延时 → 输入
100 - 需要 20 秒延时 → 输入
200 - 最大 25.5 秒延时 → 输入
255
场景三:修改从站地址
需求:将设备地址修改为 5(不知道当前地址也可以操作)。
操作步骤:
- 展开「设备参数配置」
- 地址寄存器确认为
0(国产继电器板默认值) - 点击「读取」→ 下方显示
Current: 1(通过广播地址 0x00 读取,无需知道当前地址) - 「新地址」输入
5 - 点击「设置」→ 通过广播地址 0x00 + FC 0x10 写入,操作成功
- 立即将面板顶部「从站地址」改为
5
注意:广播读取/写入时,总线上只能连接一个从站设备。如果有多个设备,会导致通信冲突。
场景四:批量初始化
需求:一键关闭所有继电器(设备上电安全检查)。
操作步骤:
- 配置好连接参数
- 点击「全部关闭」按钮
- 网格中所有通道变为灰色
场景五:读取传感器 DI 状态
需求:查看 4 路数字输入传感器的当前状态。
操作步骤:
- 展开「设备参数配置」
- 输入数量:
4,输入基地址:0 - 点击「读取」
- 下方显示 IN0:ON IN1:OFF IN2:OFF IN3:ON 等状态标签
8. 常见问题与故障排除
Q1:点击线圈卡片后提示「操作失败」
可能原因及排查:
| 检查项 | 排查方法 |
|---|---|
| 从站地址错误 | 使用广播读取地址功能确认设备实际地址 |
| 线路连接问题 | 检查 TX/RX 接线,RS485 A+/B- 是否接反 |
| 波特率不匹配 | ESP32 外设配置的波特率需与从站一致 |
| DE 引脚配置 | RS485 模块需正确配置 DE 引脚号 |
| 设备未上电 | 确认从站设备电源正常 |
| Modbus 未初始化 | 检查是否已保存 RTU 配置并重启 ESP32 |
| 设备不支持 0x5500 | 非国产通用继电器板可能不支持原生翻转指令 |
Q2:状态读取正常但无法控制(写操作失败)
可能原因:
- 从站设备线圈为只读(部分设备的状态线圈不可写)
- 线圈地址不正确(某些设备线圈地址不从 0 开始)
- 从站返回异常码 0x02(地址非法),检查设备手册中线圈地址范围
Q3:提示「Modbus busy, try again」
原因:另一个 Modbus 操作正在进行中(如轮询任务、其他 API 请求)。
解决:稍等 1-2 秒后重试。总线是半双工的,一次只能执行一个操作。
Q4:闪开延时不生效
可能原因:
- 设备不支持闪开功能(非国产通用继电器板)→ 查看设备手册确认是否支持 0x0200 地址段
- 延时值超出范围(必须 1-255)→ UI 已限制,API 调用时注意
- 通道号错误 → 确认通道号在 0 到(通道数-1)范围内
Q5:自动刷新不工作
排查:
- 确认复选框已勾选
- 检查浏览器控制台是否有 JS 错误
- 确认 Modbus 不处于频繁 BUSY 状态
Q6:波特率修改后设备无响应
原因:从站波特率已改变(通过 FC 0xB0 专有指令),但 ESP32 侧仍使用旧波特率。
解决:
- 在外设管理中修改 UART 外设的波特率为新值
- 保存 Modbus RTU 配置
- 重启 ESP32
Q7:通道数选择 16 或 32 后,读取状态很慢
原因:FC 0x01 读取多线圈需要更长的通信时间,且从站处理也更慢。
建议:仅选择设备实际的通道数,避免读取不存在的线圈导致错误或延迟。
Q8:广播读取地址时返回错误
可能原因:
- 总线上连接了多个从站设备 → 广播操作时只能连接一个设备
- 设备不支持广播地址 0x00 → 非国产通用继电器板可能不支持
- 线路问题导致响应丢失
9. 技术规格与限制
系统限制
| 项目 | 限制 |
|---|---|
| 最大通道数 | 32(单次写入线圈上限) |
| 闪开延时范围 | 1 - 255(x100ms,即 100ms - 25.5s) |
| 从站地址范围 | 1 - 255(控制操作),0x00(广播读写地址) |
| 线圈/寄存器地址范围 | 0 - 65535 |
| 自动刷新间隔 | 固定 3 秒 |
| API 并发限制 | Modbus 总线同一时刻仅支持一个操作 |
设备原生指令汇总
| 指令 | FC | 地址 | 值 | 说明 |
|---|---|---|---|---|
| 单通道翻转 | 0x05 | 线圈地址 | 0x5500 | 硬件翻转指定通道 |
| 全通道翻转 | 0x05 | 线圈基地址 | 0x5A00 | 硬件翻转所有通道 |
| 闪开延时 | 0x05 | 0x0200+ch | (delay<<8) | 硬件延时开启后自动关闭 |
| 读取地址 | 0x03 | 0x0000 | - | 广播(0x00)读取设备地址 |
| 设置地址 | 0x10 | 0x0000 | 新地址 | 广播(0x00)写入新地址 |
| 设置波特率 | 0xB0 | - | BaudCode | 专有指令修改波特率 |
通信参数
| 参数 | 说明 |
|---|---|
| 协议 | Modbus RTU (串行二进制) |
| 校验 | CRC-16/Modbus |
| 默认超时 | 1000ms(可配置) |
| 默认重试 | 2 次(可配置) |
| 帧间延迟 | 5ms(可配置) |
国际化支持
精简版默认使用中文界面并移除语言切换入口,以减少首屏资源和运行时加载压力;完整版可保留多语言资源。
浏览器兼容性
支持所有现代浏览器(Chrome、Firefox、Edge、Safari),推荐使用 Chrome 系浏览器获得最佳体验。
附录 A:Modbus RTU 帧结构
帧结构排查建议结合前文的“Modbus RTU 寄存器映射地图”:先确认从站地址和功能码,再确认 Addr 字段是否使用协议地址。很多继电器板手册会把 00001、40001 当作人类可读地址,实际 RTU 帧中对应地址可能是 0x0000。
请求帧(Master -> Slave)
| 从站地址 | 功能码 | 数据区 | CRC低 | CRC高 |
| 1 byte | 1 byte | N bytes| 1 byte| 1 byte|正常响应帧(Slave -> Master)
| 从站地址 | 功能码 | 数据区 | CRC低 | CRC高 |
| 1 byte | 1 byte | N bytes| 1 byte| 1 byte|异常响应帧(Slave -> Master)
| 从站地址 | 功能码+0x80 | 异常码 | CRC低 | CRC高 |
| 1 byte | 1 byte | 1 byte | 1 byte| 1 byte|附录 B:继电器板原生指令帧示例
翻转通道 3(从站地址 1)
请求:01 05 00 03 55 00 [CRC]
响应:01 05 00 03 55 00 [CRC]翻转所有通道(从站地址 1)
请求:01 05 00 00 5A 00 [CRC]
响应:01 05 00 00 5A 00 [CRC]闪开通道 2,延时 5 秒(从站地址 1)
请求:01 05 02 02 32 00 [CRC]
│ │ │ │ │ └─ 低字节 0x00
│ │ │ │ └──── 高字节 0x32 (50 x 100ms = 5s)
│ │ │ └─────── 通道 2
│ │ └────────── 0x02 (延时地址高字节)
│ └───────────── FC 0x05
└──────────────── 从站地址 1广播读取设备地址
请求:00 03 00 00 00 01 [CRC]
响应:00 03 02 00 01 [CRC] → 地址 = 1广播设置新地址为 5
请求:00 10 00 00 00 01 02 00 05 [CRC]
响应:00 10 00 00 00 01 [CRC]修改波特率为 9600(从站地址 1)
请求:01 B0 00 00 03 00 [CRC]
│ │ │ │ │ └─ 固定 0x00
│ │ │ │ └──── 编码 3 = 9600
│ │ │ └─────── 固定 0x00
│ │ └────────── 固定 0x00
│ └───────────── FC 0xB0
└──────────────── 从站地址 1附录 C:快速检查清单
开始使用前,请逐项确认:
