0

0

如何在 Python 中按自定义字节序(非标准大端/小端)解析电表寄存器数据

花韻仙語

花韻仙語

发布时间:2026-01-03 18:15:08

|

596人浏览过

|

来源于php中文网

原创

如何在 Python 中按自定义字节序(非标准大端/小端)解析电表寄存器数据

本文详解如何将 modbus 读取的 4 个 16 位寄存器(如 `[3468, 204, 0, 2080]`)按特定十进制拼接规则(如 `20434682080`)正确解析,适用于电表等工业设备的非标准数值编码场景。

在使用 pymodbus 读取电表(如某些国产或定制化功率计量设备)的寄存器时,常会遇到一种非标准数值编码方式:设备厂商未采用 IEEE 754 浮点、32/64 位整数的大端(BIG)或小端(LITTLE)字节序,而是将多个 16 位寄存器视为独立的十进制“数字块”,并按固定位置权重拼接成一个完整整数。

例如,读取到 result_ups.registers = [3468, 204, 0, 2080],目标值为 20434682080,其构成逻辑为:

20434682080 = 204 × 10⁸ + 3468 × 10⁴ + 0 × 10⁰ + 2080 × 10⁰?  ← 错误

实际观察可得:

  • 20434682080 拆分为:204 | 3468 | 0 | 2080 → 但直接拼接 204+3468+0+2080 = "204346802080"(长度不符)

更准确的逆向分析表明,该值实为 4 段 4 位十进制数的错位拼接,且顺序为 [1st, 2nd, 3rd, 4th] → 对应输出中的位置为:
✅ 204(占前 3 位) + 3468(次 4 位) + 0(第 3 段,补零为 0000?但此处为 0) + 2080(末 4 位)→ 不匹配。

而题目给出的期望结果 20434682080 共 11 位,分解为:

立即学习Python免费学习笔记(深入)”;

  • 204(3 位)
  • 3468(4 位)
  • 2080(4 位)
    → 中间缺失 1 位?注意原数组为 [3468, 204, 0, 2080],若按索引重排为 [204, 3468, 0, 2080],再拼接 "204"+"3468"+"0"+"2080" = "204346802080"(12 位),仍不符。

关键洞察来自答案提示:这是按寄存器索引加权的十进制组合,而非字节序问题。验证如下:

叮当好记-AI音视频转图文
叮当好记-AI音视频转图文

AI音视频转录与总结,内容学习效率 x10!

下载
registers = [3468, 204, 0, 2080]
# 按答案公式计算:
result = (
    registers[3]      # 2080 × 10⁰ = 2080
    + registers[0] * 10**4   # 3468 × 10000 = 34,680,000
    + registers[1] * 10**8   # 204 × 100,000,000 = 20,400,000,000
    + registers[2] * 10**12  # 0 × 1e12 = 0
)
print(result)  # 输出:20434682080 ✅

即:

  • registers[1](204)→ 权重 10⁸(亿位)
  • registers[0](3468)→ 权重 10⁴(万位)
  • registers[3](2080)→ 权重 10⁰(个位)
  • registers[2](0)→ 权重 10¹²(万亿位,此处为 0,故不影响)

因此,这不是 Endian.BIG 或 Endian.LITTLE 能解决的字节序问题,而是设备特有的寄存器数值映射协议

✅ 正确实现方案(集成到你的 pymodbus 代码中)

将原代码中的解码部分替换为加权拼接逻辑:

from pymodbus.client import ModbusTcpClient
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
import time

client_tcp = ModbusTcpClient('10.123.133.100', port=502)

while True:
    try:
        client_tcp.connect()
        while True:
            result_ups = client_tcp.read_holding_registers(1716, 4, unit=1, slave=1)
            if not result_ups.isError():
                regs = result_ups.registers  # [3468, 204, 0, 2080]
                # 按设备协议:regs[1]×1e8 + regs[0]×1e4 + regs[3] + regs[2]×1e12
                kwh_ups = (
                    regs[1] * 10**8
                    + regs[0] * 10**4
                    + regs[3]
                    + regs[2] * 10**12
                )
                print(f"Total kWh: {kwh_ups}")
            else:
                print("Modbus read error:", result_ups)
            time.sleep(1)
    except Exception as e:
        print("Connection error:", e)
        time.sleep(1)
    finally:
        client_tcp.close()

⚠️ 注意事项与建议

  • 务必查阅设备手册:该加权规则([1], [0], [3], [2])是此电表特有,其他设备可能完全不同(如 [3], [2], [1], [0] 或含符号位)。切勿假设通用。
  • 数据范围检查:10¹² 权重下,若 regs[2] 非零,结果可能超出 Python int 实际显示范围(虽 Python 支持任意精度,但需确认电表真实量程)。
  • 避免误用 BinaryPayloadDecoder:Endian.BIG + Endian.LITTLE 仅适用于标准二进制整型/浮点编码(如 32-bit int 大端存储为 [0x00, 0x12, 0x34, 0x56]),对十进制拼接无效。
  • 增强健壮性:添加 if len(regs) == 4: 校验,防止寄存器读取异常导致索引错误。
  • 单位与精度:确认 20434682080 是否为原始值(如 0.01kWh/LSB),可能需额外除以缩放因子(如 /100 得 204346820.80 kWh)。

通过理解设备协议本质而非强行套用字节序,你才能稳定、准确地将寄存器原始数据转化为业务所需的物理量。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

731

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

631

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

749

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1238

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

576

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

705

2023.08.11

python设置中文版教程合集
python设置中文版教程合集

本专题整合了python改成中文版相关教程,阅读专题下面的文章了解更多详细内容。

1

2026.01.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.8万人学习

SciPy 教程
SciPy 教程

共10课时 | 1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号