Modbus-TK получает Modbus Ошибка: код исключения = 3 - PullRequest
0 голосов
/ 21 января 2020

Я пытаюсь использовать modbus-tk для последовательной связи с устройством через Modbus RTU через сеть RS-485.

Чтобы понять, как использовать modbus-tk, я пытаюсь сделать запрос:

Year of Manufacture Register

Вот код, который я использую, основанный главным образом на rtumaster_example.py . Входные данные:

#!/usr/bin/env python3


import time
from collections import namedtuple
from logging import Logger

from serial import Serial
from modbus_tk import modbus_rtu
import modbus_tk.defines as cst  # cst = constants
from modbus_tk.utils import create_logger


PORT = "COM3"
SLAVE_NUM = 1
MODBUS_MASTER_TIMEOUT_SEC = 5.0

ModbusReg = namedtuple("ModbusInputRegister", ["name", "block_type", "address"])

year_of_manuf = ModbusReg(
    "year of manufacture", cst.HOLDING_REGISTERS, 18
)  # 0x7543 = 30019


logger = create_logger(name="console")  # type: Logger
serial_ = Serial(PORT)
modbus_master = modbus_rtu.RtuMaster(serial_)
modbus_master.set_timeout(MODBUS_MASTER_TIMEOUT_SEC)
modbus_master.set_verbose(True)
time.sleep(2)  # Per https://github.com/ljean/modbus-tk/issues/73#issuecomment-284800980

logger.info(
    modbus_master.execute(
        slave=SLAVE_NUM,
        function_code=cst.READ_INPUT_REGISTERS,
        starting_address=year_of_manuf.address,
    )
)

Выходные данные:

2020-01-21 10:38:09,031 INFO    modbus_rtu.__init__     MainThread      RtuMaster COM3 is opened
2020-01-21 10:38:11,048 DEBUG   modbus.execute  MainThread      -> 1-4-0-18-0-0-80-15
2020-01-21 10:38:11,077 DEBUG   modbus.execute  MainThread      <- 1-132-3-3-1
---------------------------------------------------------------------------
ModbusError                               Traceback (most recent call last)
<ipython-input-2-9afaebcf3a35> in <module>
      7     slave=SLAVE_NUM,
      8     function_code=cst.READ_INPUT_REGISTERS,
----> 9     starting_address=year_of_manuf.address,
     10 )

c:\path\to\venv\lib\site-packages\modbus_tk\utils.py in new(*args, **kwargs)
     37             ret = fcn(*args, **kwargs)
     38         except Exception as excpt:
---> 39             raise excpt
     40         finally:
     41             if threadsafe:

c:\path\to\venv\lib\site-packages\modbus_tk\utils.py in new(*args, **kwargs)
     35             lock.acquire()
     36         try:
---> 37             ret = fcn(*args, **kwargs)
     38         except Exception as excpt:
     39             raise excpt

c:\path\to\venv\lib\site-packages\modbus_tk\modbus.py in execute(self, slave, function_code, starting_address, quantity_of_x, output_value, data_format, expected_length)
    312                 # the slave has returned an error
    313                 exception_code = byte_2
--> 314                 raise ModbusError(exception_code)
    315             else:
    316                 if is_read_function:

ModbusError: Modbus Error: Exception code = 3

Похоже, это исключение, если the slave has returned an error

Что, по-вашему, я делаю неправильно? Я новичок в этой библиотеке.


Что я прочитал

Особенности устройства

  • Устройство: SST Sensing's OXY-L C -485
  • Modbus RTU, 9600/8-N-1
  • Руководство пользователя (раздел 7.1.2.1 содержит набор входных регистров)
  • Устройство подключено к Windows машине, на которой я запускаю этот Python скрипт

Пакеты

Я использую Python 3,6 Windows 10.

pyserial==3.4
modbus-tk==1.1.0

** РЕДАКТИРОВАТЬ 1 **

В соответствии с комментарием @Brits я обновил адреса своего реестра, чтобы они соответствовали кодам функций и адресам фреймов данных.

** РЕДАКТИРОВАТЬ 2 **

Обновлен вопрос, так как я получаю другую ошибку после более правильной библиотеки США. GE.

1 Ответ

0 голосов
/ 22 января 2020

Моей проблемой было отсутствие понимания метода Master.execute. Я не осознавал, что параметр quantity_of_x нужно было сделать ненулевым. Особая благодарность @Brits за помощь в указании на некоторые ключевые проблемы, с которыми я столкнулся в моем исходном коде.

Когда arg function_code == defines.READ_INPUT_REGISTERS, quantity_of_x означает сумму типа H (C, без знака) short, длина = 2 байта = 16 бит, источник ) для чтения ( исходный код modbus.py, строка 138 ).

Поскольку тип данных устройства для регистра year_of_manuf это 16-разрядное целое число без знака, правильное изменение заключалось в добавлении quantity_of_x=1 в качестве аргумента.

Функциональный ввод:

logger.info(
    modbus_master.execute(
        slave=SLAVE_NUM,
        function_code=cst.READ_INPUT_REGISTERS,
        starting_address=year_of_manuf.address,
        quantity_of_x=1,
    )
)

Выход:

2020-01-21 18:42:05,520 DEBUG   modbus.execute  MainThread      -> 1-4-0-18-0-1-145-207
2020-01-21 18:42:05,560 DEBUG   modbus.execute  MainThread      <- 1-4-2-7-227-250-137
2020-01-21 18:42:05,562 INFO    <ipython-input-1-2d4d0280e33d>.<module> MainThread      (2019,)
...