Pymodbus 读/写浮点数(实数)

xin*_*ose 6 python ethernet plc modbus

我的 AB Micro820 PLC 中有 modbus 映射设置。我有一个 40001 的数组用于写入,一个 42001 的数组用于读取。两者都是 200 个元素和 REAL 类型(32 位浮点数)。我目前可以读写,所以我知道代码可以工作,只是不正确。这些值被读/写为非常小的值(即4.58577478E-19)。有人能指出我正确的方向吗?

#!/usr/bin/env python

from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.client.sync import ModbusTcpClient

import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.INFO)

ip_address = "192.168.2.101"

client = ModbusTcpClient(ip_address)
if client.connect():    # connection is OK
    # write float
    builder = BinaryPayloadBuilder(endian=Endian.Little)
    builder.add_32bit_float(77.77)
    payload = builder.build()
    result  = client.write_registers(1, payload, skip_encode=True)
    # read floats
    result  = client.read_holding_registers(2001, 4)
    decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)
    print "read_holding_registers: " + str(decoder.decode_32bit_float())

    client.close()
Run Code Online (Sandbox Code Playgroud)

Mos*_*gey 7

总而言之:

\n

使用:

\n
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, Endian.Big, wordorder=Endian.Little)\n
Run Code Online (Sandbox Code Playgroud)\n

代替:

\n
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)\n
Run Code Online (Sandbox Code Playgroud)\n
\n

解释尝试:

\n

此包的BinaryPayloadDecoder.fromRegisters参数在文档中进行了描述。

\n

这种情况下我们应该注意:

\n
\n

byteorder \xe2\x80\x93 每个字的字节顺序

\n

wordorder \xe2\x80\x93 单词的字节序(当 wordcount >= 2 时)

\n
\n

我相信适合 modbus 寄存器(2 字节)字节顺序的值始终必须是 Endian.Big

\n

字顺序类似于字节顺序,但用于 modbus 寄存器。

\n

对于 Modbus TCP 始终必须是 byteorder=Endian.Big、wordorder=Endian.Little,因为由 2 个以上字节组成的值的字节顺序在协议规范OPEN MODBUS/TCP 规范(附录 B. 的数据编码)中精确指定非字数据)

\n

对于包含超过 2 个字节的 Modbus RTU 字节顺序值,协议规范中未准确指定此处以某种方式进行了描述

\n

大多数实现采用 Modbus TCP 方法并将浮点传输为 [2, 1, 4, 3] 字节。

\n

然而,还有其他可能性:

\n
    \n
  • [4, 3, 2, 1] - byteorder=Endian.Big, wordorder=Endian.Big
  • \n
  • [3, 4, 1, 2] - 字节顺序=Endian.Little,字序=Endian.Big
  • \n
  • [1, 2, 3, 4] - byteorder=Endian.Little, wordorder=Endian.Little
  • \n
\n