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

otm*_*ger 4 python modbus pymodbus3 pymodbus

我尝试使用“安装”/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)
Run Code Online (Sandbox Code Playgroud)

控制台中的输出是:

$ 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
Run Code Online (Sandbox Code Playgroud)

我希望能得到一些帮助来理解我遇到的错误。我尝试了 的配置以及或pymodbus等不同的功能。有什么帮助吗?read_discrete_inputsread_holding_registers

谢谢

Gsk*_*Gsk 6

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

0x01 0x04 0x00 0x00 0x00 0x01 0x31 0xCA
Run Code Online (Sandbox Code Playgroud)

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

第二个字节是功能码(0x04, Read Input Registers)

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

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

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

这意味着您需要从地址为 1 的设备的内存中第一个位置的(0x00, 0x01)输入寄存器中获取一个寄存器。(0x04)(0x00, 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')
Run Code Online (Sandbox Code Playgroud)

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

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

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

停止位不应干扰帧接收。

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

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

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

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

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

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

  • 这帮助我调试。谢谢! (2认同)