Timeout after request frame does not take into account request length (examples below have no physical Modbus devices connected, those are only the requests).
Test script:
from minimalmodbus import _MAX_NUMBER_OF_REGISTERS_TO_WRITE, Instrument # type: ignore
device = Instrument("/dev/ttyUSB0", 1)
if device.serial is not None:
device.serial.baudrate = 38400
device.serial.parity = "E"
device.serial.timeout = 0.1
while True:
try:
device.write_registers(0, [0] * _MAX_NUMBER_OF_REGISTERS_TO_WRITE)
except:
pass
System info
```text
Minimalmodbus version: 2.1.1
pySerial version: 3.5
Platform: Arch Linux x86_64 / 6.4.12-arch1-1
Filesystem encoding: 'utf-8'
Byteorder: little
Python version: 3.11.5 (main, Aug 28 2023, 20:02:58) [GCC 13.2.1 20230801]
Python version info: sys.version_info(major=3, minor=11, micro=5, releaselevel='final', serial=0)
Python flags: sys.flags(debug=0, inspect=0, interactive=0, optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0, ignore_environment=0, verbose=0, bytes_warning=0, quiet=0, hash_randomization=1, isolated=0, dev_mode=False, utf8_mode=0, warn_default_encoding=0, safe_path=False, int_max_str_digits=-1)
Python argv: ['/usr/bin/ipython']
Python prefix: '/usr'
Python exec prefix: '/usr'
Python executable: '/usr/bin/python'
Float repr style: 'short'
Variable __name__: minimalmodbus
```
1. Writing maximum number of registers with timeout set to 100ms.
![100ms](https://github.com/pyhys/minimalmodbus/assets/144025123/7d84af0b-e347-45a2-b0c4-ed4eed13f07b)
Time between frames ~41ms
2. Writing maximum number of registers with timeout set to 50ms. Request frame "eats" away the wait period for response.
![50ms](https://github.com/pyhys/minimalmodbus/assets/144025123/5ca6fd89-3aa8-4879-abb0-dcda792623e2)
Time between frames 0ms
3. Writing 40 registers with timeout set to 50ms.
![40data_50ms](https://github.com/pyhys/minimalmodbus/assets/144025123/7f05a1ab-c03b-44d2-a937-2f1b2f65ddc2)
Time between frames ~29ms
To prevent the issue I've added serial.flush after serial.write in minimalmodbus.py, line 1468
1. Writing maximum number of registers with timeout set to 100ms.
![100ms](https://github.com/pyhys/minimalmodbus/assets/144025123/d244bee3-2f4d-4265-a834-17deba802e97)
2. Writing maximum number of registers with timeout set to 50ms.
![50ms](https://github.com/pyhys/minimalmodbus/assets/144025123/5edda5bf-4a2d-4e88-a3ab-26ee9d5c9a5e)
3. Writing 40 registers with timeout set to 50ms.
![40data_50ms](https://github.com/pyhys/minimalmodbus/assets/144025123/b73a1418-076e-4a84-8b26-8afe13d28228)
I've used flush with conviction that it is a nondestructive wait operation. I do not know if that change is adequate to be implemented.
Response times are a little bit longer then expected (possibly extended by MODBUS RTU 3.5 character time).
The issue came around when stress testing some older siemens PLC (slow response times) with faster devices.
Timeout after request frame does not take into account request length (examples below have no physical Modbus devices connected, those are only the requests).
Test script:
System info
```text Minimalmodbus version: 2.1.1 pySerial version: 3.5 Platform: Arch Linux x86_64 / 6.4.12-arch1-1 Filesystem encoding: 'utf-8' Byteorder: little Python version: 3.11.5 (main, Aug 28 2023, 20:02:58) [GCC 13.2.1 20230801] Python version info: sys.version_info(major=3, minor=11, micro=5, releaselevel='final', serial=0) Python flags: sys.flags(debug=0, inspect=0, interactive=0, optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0, ignore_environment=0, verbose=0, bytes_warning=0, quiet=0, hash_randomization=1, isolated=0, dev_mode=False, utf8_mode=0, warn_default_encoding=0, safe_path=False, int_max_str_digits=-1) Python argv: ['/usr/bin/ipython'] Python prefix: '/usr' Python exec prefix: '/usr' Python executable: '/usr/bin/python' Float repr style: 'short' Variable __name__: minimalmodbus ```1. Writing maximum number of registers with timeout set to 100ms.
![100ms](https://github.com/pyhys/minimalmodbus/assets/144025123/7d84af0b-e347-45a2-b0c4-ed4eed13f07b) Time between frames ~41ms2. Writing maximum number of registers with timeout set to 50ms. Request frame "eats" away the wait period for response.
![50ms](https://github.com/pyhys/minimalmodbus/assets/144025123/5ca6fd89-3aa8-4879-abb0-dcda792623e2) Time between frames 0ms3. Writing 40 registers with timeout set to 50ms.
![40data_50ms](https://github.com/pyhys/minimalmodbus/assets/144025123/7f05a1ab-c03b-44d2-a937-2f1b2f65ddc2) Time between frames ~29msTo prevent the issue I've added serial.flush after serial.write in minimalmodbus.py, line 1468
After the changes:
1. Writing maximum number of registers with timeout set to 100ms.
![100ms](https://github.com/pyhys/minimalmodbus/assets/144025123/d244bee3-2f4d-4265-a834-17deba802e97)2. Writing maximum number of registers with timeout set to 50ms.
![50ms](https://github.com/pyhys/minimalmodbus/assets/144025123/5edda5bf-4a2d-4e88-a3ab-26ee9d5c9a5e)3. Writing 40 registers with timeout set to 50ms.
![40data_50ms](https://github.com/pyhys/minimalmodbus/assets/144025123/b73a1418-076e-4a84-8b26-8afe13d28228)I've used flush with conviction that it is a
nondestructive wait operation
. I do not know if that change is adequate to be implemented.Response times are a little bit longer then expected (possibly extended by MODBUS RTU 3.5 character time).
The issue came around when stress testing some older siemens PLC (slow response times) with faster devices.