pyhys / minimalmodbus

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

Why the silence_time can affect the roudtrip_time? #98

Open billyhuangyr opened 1 year ago

billyhuangyr commented 1 year ago

I'm using minimodbus RTU to communicate with a motor, and the baudrate I set is 115200. In order to test the time the master used to read a specific data from a slave. I write a simple loop which is like:

while True:
       Instrument.read_register(xxxx)
       time.sleep(0.01)

I enabled the debug mode and print the roudtrip_time. I found it's really tricky that if I change the sleep time of time.sleep(), the roudtrip_time will also change. For example: if I set time.sleep(0.01), then the roudtrip_time is almost 5ms. if I set time.sleep(0.005), then the roudtrip_time is almost 10ms. if I set time.sleep(0.002), then the roudtrip_time is almost 13ms. Seems there is a tricky equation: sleeptime + roudtrip_time = 15ms. I wanna know why? And how to reduce the total time each loop used?

j123b567 commented 1 year ago

Modbus/RTU splits frames by inter-frame delay. It is the only way to safely recognize the frame's beginning and end. See https://minimalmodbus.readthedocs.io/en/stable/serialcommunication.html

Before sending anything to the bus, the sender must always wait to satisfy the minimal inter-frame delay (but often longer to be sure).

So the fastest communication in your case can be 5 ms

The device, you are using can generate longer inter-frame delays so it can on purpose delay the response. It is common practice.

If you are using USB/RS485 converter, it will bring its own delay. For FTDI-based converters, you can play with "Latency Timer" in serial port configuration.

billyhuangyr commented 1 year ago

Thank you for responding. Your answer has helped me understand how a Modbus (serial) device works when reading and writing data. However, I am still confused about why the sleep time affects the roundtrip time. I checked the minimodbus function and found that they use the serial.write() and serial.read() methods to establish communication, and the roundtrip time is measured from the beginning of write to the end of read. So the roundtrip time should indeed be around 5ms, as you mentioned. However, the sleep time I set is outside of the communication process. Therefore, I'm not sure why its magnitude would affect the roundtrip time. Could you please clarify this for me? Thank you again for your help. By the way, the OS I used is ubuntu+Preempt_RT which is a RTOS.

j123b567 commented 1 year ago

RTOS does not matter much here because

This does not prevent you from using Python for control applications. I personally use Python exclusively for this, but my systems are not hard real-time. Also note, that real-time does not mean fast but with predictable latencies.

However, the sleep time I set is outside of the communication process. Therefore, I'm not sure why its magnitude would affect the roundtrip time. Could you please clarify this for me?

I don't have enough details about your system and the hardware used. But let's say, the delay between frames should be 10 ms. Minimalmodbus receives the response and saves the timestamp. Then you sleep 3 ms. Then you need to send the next request but the library reads the last received timestamp, which is just 3 ms old, so it sleeps an additional 7 ms. Then, the frame delay is safely 10 ms and the library can continue and finally start sending the request.

Why are your times longer than expected in general? I don't know. It can depend on the resolution of your time base, RS485 hardware itself, or any other reason I can't imagine.