pyhys / minimalmodbus

Easy-to-use Modbus RTU and Modbus ASCII implementation for Python.
Apache License 2.0
308 stars 145 forks source link

No response error from Instrument after several successful readings in Modbus-RTU mode #57

Closed amandeep16 closed 4 years ago

amandeep16 commented 4 years ago

Hi,

I am trying to read a PV & SP values from a temperature controller by using while true condition in python script, it is running but every time after 5 -6 successful readings I am getting : No response from Instrument error. Please help in resolving this issue.

Log is as follows:

minimalmodbus.Instrument<id=0x76679bb0, address=1, mode=rtu, close_port_after_each_call=False, precalculate_read_size=True, clear_buffers_before_each_transaction=True, handle_local_echo=False, debug=False, serial=Serial(port='/dev/ttyUSB0', baudrate=2400, bytesize=8, parity='E', stopbits=1, timeout=10, xonxoff=False, rtscts=False, dsrdtr=False)> 78

~~ 2020-09-01, 09:03:40 ~~ MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): '\x01\x03\x00\x00\x00\x01\x84\n' (01 03 00 00 00 01 84 0A) MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0 MinimalModbus debug mode. No sleep required before write. Time since previous read: 30030.19 ms, minimum silent period: 16.04 ms. MinimalModbus debug mode. Response from instrument: '\x01\x03\x02\x00\x00¸D' (01 03 02 00 00 B8 44) (7 bytes), roundtrip time: 76.4 ms. Timeout for reading: 10000.0 ms.

MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): '\x01\x03\x00\x01\x00\x01ÕÊ' (01 03 00 01 00 01 D5 CA) MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0 MinimalModbus debug mode. Sleeping 12.48 ms before sending. Minimum silent period: 16.04 ms, time since read: 3.56 ms. MinimalModbus debug mode. Response from instrument: '\x01\x03\x02\x00N8p' (01 03 02 00 4E 38 70) (7 bytes), roundtrip time: 127.3 ms. Timeout for reading: 10000.0 ms.


~~ 2020-09-01, 09:04:10 ~~ MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): '\x01\x03\x00\x00\x00\x01\x84\n' (01 03 00 00 00 01 84 0A) MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0 MinimalModbus debug mode. No sleep required before write. Time since previous read: 30034.68 ms, minimum silent period: 16.04 ms. MinimalModbus debug mode. Response from instrument: '\x01\x03\x02\x00\x00¸D' (01 03 02 00 00 B8 44) (7 bytes), roundtrip time: 73.0 ms. Timeout for reading: 10000.0 ms.

MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): '\x01\x03\x00\x01\x00\x01ÕÊ' (01 03 00 01 00 01 D5 CA) MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0 MinimalModbus debug mode. Sleeping 12.45 ms before sending. Minimum silent period: 16.04 ms, time since read: 3.60 ms. MinimalModbus debug mode. Response from instrument: '\x01\x03\x02\x00N8p' (01 03 02 00 4E 38 70) (7 bytes), roundtrip time: 125.9 ms. Timeout for reading: 10000.0 ms.


~~ 2020-09-01, 09:04:40 ~~ MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): '\x01\x03\x00\x00\x00\x01\x84\n' (01 03 00 00 00 01 84 0A) MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0 MinimalModbus debug mode. No sleep required before write. Time since previous read: 30034.79 ms, minimum silent period: 16.04 ms. MinimalModbus debug mode. Response from instrument: '\x01\x03\x02\x00\x00¸D' (01 03 02 00 00 B8 44) (7 bytes), roundtrip time: 86.8 ms. Timeout for reading: 10000.0 ms.

MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): '\x01\x03\x00\x01\x00\x01ÕÊ' (01 03 00 01 00 01 D5 CA) MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0 MinimalModbus debug mode. Sleeping 12.44 ms before sending. Minimum silent period: 16.04 ms, time since read: 3.60 ms. MinimalModbus debug mode. Response from instrument: '\x01\x03\x02\x00N8p' (01 03 02 00 4E 38 70) (7 bytes), roundtrip time: 110.8 ms. Timeout for reading: 10000.0 ms.


~~ 2020-09-01, 09:05:10 ~~ MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): '\x01\x03\x00\x00\x00\x01\x84\n' (01 03 00 00 00 01 84 0A) MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0 MinimalModbus debug mode. No sleep required before write. Time since previous read: 30035.23 ms, minimum silent period: 16.04 ms. MinimalModbus debug mode. Response from instrument: '\x01\x03\x02\x00\x00¸D' (01 03 02 00 00 B8 44) (7 bytes), roundtrip time: 85.5 ms. Timeout for reading: 10000.0 ms.

MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): '\x01\x03\x00\x01\x00\x01ÕÊ' (01 03 00 01 00 01 D5 CA) MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0 MinimalModbus debug mode. Sleeping 12.46 ms before sending. Minimum silent period: 16.04 ms, time since read: 3.58 ms. MinimalModbus debug mode. Response from instrument: '\x01\x03\x02\x00N8p' (01 03 02 00 4E 38 70) (7 bytes), roundtrip time: 107.0 ms. Timeout for reading: 10000.0 ms.


