在 raspberry pi 3B 上的 python 代码中使用 python 库 pymodbus2.5.3 将寄存器解码为 32 位浮点大端

decode register to 32bit float big endian in python code on raspberry pi 3B with python library pymodbus2.5.3

我正在尝试在我的 raspberry pi 3B 上获取使用 modbus rtu 通信协议的传感器变送器的数据流。我可以使用 pymodbus2.5.3 库获取数据。 为此,我使用此代码:

from pymodbus.client.sync import ModbusSerialClient # Import the pymodbus library part for syncronous master (=client)

client = ModbusSerialClient(
    method='rtu', #Modbus Modus = RTU = via USB & RS485
    port='/dev/ttyUSB0', #Connected over ttyUSB0, not AMA0
    baudrate=19200, #Baudrate was changed from 38400 to 19200
    timeout=3, #
    parity='N', #Parity = None
    stopbits=2, #Bites was changed from 1 to 2
    bytesize=8 #
)

if client.connect():  # Trying to connect to Modbus Server/Slave
    #Reading from a holding register
    res = client.read_holding_registers(address=100, count=8, unit=1) #Startregister = 100, Registers to be read = 8, Answer size = 1 byte



    if not res.isError(): #If Registers don't show Error
        print(res.registers) #Print content of registers
    else:
        print(res) #Print Error Message, for meaning look at (insert git hub)

else: #If not able to connect, do this
    print('Cannot connect to the Transmitter M80 SM and Sensor InPro 5000i.')
    print('Please check the following things:')
    print('Does the RS485-to-USB Adapter have power? Which LEDs are active?')
    print('Are the cables connected correctly?')

并得到以下输出:

[15872, 17996, 16828, 15728, 16283, 45436, 16355, 63231]

在 Modbus 轮询和从站程序的帮助下,我知道这些结果应该被解码为: [0.125268, --, 23.53, --, 1.21094, --, 1.77344, --]

为了获得正确的结果,我尝试了 pymodbus github 建议的命令 .decode():

res.decode(word_order = little, byte_order = little, formatters = float64)

[我知道这些不是必需的选项,但我复制了建议的 github 代码以检查它是否有效。]

将代码段放入代码后,更改的部分如下所示:

    if not res.isError(): #If Registers don't show Error
        res.decode(word_order = little, byte_order = little, formatters = float64)
        print(res.registers) #Print content of registers
    else:
        print(res) #Print Error Message, for meaning look at (insert git hub)

当我 运行 这段代码时,我得到以下输出,可以追溯到解码段:

NameError: name 'little' is not defined

在此之后,我还导入了 pymodbus 部分翻译。但它显示相同的输出。

如何解码传入的数据?

您可以使用 BinaryPayloadDecoder 来帮助解码您的负载,这是一个简化的示例,如果需要,请更改 Endian.BigEndian.Little

if client.connect():  # Trying to connect to Modbus Server/Slave
    #Reading from a holding register
    res = client.read_holding_registers(address=100, count=8, unit=1) #Startregister = 100, Registers to be read = 8, Answer size = 1 byte

    # ====== added code start ======
    decoder = BinaryPayloadDecoder.fromRegisters(res.registers, Endian.Little, wordorder=Endian.Little)
    first_reading = decoder.decode_32bit_float()
    second_reading = decoder.decode_32bit_float()
    # ====== added code end ======

    if not res.isError(): #If Registers don't show Error
        print(res.registers) #Print content of registers
    else:
        print(res) #Print Error Message, for meaning look at (insert git hub)

记得在顶部导入 from pymodbus.payload import BinaryPayloadDecoder 并在最终代码中添加必要的异常处理程序。

Reference document: https://pymodbus.readthedocs.io/en/latest/source/library/pymodbus.html#pymodbus.payload.BinaryPayloadDecoder