7.6 KiB
Modbus 接口规范
1. 文档用途
本文档用于指导主项目接入已完成现场实测的 24 路继电器、电压采集和电流采集设备。
配套文件:
device-profile.json:设备协议与通道映射的唯一权威配置。appsettings.Modbus.example.json:主项目默认配置字段示例。接入验收清单.md:开发完成后的测试和验收要求。
主项目实现时必须读取配置,不得在业务代码中硬编码从站地址、线圈、寄存器、量程、公式或通道映射。
2. 实测资料与结论
本规范依据以下现场结果整理:
结果_Modbus-接口-电流-电压对应表.txt:逐个物理插位手动测量得到的采集页通道对应关系。结果_modbus-tuner-20260618-131814.json:调试程序于 2026-06-18 导出的已调通通讯参数。
编号含义必须严格区分:
| 名称 | 含义 |
|---|---|
physicalSlot |
机器上的物理接口位置,也是主项目业务层唯一使用的通道号,范围 1~24 |
relayChannel |
调试程序继电器控制页按钮号;实测与物理插位一致 |
sourceDisplayChannel |
调试程序采集页面上出现读数的通道号,仅保留作实测追溯 |
registerOffset |
在本次 24 寄存器回包数据区中的零基位置,主项目实际解析使用 |
主项目不得把 sourceDisplayChannel 当作物理插位,也不得直接用它计算字节偏移。
3. 总线与串口参数
所有模块共用一条 RS485 总线。
| 参数 | 实测值 |
|---|---|
| 协议 | Modbus RTU |
| 波特率 | 9600 |
| 数据位 | 8 |
| 校验 | None |
| 停止位 | 1 |
| 读取超时 | 500 ms |
| 失败重试 | 2 次 |
| CRC | CRC16-Modbus |
| CRC 字节序 | 低字节在前 |
| 地址、数量和寄存器数据 | 高字节在前 |
现场调试使用过 COM9,但 COM 号属于计算机本地设置。主项目应允许用户选择和保存,不得把 COM9 固定为设备协议的一部分。
同一串口的请求必须串行执行。不得让继电器写入、电压读取和电流读取同时向串口写帧。
4. 模块地址
| 模块 | 从站地址 |
|---|---|
| 继电器板 1,负责物理插位 1~8 | 1 |
| 继电器板 2,负责物理插位 9~16 | 2 |
| 继电器板 3,负责物理插位 17~24 | 3 |
| 24 路电压采集模块 | 4 |
| 24 路电流采集模块 | 5 |
5. 继电器控制
使用功能码 0x05 写单个线圈。
- 开:
0xFF00 - 关:
0x0000 - 正常响应应回显请求中的从站、功能码、线圈地址和值。
- 响应必须检查长度、从站、功能码、回显内容和 CRC。
主项目业务接口建议:
SetRelayAsync(int physicalSlot, bool isOn)
处理流程:
- 校验
physicalSlot为 1~24。 - 从
device-profile.json的channels查找该物理插位。 - 取得
relay.slave和relay.coil。 - 构造并发送
0x05帧。 - 验证回显后才更新业务状态。
不要在未确认当前硬件是否允许的情况下自动全开 24 路。
6. 电压采集
实测配置:
| 参数 | 值 |
|---|---|
| 从站 | 4 |
| 功能码 | 0x03 |
| 起始寄存器 | 0 |
| 寄存器数量 | 24 |
| 量程 | 100 V |
| 解析公式 | B |
| 公式 | 实际电压 = DATA / 100 |
| DATA 类型 | UInt16 |
| 每通道字节数 | 2 |
| 数据字节序 | Big-Endian |
请求主体:
04 03 00 00 00 18
追加 CRC16-Modbus 后发送。正常响应共 53 字节:
[从站1][功能码1][字节数0x30][48字节数据][CRC2]
7. 电流采集
实测配置:
| 参数 | 值 |
|---|---|
| 从站 | 5 |
| 功能码 | 0x03 |
| 起始寄存器 | 0 |
| 寄存器数量 | 24 |
| 量程 | 60 A |
| 解析公式 | A |
| 公式 | 实际电流 = DATA / 10000 × 60 |
| DATA 类型 | Int16 |
| 每通道字节数 | 2 |
| 数据字节序 | Big-Endian |
请求主体:
05 03 00 00 00 18
这里的“带符号”按现场导出配置解释为:读取寄存器 0~23,并将每个 16 位原始值按二进制补码转换为 Int16。主项目不得自行把起始寄存器改成 24,也不得在映射地址上额外加 24。如后续更换硬件或重新标定,应修改配置版本并重新验收。
8. 采集回包解析
电压和电流共用以下流程:
- 检查响应最小长度。
- 检查响应从站等于配置从站。
- 检查功能码。若最高位为 1,按 Modbus 异常响应处理。
- 检查字节数为
registerCount × registerBytes,当前应为 48。 - 验证 CRC16-Modbus。
- 对每个物理插位读取对应的
registerOffset。 - 字节位置为:
position = dataStartOffset + registerOffset × channelBytes
当前 dataStartOffset=3,channelBytes=2。
- 按 Big-Endian 合成原始 16 位值。
- 根据
signed转换为UInt16或Int16。 - 根据
formula和range换算工程值。
公式定义:
A: value = DATA / 10000.0 × range
B: value = DATA / range
9. 统一业务接口
主项目业务层只允许使用物理插位 1~24,建议公开以下抽象:
ConnectAsync()
DisconnectAsync()
SetRelayAsync(int physicalSlot, bool isOn)
ReadAllVoltagesAsync()
ReadAllCurrentsAsync()
ReadMeasurementsAsync()
一次测量结果建议包含:
PhysicalSlot
Voltage
Current
VoltageRaw
CurrentRaw
Timestamp
VoltageQuality
CurrentQuality
ReadMeasurementsAsync() 应分别完成一次电压整帧读取和一次电流整帧读取,再按 physicalSlot 合并。不要为每个物理插位单独读取一次寄存器;每种采集模块一次读取 24 个寄存器即可。
10. 配置加载与校验
程序启动时必须校验:
schemaVersion是程序支持的版本。- 物理插位恰好覆盖 1~24,不重复、不缺失。
- 继电器从站和线圈组合不重复。
- 电压、电流的
registerOffset均在0~registerCount-1。 - 每类采集映射不得出现重复的
registerOffset。 - 从站地址范围为 1~247。
registerBytes=2、channelBytes=2。- 公式只能是
A或B。 - 字节序和 CRC 类型为程序支持值。
配置错误时应阻止通讯并给出具体字段,不要静默使用代码默认值。
11. 超时、重试和线程规则
- 一次请求从发送到收到完整响应视为一个事务。
- 失败后最多重试配置中的次数;当前为 2 次,即最多发送 3 次。
- CRC 错误、响应超时、从站错误、功能码错误和响应长度错误都应记录原始 HEX。
- 重试前应清理串口输入缓冲区,避免残帧与下一帧拼接。
- 串口操作使用互斥锁或单消费者队列串行化。
- 断开和应用退出时安全关闭串口。
12. 主项目配置建议
建议将机器本地参数放在主项目配置,将设备协议和映射放在独立配置:
主项目配置
└─ Modbus
├─ Enabled
├─ PortName
├─ DeviceProfilePath
└─ PollIntervalMs
device-profile.json
├─ 串口通讯默认参数
├─ Modbus 帧规则
├─ 模块协议
└─ 24 路权威映射
device-profile.json 应随主程序发布并复制到输出目录。主项目可以提供配置界面修改 COM 口,但协议和通道映射只应由经过授权的维护流程更新。
13. AI 编程强制要求
将本目录交给主项目 AI 时,应附加以下要求:
严格按《Modbus接口规范.md》和
device-profile.json实现。业务层统一使用physicalSlot1~24。所有从站、线圈、寄存器、量程、公式及映射从配置读取,不得硬编码。sourceDisplayChannel仅用于追溯现场实测,不参与解析寻址。实现配置启动校验、串口事务串行化、CRC及响应完整校验,并按《接入验收清单.md》完成测试。