~~ 2020-09-01, 09:05:41 ~~ MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): '\x01\x03\x00\x00\x00\x01\x84\n' (01 03 00 00 00 01 84 0A) MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0 MinimalModbus debug mode. No sleep required before write. Time since previous read: 30034.18 ms, minimum silent period: 16.04 ms. MinimalModbus debug mode. Response from instrument: '' () (0 bytes), roundtrip time: 10010.4 ms. Timeout for reading: 10000.0 ms.

Traceback (most recent call last): File "logger_csv.py", line 73, in main() File "logger_csv.py", line 65, in main logger.collect_data() File "logger_csv.py", line 35, in collect_data pv = instrument.read_register(0,0) File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 447, in read_register payloadformat=_PAYLOADFORMAT_REGISTER, File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1170, in _generic_command payload_from_slave = self._perform_command(functioncode, payload_to_slave) File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1240, in _perform_command response = self._communicate(request, number_of_bytes_to_read) File "/usr/local/lib/python3.7/dist-packages/minimalmodbus.py", line 1406, in _communicate raise NoResponseError("No communication with the instrument (no answer)") minimalmodbus.NoResponseError: No communication with the instrument (no answer)

ccall48 commented 4 years ago

I sometimes too encounter this error, seems to be random on random registers.

I get around it by putting a try, except with a pass inside my while loop, so the loop continues and doesn't break the script if the read fails.

j123b567 commented 4 years ago

Did you try any other software, just to be sure if it is minimalmodbus or USB/RS485 or instrument problem.

Do you have good USB/RS485 converter with correct hardware DE switching or some low-price one? Do you have correct grounding or converter with galvanic isolation?

Can you try much higher message rate? Put the block in try/except, lower the timeout to 0.5 and run the loop with delay e.g. 0.5 s. Is the error rate higher or is it still about 2-3 minutes between errors?

amandeep16 commented 4 years ago

This is the python script I am using , can you please help where to put try, except in this :

!/usr/bin/env python3

import minimalmodbus import serial import csv import psutil as ps from datetime import datetime from time import sleep minimalmodbus.CLOSE_PORT_AFTER_EACH_CALL = True instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1) # port name, slave ad$ instrument.serial.port # this is the serial port name instrument.serial.baudrate = 9600 # Baud instrument.serial.bytesize = 8 instrument.serial.parity = serial.PARITY_EVEN instrument.serial.stopbits = 1 # seconds instrument.address # this is the slave address number instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode instrument.serial.timeout = 2 instrument.close_port_after_each_call = True instrument.clear_buffers_before_each_transaction = True instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1) # port name, slave ad$

class Logger: def init(self): self.data_dict = {}

def collect_data(self):
    ''' collect data and assign to class variable '''
    pv = instrument.read_register(8451,1,3)
    sp = instrument.read_register(8451,2,3)
    self.data_dict['pv'] = (datetime.now(), pv, sp)

def print_data(self):
    ''' print select data in nicely formatted string '''
    print("-"*120)
    print("~~ {0:%Y-%m-%d, %H:%M:%S} ~~".format(*self.data_dict['pv']))

def log_data(self):
    ''' log the data into csv files '''
    for file, data in self.data_dict.items():
        with open('data/' + file + '.csv', 'a+', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(data)

def main(): while True: logger = Logger() logger.collect_data() logger.log_data() logger.print_data() sleep(30)

main()

amandeep16 commented 4 years ago

Did you try any other software, just to be sure if it is minimalmodbus or USB/RS485 or instrument problem.

Do you have good USB/RS485 converter with correct hardware DE switching or some low-price one? Do you have correct grounding or converter with galvanic isolation?

Can you try much higher message rate? Put the block in try/except, lower the timeout to 0.5 and run the loop with delay e.g. 0.5 s. Is the error rate higher or is it still about 2-3 minutes between errors?

All the advise given by you is tried already, except try/exception.Even I have changed the converter and instrument also, but with every instrument I am getting the same error.

j123b567 commented 4 years ago

Did you try also another software on your PC? If so and if it is doing the same, it is definitely not the problem of the minimalmodbus.

Did you try to check, if your software is the only one accesing the /dev/ttyUSB0? Command like this one should tell you

lsof /dev/ttyUSB0

You should always use tripple back apostrophe to surround the code here in the issue so it is readable, something like

```python some code ```

You should probably tell which version of minimalmodbus are you using.

You have also this line twice in your code, so all manual configuration is lost after the second one

instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1)

Please learn little bit of python. It is out of the scope of this issue to teach you programming.

amandeep16 commented 4 years ago

Did you try also another software on your PC? If so and if it is doing the same, it is definitely not the problem of the minimalmodbus.

Did you try to check, if your software is the only one accesing the /dev/ttyUSB0? Command like this one should tell you

lsof /dev/ttyUSB0

You should always use tripple back apostrophe to surround the code here in the issue so it is readable, something like

some code

You should probably tell which version of minimalmodbus are you using.

You have also this line twice in your code, so all manual configuration is lost after the second one

instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1)

Please learn little bit of python. It is out of the scope of this issue to teach you programming.

Hi many thanks for your suggestions...I will implement it and try to solve the problem I am facing and may be if will learn little Python there will not be any more need to contact you again..

However my question was where to put try and exception in data collection or in main..

I think its too difficult for you too..

Thanks again..

j123b567 commented 4 years ago

It depends on what you want to do and if/how you would react on the error. try/except directly in while loop will catch the error, but you simply skip the reading by it. If you would like to do something more, you should place it in data collection and do something clever instead.