Preventing callback from interrupting a function (or block of code)

14 views (last 30 days)
I am hoping to find a more eloquent solution to this problem than the one I currently have.
I am working in App Designer and I have a timer that updates object values by reading them from a modbus server. I have written a function (named ReadWriteTC) that is general and either reads or writes data from/to a modbus server. The TimerFcn uses ReadWriteTC to read all the values. There are a fair number of values, so it takes 0.5 seconds or so to complete (timer period is 2 s).
I have several numeric fields with valuechanged callbacks that write the new value to the same server. These callbacks also use ReadWriteTC.The problem is that if the valuechanged callback runs during the TimerFcn, the modbus object gets hung up (I need to crtl-C out). I think the read() modbus function is getting interrupted by the valuechanged callback, which calls write() modbus function.
What would be ideal is that the callback would queue if it was executed in the middle of my TimerFcn run (rather than interrupting it between lines of code). Is there an easy way to do this? I assumed there would be some sort of global Busy property that would trigger the BusyAction of the callback (queue). If I could just manually set this Busy property to true at the start of my TimerFcn and false at the end, all would be right in the world (I think).
What I ended up doing was just adding a flag variable to the app. At the start of ReadWriteTC it checks the flag. If true, then the function does nothing (essentially dropped). Basically, if I change a value during the TimerFcn, nothing happens and I just need to keep changing it until eventually I get it in the dead space. It works, but is really lame. I realize I could use an invisible state button, etc. to retry the write, but I feel there has to be a better way to control the callback execution.

Accepted Answer

Matt C
Matt C on 18 Oct 2019
I think that I figured this out.
There is a pause() command or similar somewhere in the modbus functions (read(),write()) that triggers the queue to execute. This is why it appeared that my TimerFcn was being interrupted.
As others have pointed out, a timer function will break a callback between lines, regardless of if it is interruptible, in order to execute "on time".
The reverse does not appear to be true. That is to say, the TimerFcn is non-interruptible as long as it does not contain a pause(), or drawnow, or any of the other commands that trigger the queue. This makes sense as the timer executes the queue before running the TImerFcn.
I still haven't found a clever way to prevent the queue from running when a pause() is encountered (basically a "do not run queue" hold). I have no clue how the app queue is maintained, or how to access and modify it.
Since I have several instruments communicating and multiple timers, I opted to have my callbacks and secondary timer functions schedule an update (basically an ad hoc queue that I control) and then an update function runs at the end of my primary timer callback and updates everything. The primary timer is set to 'drop' just in case the updates run long for some reason. Keeping commands that may have a significant lag out of non-primary callbacks works well.
Not a huge fan of maintaining my own bootleg queue, but until someone provides a more clever solution...
  1 Comment
Saliha Musovic
Saliha Musovic on 4 Jun 2022
Did you find a way to prevent a callback interupting a function? (your post is almost 3 years old so I have hope :-P)

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!