Jump to content

Master/Slave with Event Structure and Notifiers


JMak

Recommended Posts

Hi All,

I have been trying to come up with a way to make my program more efficient. I am trying to use less nested case structures, and to avoid calling sub VIs multiple times. I looked at some of the design patterns, and there was not a sole design pattern available that did what I wanted, so I have tried to combine 3 patterns into one.

My application has a user interface controlling a camera, and each function is context sensitive. For example, if the camera is already acquiring images, the "change video mode" function needs to unconfigure acquisition before adjusting the settings. If the camera is not doing anything, the unconfigure step isn't necessary.

My previous attempt used nested case structures to test the condition of all these criteria, and take the required action, so there were cases for every combination of states. I wanted the code to be more minimalist, and call functions (sub VIs) in a state machine in a different order, skipping certain cases, depending on the context. I wanted to combine the low CPU usage of the event structure with the queued message handler example, to take an array of states and process them one at a time.

My first attempt is attached. I used notifiers because I don't want steps to be queued if the user presses multiple commands before completion. I want to only process the first command received after the current notifier changes are made. I couldn't think of a way to change between using the array from the notifier and using the modified array (minus the deleted element) in a shift register, so I used the send notification inside the slave loop to send the modified array of states. I want to know if there is a better, more efficient way of doing this, and whether there are any problems here.

Thanks,

James

MasterSlave Events.vi

Link to comment

My first thought is that you have a race condition due to the two parallel loops both writing to the same lossy communication channel (notifier). If you want multiple writers you need a non-lossy method, like a queue.

The way I usually prevent the User pressing multiple commands is to lock the UI out while a command is executing, either just by the “Busy” cursor, or by disabling all invalid controls.

— James

Link to comment

I wanted to do it with a shift register, but couldn't think of a way. I'll try and get rid of the slave send notification. I just had an idea using an array size to select a case structure (or comparison) element... zero will be "read from notifier" and any other number will be "read from shift register". Shift register elements will go down to zero, then the notifier will be read. How does that sound?

Edit -

I just tried it and it didn't work because the "wait on notification" VI stops the slave loop after the first iteration, and the shift register still has commands left over, which execute at the next notification.

Edited by JMak
Link to comment

It looks a lot like you are developing what is commonly called a “Queued State Machine”**, a common design pattern. Personally, I found it was much better to use a well-thought out and tested template developed by others, rather than develop my own. In particular, I often use the JKI State Machine Template. You might want to download that and take a look.

— James

** Note: “Queued State Machine” is actually poor terminology, as they are not actually “state machines” in the proper computer science meaning. "Queued Operation Machine” is a better name. Actually, a true State Machine might be good for your problem, as your “context sensitivity” is really an issue of “state”. However, I’m not that experienced with true state machines, so hesitate to suggest it. There are others on LAVA who are experts in state machines, so perhaps one of them could chime in.

Link to comment

Thanks for the replies.

I just had a few more attempts and managed to make something with a shift register. I added a "wait" default state to the slave, which listens to the event notifier when tasks are finished. The problem with the example pattern is that the wait notifier stops the loop after one task, and I wanted it to continue until all the tasks are done.

MasterSlave Events 3.vi

Link to comment

Hi JMak,

As dj mentioned above, learn to love the queue! I didn't really like the JKI template as it locked the UI and for me I didn't really intuitively grasp how to work with it to asynchronously launch plugins. There are many different variations of the producer-consumer, or master-slave architecture. At it's most basic, it's just two while loops communicating via queue.

Good luck, I think you're taking the first big step into Labview programming.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.