Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello,
First I would like to thank you for this great modbus library, which works like a charm. But maybe you can consider this change and make the Modbus RTU functionality even faster.
We are currently using pymodbus on our project reading data from an inverter with 9600 baud. We read 7 register blocks every second. We noticed that reading a 1 register is taking around 103ms, but it should be a lot faster at 9600 baud.
After some searching I found a time.sleep(self._recv_interval) at row 257 of the serial.py which causes the delay. It is mostly executed twice, and is filled with 0.05 (50ms) which explains the 100ms delay.
In the past the time.sleep was 10ms and we found that the _recv_interval was introduced in commit:
8af46d8
We've tested the changes with reading different sizes of register blocks and didn't noticed any issue.
There are 2 small changes in this pull request:
1 - Calculating the duration of 1 byte
The calculation of duration of reading 1 byte in serial.py row 144. Originally there was 1 + 8 + 2, which I presume is a start bit, 8 databits and 2 stopbits. For the new calculation I took the bytesize and number of stopbits from the arguments of the class init.
2 - Calculating the receive interval
I don't know the background of the formula for calculating the _recv_interval value, but it is returning these values for the various baud rates:
230400 -> 10ms
115200 -> 20ms
57600 -> 30ms
38400 -> 40ms
19200 -> 50ms
9600 -> 50ms
4800 -> 50ms
The _recv_interval is only used for sleeping while waiting for the reading ready signal and the while loop is always looping 2 times (didn't investigate why), but that gives our delay of 100ms. If you compare the 100ms to the time of reading a 16 bits register at 19200 baud, which is 0.104ms. In the 100ms time, it's possible to read 961 registers.
In my adapted formula the waiting times will be like this:
230400 -> 1ms
115200 -> 1ms
57600 -> 1ms
38400 -> 2ms
19200 -> 3ms
9600 -> 6ms
4800 -> 13ms
Basically there will be sampled every 4 bytes / 2 registers if the reading is ready or not.
I think that the waiting time does not have to be limited to 50ms, but I had a minimum of 1ms.
Testing
Used test code:
Before the changes, reading 2 registers:
After the changes, reading 2 registers: