Files
home-automation/docs/references/DDSU666-Modbus-Protocol.md
T
tliu93 3e04b15656
frontend / frontend (push) Successful in 2m21s
pytest / test (push) Successful in 9m50s
docker-image / build-and-push (push) Successful in 4m24s
feat(modbus): add DDSU666 profile and select read function code per profile
- Add CHINT DDSU666 profile (ddsu666.yaml): FC03 holding registers, voltage/
  current/active power (kW)/reactive power (kvar)/PF/frequency, import+export
  active energy. Word/byte order left at big-endian as a documented best guess
  (manual has no float example) — to be confirmed on-device.
- Add DDSU666-Modbus-Protocol.md reference extracted from the official manual,
  plus the source PDF (parity with the SDM120 reference).
- Generalize driver.read_blocks to dispatch FC03 (holding) or FC04 (input)
  based on a function_code argument (default 4, SDM120 behaviour unchanged);
  the code is validated before any connection is attempted.
- Wire profile.function_code through the CLI read command, the background
  poller, and the device /test endpoint — previously the profile field was
  declared but never honoured (read path was hardcoded to FC04).
- Tests: default -> FC04, function_code=3 -> FC03 holding, invalid FC rejected
  before connecting.
2026-06-30 17:16:25 +02:00

14 KiB
Raw Blame History

DDSU666 Modbus 协议(从官方 PDF 提取)

来源:docs/references/DDSU666 Single phase Smart Meter.pdf CHINT / 正泰仪表 DDSU666 Single phase Smart Meter — Operation Manual,文档号 ZTY0.464.1224,版本 V22020 年 8 月;厂商 Zhejiang Chint Instrument & Meter Co., Ltd. 本文件是 PDF 的可读化提取,供本项目的 Modbus 采集驱动设计参考。以官方 PDF 为准,本文件如有出入以 PDF 为准。 同类文档见 SDM120 的 SDM120-Modbus-Protocol.md;两表差异较大,见下方 §6「与 SDM120 的关键差异」。

设备速览(来自手册 Table 1 / Table 5

DDSU666(直接接入) DDSU666-CT(经互感器)
精度等级 Active Class B Active Class C
参考电压 230 V 230 V
电流规格 0.255(80) A 0.0151.5(6) A
表常数 800 imp/kWh 6400 imp/kWh
接入方式 直接接入 经电流互感器
  • 单相电子式电能表,DIN35mm 导轨安装;测量电压、电流、有功/无功功率、频率、功率因数、正/反向有功电能。
  • 电能测量范围 0999999.99 kWh(LCD 只显示 6 位,自动移动小数点)。
  • 通信:RS485Modbus-RTU(也支持 DL/T 645-2007,可切换,见 §5 0005H ChangeProtocol)。
  • 手册 Table 1 标注 Frequency Reference = 60Hz,但 LCD 示例又写 F=50.00Hz(手册自身不一致);实际频率以寄存器 200EH 读数为准,不要把 50/60 写死。

0. 本项目的接入方式(重要)

DDSU666 物理层是 Modbus RTURS-485 串口),半双工。和 SDM120 一样,本项目通过一个 Modbus-TCP 网关接入:

  • 后端用 Modbus TCPIP:port)连到网关,网关在串口侧转成 RTU 与电表通信。
  • TCP 帧用 MBAP header、无 CRC(CRC 由网关在 RTU 侧处理)。本文档里 RTU 帧的 CRC (Lo/Hi) 字段在 TCP 模式下不需要我们关心。
  • Slave Address / Unit ID = 电表的通信地址 Addr(范围 1–247;面板按键只能设 1–99;见 §5 0006H),在 TCP 请求里作为 unit id 传入。
  • 若以后直连串口(RTU),才需要管波特率 / 数据格式 / CRC:默认串口格式是 8 数据位、无校验、2 停止位(8N2),与 SDM120 的 8N1 不同——直连时务必对齐。
  • 电表必须处于 Modbus 协议模式(而非 DL/T 645)才能用本协议;可经面板长按切换,或写 0005H = 2(见 §5)。

