Modbus Python 施耐德 PM5300

Modbus Python Schneider PM5300

我正在尝试从 PM5300 仪表获取电压或电流,但总是只有 32768。 代码:

from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
import logging

FORMAT = ('%(asctime)-15s %(threadName)-15s '
          '%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)

UNIT = 0x01


def run_sync_client():
    client = ModbusClient(method='rtu', port='COM15', timeout=1, baudrate=19200, parity='E', stopbits=1, bytesize=8)
    client.connect()

    request = client.read_holding_registers(address=43010, count=2, unit=UNIT)
    result = request.registers
    print(result)
    decoder = BinaryPayloadDecoder.fromRegisters(result, Endian.Little, wordorder=Endian.Big)
    #dc2 = (decoder.decode_32bit_float() + 32768 /1000)
    #print(dc2)
    print(decoder.decode_32bit_float())


    client.close()


if __name__ == "__main__":
    run_sync_client()

寄存器列表中地址3010与current匹配(4为保持寄存器)

用Endian.Little记录和打印:

2020-06-16 20:11:24,349 MainThread      DEBUG    transaction    :115      Current transaction state - IDLE
2020-06-16 20:11:24,349 MainThread      DEBUG    transaction    :120      Running transaction 1
2020-06-16 20:11:24,350 MainThread      DEBUG    transaction    :219      SEND: 0x1 0x3 0xa8 0x2 0x0 0x2 0x45 0xab
2020-06-16 20:11:24,350 MainThread      DEBUG    sync           :75       New Transaction state 'SENDING'
2020-06-16 20:11:24,350 MainThread      DEBUG    transaction    :228      Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2020-06-16 20:11:24,364 MainThread      DEBUG    transaction    :304      Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2020-06-16 20:11:24,365 MainThread      DEBUG    transaction    :233      RECV: 0x1 0x3 0x4 0x80 0x0 0x80 0x0 0xb2 0x33
2020-06-16 20:11:24,365 MainThread      DEBUG    rtu_framer     :180      Getting Frame - 0x3 0x4 0x80 0x0 0x80 0x0
2020-06-16 20:11:24,365 MainThread      DEBUG    factory        :266      Factory Response[ReadHoldingRegistersResponse: 3]
2020-06-16 20:11:24,365 MainThread      DEBUG    rtu_framer     :115      Frame advanced, resetting header!!
2020-06-16 20:11:24,366 MainThread      DEBUG    transaction    :383      Adding transaction 1
2020-06-16 20:11:24,366 MainThread      DEBUG    transaction    :394      Getting transaction 1
2020-06-16 20:11:24,366 MainThread      DEBUG    transaction    :193      Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
[32768, 32768]
**2020-06-16 20:11:24,366 MainThread      DEBUG    payload        :312      [32768, 32768]**
2020-06-16 20:11:24,367 MainThread      DEBUG    payload        :368      [b'\x00\x80', b'\x00\x80']
1.1755122874426309e-38

与 Endian.Big 结果:-4.591774807899561e-41

非常感谢!

您的问题出在您尝试读取的寄存器编号上。在 pymodbus 上,您必须将寄存器指示为绝对地址编号;您不必像以前那样将 40000 添加到 Modbus 映射。

只需更改此行:

request = client.read_holding_registers(address=43010, count=2, unit=UNIT)

至:

request = client.read_holding_registers(address=3010, count=2, unit=UNIT)

这应该会根据您仪表的 map 给出当前平均值。

我现在无法访问仪表,但如果我的笔记是正确的,字节顺序应该是 byteorder=Endian.Big, wordorder=Endian.Little 所以你可能也想 fiddle 在你的代码中使用它。

阅读 可能值得您花时间,它有一些代码我认为是针对同一系列的 Schneider Electric 设备。

我认为,如果您得到的不是明显正确的读数,而是错误的地址错误,那会更好,这正是您在这种情况下应该得到的结果。我想他们想继续打开向地图添加更多寄存器的选项,并且他们保持它不受限制。

编辑: 正如下面评论中所讨论的,要读取当前平均值的正确寄存器是 3009,因此请求应该是:

request = client.read_holding_registers(address=3009, count=2, unit=UNIT)

Some devices give you holding register numbers starting from 40001. For pymodbus and others the first holding register is number 0, so if the Modbus map of the device 你应该阅读 register数字 45125,例如,您需要减去 40001 以获得 address for pymodbus:

address=45125-40001=5124

你在这里处理的情况更烦人:映射从寄存器 1 开始,所以你需要减去 1。

如您在以下屏幕截图中所见:

ModbusPoll 遵循相同的逻辑:默认情况下,您必须为寄存器 40001 输入 0(或为寄存器 40011 输入 10。如果单击复选框 PLC 地址,则必须输入 1 才能从地址 40001 读取。

是的,我知道,令人困惑!

请注意,上面 link 中的问题 没有 提到 -1 偏移量。有些设备(比如你的!)不会让你从 "the wrong" 寄存器中读取。这样,如果您想读取当前平均值(这是一个 FLOAT32,因此占用两个寄存器),您需要从寄存器 3009 开始读取并读取两个寄存器(是的,地图显示 3010,但请记住 -1 偏移量)。相反,如果您从寄存器 3010 开始,您实际上是在尝试读取当前平均值的上半部分和下一个变量(当前不平衡)的下半部分。由于您将无法获得任何有用的数据,因为您正在读取两个混淆的变量,因此您会收到错误消息。同样,这不是最好的错误;它至少应该给你一些提示,让你知道你做错了什么,但是唉!

我有这种格式的解决方案,PM5500 系列使用 ieee 格式来浮动数据。