You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否使用同一个pymodbus BinaryPayloadDecoder对象进行两次解码?

为什么同一个BinaryPayloadDecoder对象无法多次解码同一组寄存器?

没错,BinaryPayloadDecoder是流式解码的设计——它内部会维护一个读取偏移量,每次调用decode_32bit_float、decode_32bit_int这类解码方法时,都会消耗对应长度的寄存器数据,偏移量同步向后推进。

你第一次调用decode_32bit_float时,已经把手里的2个寄存器(刚好对应32位浮点数的4字节)全部读取完毕,此时解码器内部已无剩余数据。第二次再调用decode_32bit_int,自然会因为缺少足够的字节数抛出struct.error。

解决办法

最直接的方式就是像你已经尝试的那样,每次解码前重新创建一个BinaryPayloadDecoder对象,让每个解码器都从寄存器数据的起始位置开始读取:

from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian

registers = [0x41b7, 0x7873]
# 解码浮点数
decoder_float = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.BIG, wordorder=Endian.BIG)
myfloat = decoder_float.decode_32bit_float()
print("reg = ", myfloat)

# 重新创建解码器解码整数
decoder_int = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.BIG, wordorder=Endian.BIG)
myint = decoder_int.decode_32bit_int()
print("reg = ", myint)

如果不想重复写创建解码器的代码,也可以封装一个小函数复用逻辑:

from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian

def decode_registers(registers, decode_func, byteorder=Endian.BIG, wordorder=Endian.BIG):
    decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=byteorder, wordorder=wordorder)
    return getattr(decoder, decode_func)()

registers = [0x41b7, 0x7873]
myfloat = decode_registers(registers, "decode_32bit_float")
myint = decode_registers(registers, "decode_32bit_int")
print("float: ", myfloat)
print("int: ", myint)

补充说明

BinaryPayloadDecoder并没有提供公开方法重置内部的读取偏移量,没法让同一个解码器回到起始位置重新读取数据。这种设计是为了适配流式数据场景(比如从串口/网络持续接收数据并解码),而非针对同一组数据做多次不同格式的解码。

内容的提问来源于stack exchange,提问作者SWood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 23:50:59