Modbus 错误: [输入/输出] 未收到来自远程设备的响应



I' 尝试使用串行连接从我的 Mac 笔记本电脑连接到 Modbus 设备 (MR-SI4),该连接使用 USB RS485 转换器"安装"到/dev/cu.SLAB_USBtoUART上。

这是我的代码:

import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
from pymodbus.constants import Endian
from pymodbus.constants import Defaults
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
from pymodbus.transaction import ModbusRtuFramer
# settings for USB-RS485 adapter
SERIAL = '/dev/cu.SLAB_USBtoUART'
BAUD = 19200
# set Modbus defaults
Defaults.UnitId = 1
Defaults.Retries = 5
client = ModbusClient(method='rtu', port=SERIAL, stopbits=1, bytesize=8, timeout=3, baudrate=BAUD, parity='E')
connection = client.connect()
print "Readout started"
#result = client.read_discrete_inputs(0)
#result = client.read_holding_registers(12,19)
result = client.read_input_registers(0,1)
print(result)

控制台中的输出为:

$ sudo python test.py 
Readout started
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:send: 0x1 0x4 0x0 0x0 0x0 0x1 0x31 0xca
DEBUG:pymodbus.client.sync:will sleep to wait for 3.5 char
DEBUG:pymodbus.transaction:recv: 
DEBUG:pymodbus.transaction:getting transaction 1
Modbus Error: [Input/Output] No Response received from the remote unit

我很想得到一点帮助来理解我遇到的错误。我尝试了pymodbus的配置以及不同的功能,例如read_discrete_inputsread_holding_registers。有什么帮助吗?

谢谢

在使用 modbus 时,即使您使用的是高级库,随身携带官方 modbus 文档总是很有用的。 通过文档,您可以检查帧的每个字节的含义:

0x01 0x04 0x00 0x00 0x00 0x01 0x31 0xCA

第一个字节是设备地址(0x01)

第二个字节是函数代码(0x04, Read Input Registers)

第三个和第四个字节是起始位置(0x00, 0x00)

第五和第六个字节是输出的数量(0x00, 0x01)

最后 2 个字节是 CRC 控制(0x31, 0xCA)

这意味着您要求从输入寄存器(0x04)从存储器中的第一个位置(0x00, 0x00)地址为 1(0x01)的设备(0x00, 0x01)寄存器。

帧本身是正确的,如果设备软件/固件遵循modbus标准,您应该有一个答案:您要求的寄存器或错误帧(0x01, 0x80, crc, crc)

也就是说,我们可以检查为什么您没有从设备收到答案。为此,如果您不确定您的代码/您要问的内容/设备的行为方式,您可以使用外部工具来比较结果。我建议你像docklight一样思考,它可以帮助你建立连接和发送/接收modbus框架。

我要检查的第一件事是连接参数:

client = ModbusClient(method='rtu', port=SERIAL, stopbits=1, bytesize=8, timeout=3, baudrate=BAUD, parity='E')

方法是正确的,因为这是您要求的协议。

端口正确,否则会返回系统错误。

超时是引发错误的原因:在给定的时间内,未收到响应。无论如何,问题可能不在这里,因为您为超时设置了很高的值。

停止位不应干扰帧接收。

问题可能出在波特率和奇偶校验上:此处的错误可能会导致代码引发的错误。

如果您不知道波特率和/或奇偶校验的正确值,您可以尝试使用最常见的波特率和奇偶校验值:'N', 'E', 'O', 'M', 'S'(代表:无、偶数、奇数、标记、空格。默认值为"无")。

如果我必须打赌,我会首先将偶数平价替换为无(parity = 'N')。

如果问题仍然存在,则设备地址 (0x01) 可能是错误的。地址可以表示为0(0x00)到255(0xFF)之间的值。

根据协议标准,即使起始地址(0x00, 0x00),输出数量(0x00, 0x01)或crc(0x31, 0xCA)是错误的,设备也应该做出一些响应,但并不总是这样:如果您认为自己处于这种情况,请研究设备的特定文档。

最后一种可能性是使用低级库,如 PySerial,并定义自己的协议。

我能够通过将常量RetryOnEmpty设置为True来解决此问题。

from pymodbus.constants import Defaults
Defaults.RetryOnEmpty = True

配置超时和一些重试也可能很有用。

Defaults.Timeout = 5
Defaults.Retries = 5

https://pymodbus.readthedocs.io/en/v1.3.2/library/constants.html

检查此Stack_post。

您可以处理以下错误:

if not result.isError():
'''isError() method implemented in pymodbus 1.4.0 and above'''
print(result.registers)  # Note.
else:
# Handle Error.
print('Unable to read or there is the connection problem.')

[]:

  • 在许多情况下,RTU 奇偶校验为"无":parity='N'
  • 确保从串行端口上的root权限(/dev/cu.SLAB_USBtoUART)。

我也有类似的错误,没有响应。我的设备地址错误。它是 1,即单位 = 1。它应该是零。 即client.read_holding_registers(500,1,unit=0)

import pymodbus
from pymodbus.client.sync import ModbusSerialClient
client = ModbusSerialClient( method = 'rtu', port = "COM4", stopbits = 1, 
bytesize = 8, baudrate=9600 , parity= 'N')
client.connect()
result = client.read_holding_registers(500,1,unit=0)
print(result)

0x0 0x3 0x1 0xf4 0x0 0x1 0xc5 0xd5

否则错误输出为

0x1 0x3 0x1 0xf4 0x0 0x1 0xc5 0xd5

相关内容

  • 没有找到相关文章

最新更新