AdvancedClimateSystems / uModbus

Python implementation of the Modbus protocol.
Mozilla Public License 2.0
211 stars 81 forks source link

RTU client does not respect inter-frame delay #114

Open acolomb opened 3 years ago

acolomb commented 3 years ago

While the RTU server code sets its port timeout according to the specification's 3.5 character inter-frame delay, the RTU client will happily send requests directly after receiving a response. The delay could be handled in the application, but as the protocol clearly requires this, an implementation within the library would be in order. I have seen real-world communication problems because of this, which are hard to diagnose because it usually just results in a timeout (no response) or a CRC error if you're lucky.

I don't know how to best implement such short delays within Python. time.sleep() seems way too inaccurate for millisecond delays, and busy spinning until the required time has passed seems like a high CPU burden. I envision something like saving the timestamp (e.g. time.perf_counter()) of the last serial reception, and checking that enough time has passed before sending the next request. But if not, is there a nice way to tell Python "wait and resume execution after this timestamp"? The POSIX thread API has such a mechanism for waiting timeouts, but I haven't found a good Python equivalent yet. If someone has an idea, I could look into the implementation.