2

I'm use "pymodbus" lib to connect PLC devices. The device is used Modbus RTU over TCP that devices will return the temperature and humidity of the environment.

map address list

  • 0001: temperature
  • 0002: humidity

I performed once to get value and it can succeed. But I'm using while loop sometimes get error. I don't know why.

code:

from time import sleep
from pymodbus.client.sync import ModbusTcpClient
from pymodbus.framer.rtu_framer import ModbusRtuFramer

from pymodbus.register_read_message import ReadHoldingRegistersResponse

client = ModbusTcpClient(host='192.168.1.1', port=5000, framer=ModbusRtuFramer)    
client.connect()
while True:
    rr = client.read_holding_registers(0, 2, unit=1)

    if isinstance(rr, ReadHoldingRegistersResponse):
        temp = rr.registers
        print(temp)
    else:
        print('error')
    sleep(1)
client.close()

output:

> ...
> [189, 444]
> [189, 443]
> [189]
> error
> error
> ...

We can see that sometimes the result is obtained normally, sometimes the result is incomplete, and sometimes the result is not available.

What should I do to solve this problem, I want to monitor this device. Thank you.

frank
  • 81
  • 1
  • 5
  • I have never seen this. The only real difference I have is not using `framer=ModbusRtuFramer` so perhaps the answer lies in what that does. Certainly for me, it's either a full list or no list (with an Exception thrown), but not a partial read. – roganjosh Mar 28 '19 at 14:52
  • Hi, thank you. If I don't use `framer = ModbusRtuFramer` will get an error. – frank Mar 28 '19 at 15:09
  • Error msg: `AttributeError: 'ModbusIOException' object has no attribute 'registers'` – frank Mar 29 '19 at 00:56
  • 1
    Sometimes, the slave device would not be able to process the requests (due to limitations on the read/write buffers) when read very fast (like in this case every 1 sec) and that could result in `ModbusIOException`. Enable debug logs and see what exactly is happening over the socket . I would use a higher interval between polls in any case. – Sanju Mar 29 '19 at 14:49

2 Answers2

0

Yes, I see this all the time in my pymodbus code. I suspect there's something wrong with the implementation when doing succesive reads. What I do, is quite simply, to retry the failed read after a slight delay. And that usually gets it working again. Alternatively, try closing and re-connecting the client and re-attempt the reading. Also try increasing the sleep time. Let me know how it goes!

Sergio Flores
  • 399
  • 1
  • 8
  • Hi, Thank you. I add `client.close()` `client.connect()` in the else case. The same problem still occurs. – frank Mar 29 '19 at 00:55
  • Mmm, yes tbh I see it all the time, but in my application is not relevant since I need to read every 5 mins, and I restart the python script to do so. I have seen the isuse, but dissapears in the next run. So, how about that, instead of running in a loop, put it in a cron with x seconds delay, connect-read-store-disconnect – Sergio Flores Mar 29 '19 at 01:39
0

You can try to print what you have in your temp variable in case it's not instance of ReadHoldingRegisterResponse - it may help.

What I use to have sometimes when the device didn't sent the response yet is:

Modbus Error: [Input/Output] No Response received from the remote unit
Diana
  • 66
  • 6