LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How can I send commands from a single UI loop to different while loops?

apok,

 

That will only work if you want all the loops to run at the same rate. Because you have infinite timeouts on the Wait on Notification and Dequeue functions, the "receiving" loop will only iterate when the top loop does.  Further you must send a "Do not Stop" notification on every iteration.  It makes more sense to only send the notification when there is something to notify, namely "Stop."

 

The whole idea of Producer/Consumer is to allow the loops to run at different rates which are appropriate for the work they are doing.

 

For example a DAQ loop might execute 100 times per second and the file loop once per minute while the GUI loop might not iterate at all if no user input occurs.

 

Lynn

0 Kudos
Message 11 of 29
(1,045 Views)

@johnsold wrote:

apok,

 

That will only work if you want all the loops to run at the same rate. Because you have infinite timeouts on the Wait on Notification and Dequeue functions, the "receiving" loop will only iterate when the top loop does.  Further you must send a "Do not Stop" notification on every iteration.  It makes more sense to only send the notification when there is something to notify, namely "Stop."

 

The whole idea of Producer/Consumer is to allow the loops to run at different rates which are appropriate for the work they are doing.

 

For example a DAQ loop might execute 100 times per second and the file loop once per minute while the GUI loop might not iterate at all if no user input occurs.

 

Lynn


Lynn,

Can you show me through a vi what you mean? I am not seeing it visually...

0 Kudos
Message 12 of 29
(1,040 Views)

apok,

 

I modified your VI to show the loops running at different rates.  This is somewhat artificial of course, but I think it demonstrates the principle.

 

The changes include removing the notifier.  Having two "waiting" functions in one loop complicates things.  It can be done but sending the Stop command through the queues here is easy.  The datatype is already the same and "stop" is not a valid signal for the displays, so it works.

 

It only enqueues an element to the loop which is to receive the data (A or B). The Stop case enqueues "stop" to both queues.

 

On one of the receiving loops I set a dequeue timeout of 1 second. The other has the default infinite timeout. I also append the top loop iteration count to the A or B strings so the string displays show the number of times the upper loop has iterated.  Note that the iA count increases whether a button is pressed or not. The iB count only increments when the Process B button is pressed. (Process is spelled with one "c").

 

I combine all the error wires so that the queues are not destroyed before all the loops stop.

 

Lynn

Message 13 of 29
(1,018 Views)

Hi Lyn and apok,

 

Thanks your for the replies... Sorry it has taken a while for me to get back to you. My wife and I just had a baby a couple of few days ago; so I have been otherwise occupied and only now settling in back in at home...

 

Lyn: Your example has provided me with a good structure to work follow... But basically, I need a separate queue for every UI control on the FP... I thought this may have been the cause; although I was hoping their might be some "advanced" procedure for this...I will have a play and post a reply with what a simple example of how this would work for me... I hope you will have a couple of minutes to take a looks and critique it for me...

 

Regards,

Jack

0 Kudos
Message 14 of 29
(989 Views)

Jack,

 

Has the little one started programming in LabVIEW yet? Congratulations and I hoipe everything is going well ofr all of you.

 

You probably do not need a separate queue for each control.  Define a set of commands and data parameters associated with each command. For example the queue to the file loop could have commands like Open, Write, Read, Get Size, Close, and Stop. The parameter associated with Open would be a filename or path. The write parameter would be the data to write.  The other commands would have no parameters (or might require the path). The GUI could have five different buttons, a path control, and a graph with the data displayed.  The queue datatype would be a cluster. The first element would be a typedefed enum with the commands as the item names. A path control and an array for the data would be the other two elements of the queue.  On the UI six controls and an indicator feed into one queue.

 

You will have a separate queues for each loop. since a queue should only be read (dequeued) in one place.

 

Lynn

0 Kudos
Message 15 of 29
(984 Views)

Courtesy of LabVIEW Champion Jack Dunaway I have really been seeing the benefits of user events. I give him all the credit for this which is helping to make my programming more flexible. Look at the image he sent me (attached) as an example. You have multiple loops which have registered for the same event. This will allow both loops to get the same message when it is fired from a single user event refnum. Now you don't have your queues all over the place, it allows for a one to many architecture when needed, and the event registration refnum can be destroyed (for instance if a window is closed) but you don't have to worry about stopping messages from being queued up because if no one is registered the user events won't cause a memory leak shown here.

 

Even if you don't subscribe to this method, I encourage you to take a look.

0 Kudos
Message 16 of 29
(968 Views)

Hi Lyn,

 

So far, so good with bub... She is a much better sleeper than our first (fingers crossed she doesn't change)...

 

I have attached a simple queued UI for my vi as a starting point based on general instrument controls (i.e. idle, self-cal, run, stop)... The wires are connecting and the commands are being fed through the queue; but the "run" state only runs for a single iteration and I cannot get continuous data being read... Do I need a shift register somewhere? What have I done wrong?

 

Regards,

Jack

0 Kudos
Message 17 of 29
(941 Views)

Jack,

 

Your Program Loop will wait forever for the next element in the queue. So after it receives a RUN command, the RUN code executes one time and the  loop waits for the next element in the queue.

 

If you want the RUN command to mean: "Run until someone tells you to do something else," then you need a different structure. You could put your Menu items into a shift register in the Program Loop. As the code exits each case it determines the next state, which can be the same state repeated. Set the Dequeue with a short timeout. Check the timed out? output to see whether a new Menu item has been received or to use the one set by the previous state.  Look at the information about state machines.  That is what you are trying to acheive.

 

I would put all that DAQ stuff stretched out to the left into one setup or initialization subVI.

 

Also, be careful with the Use Default if Unwired on the case structure output tunnels. This can often lead to results differetn from what you may have intended.

 

Lynn

0 Kudos
Message 18 of 29
(930 Views)

It may be an advanced solution to your problem depending on your familiarity with OOP and the LabVIEW implimentation of OOP (LVOOP).  The "Actor Framework" provides an OOP solution to this problem and can be useful as your project's scope increases.  Sending messages between threads is a common programming challenge to LabVIEW developers and there are a LOT of ways to skin that cat.

 

I've always just used notifiers and sometimes when I was in a hurry I would use Local Variables... There are also Action Engines but I prefer solving this problem with the Actor Framework these days.

0 Kudos
Message 19 of 29
(925 Views)

Hi Lyn,

 

I get the simple state machine architecture; but I am not sure how/where I wire the shift register... Please see what I have done attached... Not sure how I can have both the queue (that signals the menu item selected) and the constant in the case structure that maintains the current state as the case selector is already wired to the de-queue?

 

Regards,

Jack

0 Kudos
Message 20 of 29
(893 Views)