Pymodbus: неверный счетчик байтов в ответ - PullRequest
1 голос
/ 19 июня 2019

Мы запрашиваем 14 ответов от устройства RS485, и иногда полученный ответ не имеет 9 байтов, которые он настроил.Это потому, что он отвечает иногда в 3 аргумента.

Normal: 
CALL->     01 04 00 00 00 02 71 CB 
RESPONSE-> 01 04 04 43 59 E6 66 F4 59


Error:
CALL->      01 04 00 00 00 02 71 CB 
RESPONSE -> 01 04 04 43
            59 CC CD AA 86 

Когда происходит ошибка, я получаю следующее сообщение от pymodbus:

DEBUG:pymodbus.transaction: Incomplete message received, Expected 9 bytes Recieved 4 bytes !!!!
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x1 0x4 0x4 0x3e
DEBUG:pymodbus.framer.rtu_framer:Frame check failed, ignoring!!
DEBUG:pymodbus.framer.rtu_framer:Resetting frame - Current Frame in buffer - 0x1 0x4 0x4 0x3e
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'

Я пытался перевести сон в режим ожидания, чтобы он не разрушал устройство вызовами, ноя получаю их в любом случае.Я также прочитал https://wingpath.co.uk/docs/modtest/troubleshoot.html, и они говорят это:

"Wrong byte count in response: XXX when expecting XXX"

The byte count in the response sent by the slave is not what was expected for the count that ModTest sent in the request.

Turn on tracing to get more information.

Check that your slave is functioning correctly.

If you want ModTest to accept the response even though it is incorrect, you could deselect Strict Checking.

Но я не знаю, как активная трассировка на PYMODBUS, функция верна, а другая для библиотекичто я не пользуюсь, я думаю,

Код выглядит так

from __future__ import division
import pymodbus
import serial
from pymodbus.pdu import ModbusRequest
from pymodbus.client.sync import ModbusSerialClient as ModbusClient #initialize a serial RTU client instance
from pymodbus.transaction import ModbusRtuFramer
from time import sleep
from pymodbus.constants import Endian              # Nodig voor 32-bit float getallen (2 registers / 4 bytes)
from pymodbus.payload import BinaryPayloadDecoder  # Nodig voor 32-bit float getallen (2 registers / 4 bytes)
from pymodbus.payload import BinaryPayloadBuilder  # Nodig om 32-bit floats te schrijven naar register

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

#
method = "rtu"
port = "COM1"
baudrate = 2400
stopbits = 1
bytesize = 8
parity = "N"
timeout = 10 # I SET THIS TO 10 MAYBE IT WOULD HELP BUT DIDN'T
retries = 5  # SAME THING WITH THIS ONE
#
try:
    client = ModbusClient(method = method, port = port, stopbits = stopbits, bytesize = bytesize, parity = parity, baudrate = baudrate, timeout = timeout, retries = retries)
    connection = client.connect()
    print (connection)
except:
    print ("Modbus connectie error")
#
def 420 (y):
    variables = [0,6,12,18,24,30,36,70,72,74,76,78,342,344]
    labels = ["Voltage","Corriente","Potencia_Activa","Potencia_Aparente","Potencia_Reactiva","Factor_Potencia","Angulo_Fase","Frecuencia","Potencial_Activa_Consumida","Potencia_Activa_Inyectada","Potencia_Reactiva_Consumida","Potencia_Reactiva_Inyectada","Energia_Activa_Total","Energia_Reactiva_Total"]
    unidades = ["V","A","W","VA","VAr","%","Grados","HZ","kWh","kWh","kVArh","kVArh","kWh","kVArh"]
    LISTA = []
    h = 0
    hh = 0
    for xx in variables:
        try:
            data = client.read_input_registers(xx, 2, unit=1)
            decoder = BinaryPayloadDecoder.fromRegisters(data.registers, Endian.Big)
            eastron = round(decoder.decode_32bit_float(), 3)
            weaito = str(labels[h]) + " = " + str(eastron) + " " + str(unidades[hh])
            LISTA.append(weaito)
            h = h + 1
            hh = hh + 1
            sleep(0.5)
        except:
            print ("PICO")
            sleep(1)
    print(LISTA)

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

1 Ответ

0 голосов
/ 19 июня 2019

Вы, похоже, испытываете известную проблему с интервалом между символами.

Хотя есть и простой обходной путь.Во-первых, убедитесь, что вы используете pymodbus версии 2.2.0 (вы можете сделать это, открыв терминал командной строки в Windows и набрав pip list, если у вас правильно настроен путь, в противном случае вам нужно перейти в папку Python сценариев, где pip.exe сохраняется).

Затем измените свой код, добавив аргумент strict, объявленный как False:

....
client = ModbusClient(method = method, port = port, stopbits = stopbits, bytesize = bytesize, parity = parity, baudrate = baudrate, timeout = timeout, retries = retries)
client.strict = False    #Use Modbus interchar spacing as timeout to prevent missing data for low baudrates
connection = client.connect()
...

Это определит расстояние между символами в соответствии со спецификацией Modbus,в 1,5 раза по битовому времени на выбранной скорости передачи вместо использования значения по умолчанию от socket.interCharTimeout:

self._t0 = float((1 + 8 + 2)) / self.baudrate
self.inter_char_timeout = 1.5 * self._t0

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

Если ваша проблема не решена, я думаю, у вас может быть проблема с оборудованием.Я бы посоветовал вам отложить свой код на некоторое время и попробовать прочитать регистры с помощью QModMaster или чего-то подобного, чтобы убедиться, что ваше оборудование работает должным образом.(у вас могут возникнуть шумы или проблемы с заземлением, которые укорачивают ваши кадры, если вы хотите, чтобы некоторые указатели были на этом фронте, отредактируйте ваш вопрос, включив в него более подробную информацию о вашем оборудовании, например: тип устройств и способ их подключения).

...