Modbus RTU Debugging and Control
Modbus RTU Debugging and Control
Synchronized Device Documentation
This page corresponds to the synchronized Chinese source. Commands, JSON examples, API paths, field names, and screenshots are kept aligned with the Chinese device-side source documentation.
What This Page Covers
- Connection model, required protocol parameters, and platform expectations.
- Configuration examples, register or topic mapping, and debug workflow.
- Connectivity validation, logs, and troubleshooting notes.
Source Reference
The detailed operational source is preserved below so implementation details stay exact while the English navigation, titles, and reading path remain available.
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:快速检查清单
开始使用前,请逐项确认:
