pyhys / minimalmodbus

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

How to check whether minimalmodbus finished his actions? #87

Closed kang2k10 closed 1 year ago

kang2k10 commented 2 years ago

How to check whether minimalmodbus finished his actions? I have a function that is by the timer, every second reads the register from slave From another function, by pressing the button, i need to write a bit in this slave Sometimes an error occurs when reading is going on and immediately is trying to record Something like instrumment.iSrunning )

j123b567 commented 2 years ago

It is not that simple. Proposed solution does not solve the problem (it will have race conditions so it will sometimes also fail). By timer, you mean threading.Timer? It seems that you are using multiple threads and this library is not hread safe.

You should rather use external Lock and lock the resource.

At the beggining

instr = minimalmodbus.Instrument(...)
lock = threading.Lock()

And then everywhere in your code

with lock:
    instr.read_register(...)
    instr.write_register(...)
    ...
kang2k10 commented 2 years ago

Thanks, but idea use Lock, not good ( In parallel Thread, video is processed from the camera, it cannot be stopped

j123b567 commented 2 years ago

I don't understand your problem. If you are processing something on the other thread that don't call any modbus, then using Lock is fine. If you call modbus in the video processing thread, it is bad no matter if you are using Lock or not. IMHO it is worse not using some sort of mutex/lock as you already notice in the question.

Your original proposal is in fact mutual exclusion but wrong. And the Lock is just the same mutual exclusion but thread safe and already existing in python.

You should of course lock the resource for the shortest time you can.

with lock:
    instr.read_register(...)
do_something_other()

You can create dedicated thread just for modbus, handle all periodic and other requests in it and use some inter thread communication to request something and to inform about result asynchronously. This is how I'm using this library. Inter thread communitation is out of the scope of this discusion.

kang2k10 commented 2 years ago

I use 2 threading.timer

  1. process video
  2. read modbus register in main pyqt code, some buttons. after pressing this, writing modbus bit to slave. If first start thread (read modbus), and immediately press button for send bit to modbus, arise error.
j123b567 commented 2 years ago

My first answer still apply. Use propper locking of shared resource.

When using pyqt, you have also alternative not to use second threading.timer and use QTimer instead. All actions are then performed in the main qApp event loop in single thread. So, no locking is needed anymore.