最近也在折腾类似的玩意(用的德力西 DTSU6606 ),不过没试过 RTU 转 TCP,稍微看了一下说明书,感觉有如下几个地方可以排查一下,首先放一段说明书原文:
> DL/T 645-2007 协议切换到 ModBus-RTU 通讯协议的数据帧如下:FE FE FE FE 68 xx xx xx xx xx xx 68 14 0E 33 33 35 3D 35 33 33 33 33 33 33 33 33 33 CS 16
>
> 注意:xx xx xx xx xx xx 为表通讯地址; CS 为校验码.
>
> 仪表默认出厂参数:波特率 2400bps ( DDSU666-E/D/F 波特率为 9600bps ),偶校验。1 停止位,协议 DL/T645-2007,表号为标签表号,共 12 位(十进制)。
- 说明书中提到这台表支持 Modbus RTU 和 DL/T 645 两种软件协议,同时默认是 DL/T 645 协议(见说明书第 9 页)。说明书给出了从 DL/T 645 切换到 Modbus RTU 的对应指令:
此处涉及到 DL/T 645 协议,6 个字节的“表通讯地址”实质上是电表 SN 序列号的 BCD 表示(两个字符一组,倒着写),通常印在表的前面板上,小端在前。例如表号为 No.123456789098,则通讯地址为 0x98 0x90 0x78 0x56 0x34 0x12 。
而根据 DL/T 645 协议,校验码的计算方法为求校验码之前所有字节的和,长度为 1 字节溢出丢弃(例如数据为 0x12 0x34 0x56 0x78 0x9A,校验码 0x12 + 0x34 + 0x56 + 0x78 + 0x9A = 0x01AE 取最低字节即为 0xAE 。
为了排除干扰,建议此处暂时忽略 Modbus 网关,使用 USB 转 RS485 设备和串口终端程序直接与电表进行进行通信。
- 发送切换到 Modbus 的指令之后,需要验证是否成功切换,此处可以手动构建并发送一个 Modbus RTU 数据包。参考 **说明书第 10 页的表格** ,可以看到表内实现的所有保持寄存器的地址。
此处使用“A 相电压”寄存器进行测试,阅读表格可知其地址为 0x2000,类型为 float,长度为 2 字节。根据 Modbus RTU 协议构造一个请求数据包:
`01 03 20 00 00 02 CF CB`
0x01: 从机地址,默认应该为 0x01,不行的话自己遍历一下
0x03: 指令“读保持寄存器”
0x0020: 从地址 0x2000 开始读(小端在前)
0x0002: 从起始地址连续读 2 字节(大端在前)
0xCFCB: Modbus RTU 使用的 CRC-32 校验,可以使用 [这个网站]([Online Modbus RTU Parser & Modbus TCP Parser (
rapidscada.net)](
https://rapidscada.net/modbus/ModbusParser.aspx) 进行验证,如果不正确会自动提示并算出正确的校验值。
一切正常则发送之后应会收到应答,应答内容粘贴进上面的网站可以看到数据解析。
- 确定电表本身 Modbus RTU 通讯正常之后就可以上网关了,个人没用过 Modbus TCP 和 mbpoll,感觉应该是要在网关的配置中把 Modbus TCP (网关端口 502 对外开放的服务器)的寄存器映射到 Modbus RTU (网关连接的电表) 的寄存器?