【发布时间】:2020-01-22 11:10:31
【问题描述】:
我正在尝试使用modbus-tk 通过 RS-485 网络通过 Modbus RTU 与设备进行串行通信。
为了了解modbus-tk的使用方法,我尝试查询:
- 输入寄存器:
Year of Manufacture - 注册地址:
0x7543 = 30019 - 设备:
1 - 数据类型:16 位整数
- 值 =
2019(使用 free master modbus simulator 验证)。
这是我使用的代码,主要基于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
这个例外似乎是针对 if the slave has returned an error
你认为我做错了什么?我是这个图书馆的新手。
我读过的内容
-
Can't connect to slave with Python's modbus_tk,我正在使用
pyserial >= 3.1 - 以及
modbus-tk标签下的所有其他问题、Google Groups 中的一些帖子以及 repo 的示例 +README.md
设备细节
- 设备: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
**编辑 1**
根据@Brits 的评论,我将注册表地址更新为正确的功能代码和数据框地址。
**编辑 2**
更新了问题,因为在更正确的库使用后我得到了一个不同的错误。
【问题讨论】:
-
Modbus 寻址可能有点混乱。 0x7543(30019)在与大多数库一起使用时转换为功能代码 3(READ_HOLDING_REGISTERS)寄存器 18(十进制 - 数据帧地址基于 0)(没有使用 modbus-tk,但是当您单独传递函数时,我强烈怀疑这是问题所在) 有关wikipedia 和this question 的更多信息
-
好的,谢谢你指出@Brits!我确实有点困惑。我已经纠正了问题并编辑了问题。我仍然得到相同的
ModbusInvalidResponseError,还有其他想法吗? -
我在想我不是在制作 Modbus 从站,所以我从我的问题中删除了那部分。现在我收到了
ModbusError。有关更多详细信息,请参阅相关回溯 -
异常代码 3 是“非法数据值”(意味着请求中的某些内容无效)。由于我没有使用 modbus-tk 很难评论太多,但建议尝试
logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 18, 1))(从示例代码修改)。我怀疑一个问题可能是最后一个参数,quantity_of_x,默认为 0。这个参数成为 modbus 请求数据包中的“寄存器数量”; 0 对此无效(请求不获取寄存器)。 -
你好@Brits!再次感谢您回圈,您确实是正确的!我更仔细地阅读了源代码,我意识到
quantity_of_x参数不应保留为0的默认值。我想知道为什么在库中指定了默认值,如果它永远不会起作用。