Modbus 子设备
功能说明
Modbus 子设备外设用于通过 RS485 总线控制外部 Modbus 从站设备,如继电器模块、PWM 控制器、PID 控制器、电机驱动器等。支持线圈写入(FC05)和寄存器写入(FC06)两种控制协议。
支持的外设类型
| 类型 | type值 | 说明 |
|---|---|---|
| MODBUS_DEVICE | 51 | Modbus RS485 子设备 |
通信方式
- 物理层:RS485 半双工
- 协议:Modbus RTU
- 控制方式:通过 UART 外设配置的 RS485 端口发送命令
Modbus 子设备不占用 GPIO 引脚(通过已配置的 UART/RS485 端口通信)
配置方式
方式1:Web界面配置(推荐)
在通信协议页配置Modbus RTU的串口、波特率和子设备。启用主站并采用结构化采集/控制模式后,协议管理器把启用的子设备注册成只读管理的虚拟外设modbus:索引。透传模式不注册这些虚拟外设;外设页不能独立新增、修改或启停type 51。
| 区域 | 字段 | 示例值 / 状态 |
|---|---|---|
| 状态概览 | 风险等级 | 低 |
| 状态概览 | 启用任务 | 0 |
| 状态概览 | 超时率 | 0% |
| 状态概览 | 总轮询 / 成功 / 失败 / 超时 | 0 / 0 / 0 / 0 |
| 基础配置 | 启用 Modbus RTU | 已启用 |
| 基础配置 | 外设配置选择 | 选择已配置的 RS485/UART 外设 |
| 基础配置 | 传输类型 | 透传(原始 HEX 帧) |
| 基础配置 | DE 引脚(RS485) | 14 |
| 子设备名称 | 类型 | 从站地址 | 设备信息 | 启用 | 操作 |
|---|---|---|---|---|---|
| 温湿度 | 采集 | 2 | FC04 @0 x2 [2映射] | ON | 编辑 / 映射 / 删除 |
| PM25-10 | 采集 | 1 | FC03 @0 x2 [2映射] | ON | 编辑 / 映射 / 删除 |
| 气象百叶箱 | 采集 | 4 | FC03 @500 x8 [6映射] | ON | 编辑 / 映射 / 删除 |
Modbus子设备的虚拟外设对象来自通信协议配置;底层串口、波特率、从站与寄存器映射均以通信协议页保存的配置为准。不要把虚拟对象复制进peripherals.json作为独立设备。
步骤1:配置总线
- 打开浏览器访问 ESP32 IP 地址
- 登录后进入 通信协议,选择Modbus RTU主站及已保存的UART/RS485外设,核对串口参数。
步骤2:在通信协议页添加子设备
在Modbus子设备列表新增对应的relay、pwm、pid或motor设备。
核对这些配置含义(实际可见项随类型变化):
字段 填写内容 说明 虚拟外设ID modbus:0或modbus:1按协议子设备索引自动生成,不手工填写 名称 4路继电器或4路PWM调光显示名称 虚拟外设类型 Modbus设备 (type: 51) 协议管理器生成 从站地址 1或2Modbus地址(1-247) 通道数量 4继电器路数或PWM路数 控制协议 线圈(FC05) 或 寄存器(FC06) 根据设备类型 设备类型 relay 或 pwm 继电器或PWM 点击 保存
步骤3:验证配置
- 在通信协议页保存并启用子设备,按页面提示使配置生效。
- 在外设/规则目标列表核对生成的
modbus:索引,修改或停用仍回到通信协议页。 - 接线和负载条件确认后,用Modbus专用控制界面测试;通用外设写入接口不提供type 51控制。
⚠️ 重要:Modbus设备依赖UART外设提供RS485物理通道,需先配置UART
虚拟对象字段说明
以下JSON仅帮助理解虚拟对象字段,不是可导入peripherals.json的模板。配置、导出与迁移应使用通信协议页和系统方案工具;对象ID由协议管理器生成。
4路继电器模块
{
"id": "modbus:0",
"name": "4路继电器",
"type": 51,
"enabled": false,
"pins": [],
"params": {
"slaveAddress": 1,
"channelCount": 4,
"coilBase": 0,
"ncMode": false,
"controlProtocol": 0,
"deviceType": 0,
"deviceIndex": 0,
"batchRegister": 0,
"pwmRegBase": 0,
"pwmResolution": 0,
"motorRegs": [0, 0, 0, 0, 0],
"motorDecimals": 0,
"sensorId": ""
}
}PWM 调光模块
{
"id": "modbus:1",
"name": "4路PWM调光",
"type": 51,
"enabled": false,
"pins": [],
"params": {
"slaveAddress": 2,
"channelCount": 4,
"coilBase": 0,
"ncMode": false,
"controlProtocol": 1,
"deviceType": 1,
"deviceIndex": 1,
"batchRegister": 0,
"pwmRegBase": 100,
"pwmResolution": 10,
"motorRegs": [0, 0, 0, 0, 0],
"motorDecimals": 0,
"sensorId": ""
}
}参数说明
| 参数 | 说明 |
|---|---|
| slaveAddress | Modbus 从站地址(1-247) |
| channelCount | 通道数量 |
| coilBase | 线圈/寄存器基地址 |
| ncMode | NC 常闭模式(true=常闭,控制逻辑反转) |
| controlProtocol | 控制协议:0=线圈(FC05), 1=寄存器(FC06) |
| deviceType | 设备类型:0=relay, 1=pwm, 2=pid, 3=motor |
| deviceIndex | 在 ModbusHandler config 中的索引 |
| batchRegister | 位图批量寄存器地址(0=不使用) |
| pwmRegBase | PWM 寄存器基地址 |
| pwmResolution | PWM 分辨率(bits) |
| motorRegs | 电机寄存器地址 [正转,反转,停止,速度,脉冲数] |
| motorDecimals | 电机参数小数位 |
| motorMinPosition | 电机/滑台软限位最小位置,单位为步数 |
| motorMaxPosition | 电机/滑台软限位最大位置;当 motorMaxPosition > motorMinPosition 时启用软限位 |
| motorCurrentPosition | 协议层位置记录;不能把命令ACK当作真实位置或自行修改虚拟外设字段校准 |
| motorMoveStep | forward/reverse 默认相对移动步数;未设置时使用最近一次 setPulse 值 |
| motorLastPulse | 协议层最近脉冲设置;不代表电机已完成对应位移 |
| sensorId | 传感器标识符(用于数据采集上报) |
Modbus 电机滑台软限位
当协议子设备deviceType为motor时,行程参数由协议配置和电机控制服务共同管理。以下字段帮助理解旧配置兼容,不应独立导入虚拟外设:
{
"deviceType": "motor",
"motorRegs": [0, 1, 2, 5, 7],
"motorMinPosition": 0,
"motorMaxPosition": 10000,
"motorCurrentPosition": 0,
"motorMoveStep": 1600,
"motorLastPulse": 1600
}开发候选中的虚拟电机寄存器写入使用同一电机控制服务、已保存的动作映射和行程准入。映射有歧义、来源已过期或行程条件不满足时拒绝执行。受理操作号、通信应答和机械位置分别记录,不再由虚拟外设写入函数按请求脉冲乐观增加位置;具体结果见Modbus控制结果与来源。
软限位依赖可信的位置与参考状态。首次上电、手动移动或回零后,按电机控制页的准备和参考确认流程核实状态;独立硬件限位与急停仍负责实际机械保护。不得把通信ACK当作回零或位置校准。
与外设执行联动
Web界面配置步骤
创建Modbus继电器控制规则
- 点击左侧菜单 外设执行
- 点击 新增规则 按钮
- 配置触发器(如平台触发、事件触发)
- 添加Modbus动作:
- 动作类型:Modbus线圈写入
- 目标外设:modbus:0(核对实际索引)
- 动作值:
0:1(通道0,逻辑开启)
- 点击 保存
💡 提示:线圈写入(FC05)用于继电器,寄存器写入(FC06)用于PWM
JSON配置示例
Modbus 线圈写入(ACTION_MODBUS_COIL_WRITE = 16)
{
"targetPeriphId": "modbus:0",
"actionType": 16,
"actionValue": "0:1",
"useReceivedValue": false,
"syncDelayMs": 0,
"execMode": 0
}Modbus 寄存器写入(ACTION_MODBUS_REG_WRITE = 17)
{
"targetPeriphId": "modbus:1",
"actionType": 17,
"actionValue": "100:512",
"useReceivedValue": false,
"syncDelayMs": 0,
"execMode": 0
}Modbus 轮询采集(ACTION_MODBUS_POLL = 18)
{
"targetPeriphId": "modbus-task:0",
"actionType": 18,
"actionValue": "{\"poll\":[0]}",
"useReceivedValue": false,
"syncDelayMs": 0,
"execMode": 0
}注意事项
- UART 前提:Modbus 设备依赖 UART 外设提供 RS485 物理通道,需先配置 UART
- 地址唯一:同一总线上每个设备地址必须唯一
- 通信间隔:连续命令间建议 ≥50ms 间隔(pollInterPollDelay 参数控制)
- 超时重试:读取按实际配置执行;已接普通来源仲裁的继电器写命令不自动重试。超时不能当作未动作后再次发送
- pinCount=0:Modbus 设备不使用 GPIO 引脚
开发候选的继电器控制归属
2026-10-04新增的普通来源仲裁已接入直接MQTT、HTTP单继电器及规则poll-control继电器入口,尚待本批集中回归和设备验收。相同总线handler实例及从站共用控制归属,不因配置索引、通道或别名不同而允许互相抢写。HTTP身份取自登录会话;冲突、来源过期或覆盖确认失效时拒绝输出。
等待总线期间取消的命令不能迟到写出;已经发送的字节则不能撤回,需要等实际事务结束后释放占用。toggle先在同一总线锁内读取并校验,再写一次;读失败不猜测开关状态。FC05/06完整回显只证明通信应答,不能证明触点或负载已动作。多通道操作保留已确认前缀,后续失败不回滚或重发整批。
后继地址归属修复待集中验证:命名继电器、电机目标和标准写帧均先检查保存映射的唯一归属,再校验写入值。线圈和holding寄存器分开,FC06/FC16属于同一holding空间;值大小、PWM分辨率或电机功能码不能掩盖重叠映射。PID的PV保持只读,继电器自身batch/普通coil与硬件延时地址冲突也拒绝。非重叠混配可取得目标快照,但仍共用同一从站控制归属,输出前重新检查;vendor混配、行程保护及未知写的原拒绝规则保留。此处不代表所有Modbus入口、混配设备或物理输出已验收。候选状态见系统改进进度。