1. 协议帧格式(Appendix A

异步传输,按字节为单位。一帧 10 位字符 = 1 起始位(0) + 8 数据位(无校验) + 2 停止位(1)(其它格式可定制)。

信息帧结构(Table A.1

字段 长度 说明
Start(起始) >3.5 字符静默 帧间至少 3.5 字符空闲时间作为分隔
Address code(地址码) 1 字节 目标从机地址 1–247;每个从机在总线上地址唯一
Function code(功能码) 1 字节 仅支持 03H / 10H(见 §2
Data(数据域) n 字节 随功能码不同而不同(起始地址、寄存器数、寄存器数据等)
CRC check codeCRC 校验) 2 字节 16-bit CRC低字节在前、高字节在后;多项式 A001
End(结束) >3.5 字符静默 帧间静默

TCP 网关模式下 Start/End 静默与 CRC 由网关处理,本项目不关心。

功能码 03H 示例(读寄存器,Table A.3/A.4

读从机 01H、起始地址 0CH、2 个寄存器:

  • 主机发送:01 03 00 0C 00 02 04 08(最后 04 08 是 CRC,低字节 04 在前)。
  • 从机返回(设 0CH/0DH 内容为 0000H1388H):01 03 04 00 00 13 88 F7 65
    • 04 = 字节数;00 00 = 0CH 数据;13 88 = 0DH 数据;F7 65 = CRC(低字节 F7 在前)。

注意:单个 16-bit 寄存器内是「高字节在前、低字节在后」(Table A.4 里 0DH 数据返回 13 88 = 0x1388)。这一点对解码浮点的字节序很关键,见 §3。

功能码 10H 示例(写多个寄存器,Table A.5/A.6

向从机 01H、起始地址 00H 连续写 3 个寄存器 0002H,1388H,000AH

  • 主机发送:01 10 00 00 00 03 06 00 02 13 88 00 0A 9B E9
    • 06 = 写入字节数(3 寄存器 × 2 字节);随后是 3 个寄存器的数据;末尾 9B E9 CRC。
  • 从机返回:01 10 00 00 00 03 80 08(回显起始地址 + 寄存器数 + CRC 80 08)。

异常响应(Table A.7/A.8

  • 异常时返回的 Function Code = 原功能码 + 128(即最高位置 103H→83H10H→90H)。
  • 数据为单字节 Error Code
Error Code 含义 说明
01H Illegal function code 收到的功能码本表不支持
02H Illegal register address 寄存器地址超出有效范围
03H Illegal data value 数据值超出对应地址的取值范围

2. 功能码

DDSU666 只支持两个功能码Table A.2):

功能码 作用 说明
03H Read register(读寄存器) 读一个或多个寄存器——测量值、电量、配置全部走它
10H Write multiple registers(写多个寄存器) 向 n 个连续寄存器写 n 个 16-bit 数据(改配置 / 清电量)

⚠️ DDSU666 没有「输入寄存器 / FC04」概念——所有数据(包括电压电流功率)都用 FC 03H 读保持寄存器。这是它和 SDM120(测量值走 FC04)最大的踩坑差异,见 §6。

3. 数据编码

DDSU666 有两类数据:

  1. 配置 / 参数寄存器(§50000H0010H:每个 1 个寄存器、16-bit with symbols16 位有符号整数)。
  2. 测量 / 电量寄存器(§42000H+ / 4000H+:每个参数 = 32-bit IEEE-754 单精度浮点(手册写 “single precision floating decimal”),占 2 个相邻寄存器Length = 2 Word)。

浮点字节序 / 字序

  • 字节序(byte order)= 大端:寄存器内高字节在前 —— 由 Table A.4 的 0x1388 返回为 13 88 确认。
  • 字序(word order,两个寄存器谁是高 16 位):手册没有给出浮点解码的实例,未明确标注。按标准 Modbus 浮点惯例应为大端字序(高寄存器在前,ABCD,与本项目 SDM120 驱动一致(registers_to_float>f,高寄存器在前)。
  • ⚠️ 需上机实测确认:读 2000H(电压)应解出 ~230V 这样的合理值;若解出乱数,多半是字序相反,改成「低寄存器在前」再试。CHINT 同系列(DTSU/DDSU666)现场固件偶有字序差异,首次接入务必用一个已知量(电压)校验,不要凭手册想当然。

Python 解码(大端、高寄存器在前):struct.unpack('>f', struct.pack('>HH', hi_reg, lo_reg))[0]。 pymodbusBinaryPayloadDecoder.fromRegisters(regs, byteorder=Endian.BIG, wordorder=Endian.BIG)

4. 测量 / 电量寄存器表(FC 03H 读)

全部为只读、Float32-bit),每项占 2 个寄存器。地址为 Modbus 协议原始地址(即帧里的 Start Register Address Hi/Lo),手册用十六进制。

4.1 瞬时量(“Electric quantity of the secondary side”,2000H 段)

地址(hex) 参数 代号 单位 备注
2000H 电压 Voltage U V
2002H 电流 Current I A
2004H 有功功率 Active power P kW 手册标注 “the unit is KW”——不是 W
2006H 无功功率 Reactive power Q kvar
2008H (保留 RESERVED 占 2 寄存器,跳过
200AH 功率因数 Power factor PF 无量纲
200CH (保留 RESERVED 占 2 寄存器,跳过
200EH 频率 Frequency Freq Hz

4.2 电量(“Electrical data of the secondary side”,4000H 段)

地址(hex) 参数 代号 单位 备注
4000H 正向(导入)有功电能 Active in electricity Ep kWh 正向 / forward active energy
400AH 反向(导出)有功电能 Reverse in electricity -Ep kWh 反向 / reverse active energy

手册里 4000H400AH 之间(4002H4009H)未列出,视为保留/未文档化。

读取分块建议

  • 瞬时量:2000H200FH16 个寄存器连续,一次块读即可覆盖 U…Freq(含两段 RESERVED,解码时跳过)。
  • 电量:4000H2 寄存器)与 400AH(2 寄存器)相距较远,分两小块读,或读 4000H400BH(12 寄存器)一次取出后挑用——以网关 / 电表是否允许跨保留地址块读为准,谨慎起见分开读更稳。

常用核心子集(日常监控够用)

电压 2000H、电流 2002H、有功功率 2004HkW)、功率因数 200AH、频率 200EH、正向有功电能 4000H、反向有功电能 400AH

5. 配置 / 参数寄存器表(FC 03H 读 / FC 10H 写)(Table 9

每个 1 个寄存器、16-bit 有符号整数R/W 列来自手册。

地址(hex) 代号 含义 R/W 取值 / 说明
0000H UCode 编程密码 Programming password code R/W 写配置前的密码字
0001H REV. 保留;实际读出的是版本号 R
0002H ClrE 电能清零 CLr.E R/W 1 清除总电量(不可逆,慎用)
0003H0004H RESERVED 保留
0005H ChangeProtocol 协议切换 R/W 2 = Modbus-RTU1 = DL/T 645-2007
0006H Addr 通信地址 R/W 1247(面板按键仅 199
0007H000AH RESERVED 保留
000BH Meter type 表型 Meter type R 只读设备类型标识
000CH BAud 通信波特率 R/W 1=2400bps2=4800bps3=9600bps(手册寄存器仅列这三档;通信章另提到也支持 1200bps)
000DH0010H RESERVED 保留

⚠️0002H(清电量)、0006H(改地址)、000CH(改波特率)、0005H(切协议)都会改变电表状态或通信参数,配错可能清空累计电量导致通信中断。本项目默认只读采集,不在自动化链路里写电表配置寄存器。 写配置通常需先经 0000H UCode 密码字校验;具体密码值手册正文未给出,需向厂商确认或经面板操作。

6. 与 SDM120 的关键差异(迁移 / 复用驱动时必看)

本项目已有 SDM120 profileapp/integrations/modbus/profiles/sdm120.yaml)。DDSU666 不能照搬,主要差异:

维度 SDM120 (Eastron) DDSU666 (CHINT)
读测量值功能码 FC 04(输入寄存器 3X FC 03(保持寄存器,无 FC04
测量值起始地址 0x0000 起(30001 瞬时量 0x2000 起;电量 0x4000/0x400A
有功功率单位 W(瓦) kW(千瓦) —— 入库前注意换算 / 单位标注
无功功率单位 VAr kvar
配置寄存器格式 FloatFC03/16 16-bit 有符号整数FC03/10
写功能码 16 / 0x10 10H(同 0x10
串口默认格式 8N11 停止位) 8N22 停止位)
多协议 仅 Modbus Modbus 与 DL/T 645-2007 可切换(需确保在 Modbus 模式)
浮点字序 大端、高寄存器在前(手册有实例佐证) 字节序大端已确认;字序手册无实例,需上机实测

7. 给本项目采集驱动的要点小结

  1. Modbus TCP 网关ModbusTcpClient(host, port)slave=<Addr>;电表须在 Modbus 协议模式
  2. 所有读取(测量 + 电量 + 配置)都用 FC 03H——没有 FC04
  3. 测量值在 0x2000 段、电量在 0x4000/0x400A,均为 float32;解码大端字节序,字序默认高寄存器在前但务必用电压实测校验
  4. 有功功率单位是 kW、无功是 kvar——与 SDM120 的 W/VAr 不同,新建 profile / 入库映射时单位别抄错。
  5. 配置寄存器(0x00000x0010)是 16-bit 有符号整数,不是 float。
  6. 默认只读0002H 写 1 会清空累计电量0006H/000CH/0005H 会改通信参数,自动化链路里一律不写。
  7. 新建 profile 时这是 ddsu666 这一个 register profile 的定义;建议 function_code: 3word_order: big(先按大端字序,接入后用电压读数验证)、瞬时量与电量分块读。

8. 实测记录(真机验证,2026-06-30)

首次接入一台 DDSU666 直接接入版(5(80)A 实测,确认以下几点:

  • 字序大端,确认无误:电压 / 电流 / 频率 / 电能用「大端、高寄存器在前」解码全部得到合理值(如 233.9 V / 0.055 A / 49.99 Hz),与 §3 的假设一致。ddsu666.yamlword_order: big / byte_order: big 无需修改,§3 里「字序需上机实测」一项可视为已关闭。
  • FC03 读通:所有量走 FC03profile ddsu666 在采集链路(CLI read / 设备 /test / 后台轮询)中工作正常。
  • 低电流下「瞬时功率读 0、但电能照常累加」:测试负载仅为一台 PoE 交换机(≈230 V / 0.05 A,真实有功仅几瓦),远低于本表测量量程下限 Imin≈0.25 A。此工况下:
    • 瞬时 active_power0x2004)与 power_factor0x200A)寄存器返回全零(原始 hex 0x0000 0x0000);电表 LCD 上功率在 03.3 W、PF 在 00.6 之间抖动。
    • 抖动成因 = 低电流测量噪声 + 开关电源(SMPS,无 PFC)畸变电流(电流为电压峰值附近的窄脉冲、谐波重 → 畸变功率因数天然偏低)。不是「采样率与开关频率拍频」:计量芯片 SH79F7019 采样在 kHz 量级,远低于开关电源 50–200 kHz 的开关频率,两者不在一个频段。
    • 但累计电能 import_energy0x4000正常累加(实测 0 → 0.01 kWh)——电表内部积分器在防潜动起始电流(0.004·Ib≈0.02 A)之上照常计量。
    • 结论:低于量程下限时瞬时功率 / PF 不可信,但电能计量不丢;电流进入量程(正常负载)后瞬时量即稳定可信。这是 5(80)A 大量程表对极小负载的固有特性,非缺陷、非解码问题
  • 排错提示:若日后看到 DDSU666「功率一直 0」,先确认负载电流是否在 Imin 以上——多半是负载太轻而非链路故障;可用 scripts/modbus_cli probe --fc 3 --address 0x2000 --count 160x2004/0x2005 原始寄存器是否真为全零佐证。