-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Versions
- Python: 3.7
- OS: Current Raspberry OS
- Pymodbus: 2.5.2
- Modbus Hardware (if used): Exar CC-USB-RS485-150U / Exar 21B1411
Pymodbus Specific
- Server: rtu - sync + async
- Client: rtu - sync + async
Description
In serial/RTU mode, PyModbus participates on a Modbus bus using PySerial. Unfortunately, PySerial's read behaves differently to recv on sockets, as the pySerial timeout defines how long time it has to fill the 1024 bytes buffer of PyModbus before it has to return whatever it managed to get instead of filling the buffer with the payload of a TCP packet. This results in delayed processing as it could take up to a second for the ModbusSerialServer to start processing the message(s). The delay causes the requestor to retry its request, further filling the buffer of identical requests.
PyModbus in general seem to be unable to handle participation on multi-drop bus as Modbus over RS485 is, because a server can only parse requests. It gets confused seeing Modbus responses it has not generated itself on the wire it serves on as a server.
It seems a server can only, and is only expected to, have a ServerDecoder. Such a decoder can only parse Modbus Requests. When it fails, such as when a Response appears on the line, it will flush the buffer and lose data, including valid Requests still pending to be parsed. This flush of the input buffer again causes the requestor to retry its request and may/will trigger a failure-to-respond status of the PyModbus-implemented server.
While PyModbus attempts to do add framing of outgoing data by pausing between frames for 3.5 char times, it does not attempt to detect pauses between frames on incoming data. This makes the serial stream be an unframed series of bytes. As consequence, to recover framing information it must properly be able to parse both requests and responses (of all types present on the bus) to not come out of sync. This it does not do (yet?), either.