Modbus Error: [Input/Output] No Response received from the remote unit

蹲街弑〆低调 提交于 2019-11-29 08:13:56

When working with modbus, even if you're using an high-level library, it's always useful to have close at hand the offical modbus documentation. With the documentation, you can check what each byte of your frame means:

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

The first byte is the device address (0x01)

The second byte is the function code (0x04, Read Input Registers)

Third and fourth bytes are the starting position (0x00, 0x00)

Fifth and sixth bytes are the quantity of outputs (0x00, 0x01)

The last 2 bytes are the CRC control (0x31, 0xCA)

This means that you are asking for one (0x00, 0x01) registers from the input registers (0x04) from the first position in memory (0x00, 0x00) from device with address 1 (0x01).

The frame by itself is correct, and if the device software/firmware follows the modbus standard, you should have an answer: the register that you asked for OR an error frame (0x01, 0x80, crc, crc).

This said, we can check why you do not receive an answer from your device. For doing this, if you're not sure about your code/on what you're asking/how your device behave, you can use an external tool to compare the results. I'd suggest you somethink like docklight, that helps you to set up your connection and send/receive modbus frame.

First thing I'd check are the connection parameters:

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

Method is correct, since is the protocol you're asking for.

The port is correct, otherwise it gives back a system error.

Timeout is what raise the error: in a given time, no response was received. Anyway the problem is probably not here, since you set a high value for timeout.

Stopbits should not interfere with the frame reception.

The problem could be in baudrate and parity: an error here can cause the error raised by your code.

If you do not know the correct value for baudrate and/or parity, you can try with the most commons baudrates and the parity values: 'N', 'E', 'O', 'M', 'S' (stands for: None, Even, Odd, Mark, Space. Default is None).

If i've to bet, i'd start by replacing Even parity with None (parity = 'N').

If you still have the problem, the device address (0x01) may be wrong. The address can be represented a value from 0 (0x00) to 255 (0xFF).

By protocol standard, even if the starting address (0x00, 0x00), the quantity of outputs (0x00, 0x01) or the crc (0x31, 0xCA) are wrong, the device should respond something, but it's no always like that: if you think you're in this situation, research for device's specific documentation.

The last possibility is to use a low level library, such as PySerial, and you define your own protocol.

Check this Stack_post.

You can handle the error:

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.')

[NOTE]:

  • In many cases, RTU parity is None: parity='N'
  • Make sure from root permission on your serial port (/dev/cu.SLAB_USBtoUART).

I was able to work around this issue by setting the constant RetryOnEmpty to True.

from pymodbus.constants import Defaults
Defaults.RetryOnEmpty = True

It also may be useful to configure a timeout and some retries.

Defaults.Timeout = 5
Defaults.Retries = 5

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!