gpt4 book ai didi

python - modbus-tk 用于 Modbus RTU,读/写多个寄存器(fn 代码 23),返回异常代码 1

转载 作者:行者123 更新时间:2023-12-01 18:14:21 26 4
gpt4 key购买 nike

我正在使用 modbus-tk 通过 RS-485 网络通过 Modbus RTU 与设备进行串行通信。

我正在尝试弄清楚如何使用函数 23,READ_WRITE_MULTIPLE_REGISTERS。这是我第一次使用函数 23。这是我当前的实现:

response = modbus_master.execute(
slave=SLAVE_NUM,
function_code=cst.READ_WRITE_MULTIPLE_REGISTERS,
starting_address=2,
quantity_of_x=1,
output_value=[1],
)

运行此命令时,出现以下错误:Modbus 错误:异常代码 = 1

我在 Wikipedia 上查找了此异常代码,并查看:

Function code received in the query is not recognized or allowed by slave

您认为这是否意味着我的设备确实不支持此功能代码?或者我有语法问题/误用了这个函数吗?

我已将完整脚本放在下面。

<小时/>

完整代码示例

输入

#!/usr/bin/env python3


import time
from collections import namedtuple
from logging import Logger

from serial import Serial
from modbus_tk.modbus_rtu import RtuMaster
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

ModbusHoldingReg = namedtuple(
"ModbusHoldingRegister", ["name", "address", "last_read_value", "to_write_value"]
)
shutdown_delay = ModbusHoldingReg("shutdown delay", 2, 0, None) # sec

logger = create_logger(name="console") # type: Logger

serial_ = Serial(PORT)
modbus_master = RtuMaster(serial_)
modbus_master.set_timeout(MODBUS_MASTER_TIMEOUT_SEC)
modbus_master.set_verbose(True)
# Sleep some time per [1]
# [1]: https://github.com/ljean/modbus-tk/issues/73#issuecomment-284800980
time.sleep(2.0)

# Read/write from/to multiple registers
response = modbus_master.execute(
slave=SLAVE_NUM,
function_code=cst.READ_WRITE_MULTIPLE_REGISTERS,
starting_address=shutdown_delay.address,
quantity_of_x=1,
output_value=[1],
) # type: tuple
print(response)

输出

2020-01-31 10:43:24,885 INFO    modbus_rtu.__init__     MainThread      RtuMaster COM3 is opened
2020-01-31 10:43:26,890 DEBUG modbus.execute MainThread -> 1-23-0-2-0-1-0-23-0-1-2-0-1-55-131
2020-01-31 10:43:31,933 DEBUG modbus.execute MainThread <- 1-151-1-143-240
---------------------------------------------------------------------------
ModbusError Traceback (most recent call last)
<ipython-input-1-f42d200d6c09> in <module>
37 starting_address=shutdown_delay.address,
38 quantity_of_x=1,
---> 39 output_value=[1],
40 ) # type: tuple
41 print(response)

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 = 1
<小时/>

设备细节

  • 设备:SST Sensing 的 OXY-LC-485
  • Modbus RTU,9600/8-N-1
  • User Guide (第 7.1.2.1 节包含一组输入寄存器)
  • 设备已插入我运行此 Python 脚本的 Windows 计算机

套餐

我在 Windows 10 上使用 Python 3.6。

pyserial==3.4
modbus-tk==1.1.0

最佳答案

进一步回答@maxy; modbus spec指出异常代码 1(非法功能)意味着:

The function code received in the query is not an allowable action for the server (or slave). This may be because the function code is only applicable to newer devices, and was not implemented in the unit selected. It could also indicate that the server (or slave) is in the wrong state to process a request of this type, for example because it is unconfigured and is being asked to return register values.

因此,在这种情况下,我会说该设备不支持此命令。

但是鉴于另一个用户报告了此命令的问题,我认为值得检查编码:

1- Slave ID
23- Function Code
0, 2- Read Starting Address
0, 1- Quantity to Read
0, 23- Write Starting Address
0, 1 - Quantity to write
2, Write Byte Count
0,1, - Write Registers value
55,131 - CRC (have not checked)

这对我来说看起来是正确的,但有一个异常(exception);不清楚“写入起始地址”来自哪里(并且怀疑它与功能代码相同)。看着source :

pdu = struct.pack(
">BHHHHB",
function_code, starting_address, quantity_of_x, defines.READ_WRITE_MULTIPLE_REGISTERS,
len(output_value), byte_count
)

这对我来说看起来是错误的(defines.READ_WRITE_MULTIPLE_REGISTERS 将始终为 23)。代码在提交 dcb0a2f115d7a9d63930c9b4466c4501039880a3 中更改为这样;以前是:

pdu = struct.pack(
">BHHHHB",
function_code, starting_address, quantity_of_x, starting_addressW_FC23,
len(output_value), byte_count
)

这对我来说更有意义(你需要一种方法来传递地址来开始写入,而当前的界面似乎没有提供这个)。我已将此注释添加到 github issue .

因此,总而言之,您的问题可能是由于设备造成的,但即使设备支持该命令,我也不认为由于 modbus-tk 中的错误而导致该命令起作用。

关于python - modbus-tk 用于 Modbus RTU,读/写多个寄存器(fn 代码 23),返回异常代码 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60013544/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com