Modbus Python Schneider PM5300 - PullRequest
       153

Modbus Python Schneider PM5300

2 голосов
/ 17 июня 2020

Я пытаюсь получить напряжение или ток от измерителя 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 в списке регистров совпадает с текущим (4 - регистр хранения).

Журнал и печать с порядком байтов. Литтл:

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

With Endian.Big результат: -4.591774807899561e-41

Большое спасибо!

1 Ответ

2 голосов
/ 17 июня 2020

Ваша проблема в номере регистра, который вы пытаетесь прочитать. На 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)

Это должно дать текущее среднее значение согласно карте вашего счетчика.

У меня сейчас нет доступа к счетчику, но если мои записи верны, порядок байтов должен быть byteorder=Endian.Big, wordorder=Endian.Little, так что вы Возможно, вы захотите поиграть с этим и в своем коде.

Чтение этого вопроса может стоить вашего времени, в нем есть код, который, я думаю, нацелен на то же семейство устройств Schneider Electri c .

Я бы сказал, что было бы лучше, если бы вместо явно правильного чтения вы получили бы неправильную адресную ошибку, которую вы должны получить в этом случае. Я предполагаю, что они хотели оставить открытой возможность добавления дополнительных регистров на карту, и они оставили ее неограниченной.

EDIT: Как обсуждалось в комментариях ниже, правильный регистр для чтения для текущего в среднем 3009, поэтому запрос должен быть:

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

Некоторые устройства дают вам номера регистров хранения, начиная с 40001. Для pymodbus и других первый регистр хранения имеет номер 0, поэтому, если карту Modbus устройства вы должны прочитать регистр номер 45125, например, вам нужно вычесть 40001, чтобы получить address для pymodbus :

address=45125-40001=5124

Случай, с которым вы имеете дело Здесь еще больше раздражает: карта начинается с регистра 1, поэтому вам нужно вычесть 1.

Как вы можете видеть на следующем снимке экрана:

ModbusPoll screenshot

ModbusPoll следует тому же логу c: по умолчанию вам нужно ввести 0 для регистра 40001 (или 10 для регистра 40011. Если вы установите флажок PL C адреса, вам нужно будет ввести r 1 для чтения с адреса 40001.

Да, я знаю, сбивает с толку!

Обратите внимание, что в вопросе в приведенной выше ссылке не упоминается смещение -1. Некоторые устройства (например, ваше!) Не позволяют читать с "неправильного" регистра. Таким образом, если вы хотите прочитать текущее среднее значение (которое является FLOAT32 и, следовательно, занимает два регистра), вам нужно начать чтение из регистра 3009 и прочитать два регистра (да, на карте указано 3010, но имейте в виду смещение -1). Если вместо этого вы начинаете с регистра 3010, вы фактически пытаетесь прочитать верхнюю половину текущего среднего и нижнюю половину следующей переменной (текущий дисбаланс). Поскольку вы не сможете получить какие-либо полезные данные, потому что вы читаете две смешанные переменные, вы получите ошибку. Опять же, не лучшая ошибка; он должен хотя бы намекнуть на то, что вы делаете неправильно, но, увы!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...