LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to stop an event structure in a while loop

I'm looking for the correct way to stop my event structure + while loop combo, and every method I try seems to have some sort of drawback. (See attachment)

 

Method 1, once an iteration of the code finishes running there is nothing to give me time to click the stop button, so it quickly zips right around and doesn't give me the chance to click stop.

 

Method 2 has a similar problem, in that I have to anticipate that "this will be my last run" before I start it.  I cannot wait for the "main code" to execute, look at the results, and then decide "ok, time to stop"

 

Method 3 has a similar problem as well, in that if I make a stop case from the selector, the main code will execute a final time.  Granted, the way the program works it will have zero values, so it will be a sort of null-test, but it wastes time. 

 

I want the code to execute so that i can choose to either click "start" or "stop" and if I choose stop, the main code should not execute.

0 Kudos
Message 1 of 26
(20,382 Views)

Can't you make a Stop case in your Event?  It'll be like #2 except Stop has it's own event.  You can press Stop at any time and the structure will finish what it's doing(and any other events queued up) then execute the Stop case.


--Using LV8.2, 8.6, 2009, 2012--
Message 2 of 26
(20,364 Views)

It is usually not a good idea to put your main code in an event structure since the user interface become non-responsive until the main code completes. As Taper said the stop event will be fired only after the main code completes, what if it take an hour to complete?. What if you want to abort the execution of the ongoing "test"? A good approach is to use the event structure to manage the UI interactions. Have a look at the Producer-Consumer (events) design pattern (you can search the NI site for more info on design patterns).

 

Attached is an example I created from the producer-consumer (events) template. ( File -> New... -> VI -> From Template -> Frameworks -> Design Patterns -> Producer/Consumer Design Pattern (Events))

 

 

Ben64

Message 3 of 26
(20,347 Views)

Thanks for the producer/consumer link, I forgot my flash drive this morning so I won't be able to see your .vi until tomorrow.

 

I actually found a pretty good solution (again no flash drive or I would post a picture).  I took the [main code] out of the event structure entirely, so that the only thing in the event is the case structure and the continue button and threw that in the beginning (and got rid of the constants/shift registers in the while loop).  After that I simply put the [main code] in a case structure, and put in a true constant in each of voltage range cases, and a false constant in the "stop case" that way the main code runs for all the voltage ranges, unless I pick the "stop case," where none of the [main code] executes and it just stops the loop.

0 Kudos
Message 4 of 26
(20,301 Views)

Solved.JPG

 

: )

0 Kudos
Message 5 of 26
(20,270 Views)

It would be easier if the Stop case had a True constant.  All other cases have nothing and the tunnel is set to use default if unwired, which would be False.  Then you can eliminate the Not function going to the stop button.  And you'd just have to swap the true case code for the False case in your case structure.

Message 6 of 26
(20,265 Views)

I'm not sure what your front panel looks like but to me this is fairly convoluted code. It appears that you have some "magic" number value for Selector which actually determines when the application should stop. And to do this the user must hit the Continue key to stop. It would seem to be much more intuitive for a user to have a dedicated Stop button to control when to exit. If you want to get sophisticated you can hide/show the stop button when it is an appropriate action. Also, as mentioned you have all of your code in the while loop which may result in a slow UI responsive. The button presses will not get processed until the code in the case structure completes. If the user gets no indication you caught the press of the button they will likely keep pressing it, queuing up multiple events for your event structure to process.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 7 of 26
(20,264 Views)

The front panel is actually quite simple, aside from the selector and the continue button, the only things on the front panel are gpib addresses and a couple of indicators. 

 

This is also for a sub.vi in a larger calibration program for a tranfer standard we make, so the stop button doesn't trigger the end of the calibration procedure, just moves you out of this sub.vi and on to the next part of the test, so the continue button is more like a confirm button before the program moves on.

 

Aside from the lack of the ability to properly abort the execution halfway through (which would be nice but I haven't worked out how to do yet), accessing the selector before the main code is complete is wholly unnecessary, so I'm not worried about that.

 

As far as the slow UI response stemming from the code being in a while loop, the main code takes a fair amount of time to run and the program pauses when it gets to the event structure, so is a while loop really going to slow the program down?  If it does, will putting a wait function for a few milliseconds take care of it?  I was under the impression that the event structure would behave differently than a simple case structure with a start button because the while loop won't continue looping around and eating up my processor speed waiting for me to click the button (i.e. a greedy loop).

 

Being able to abort halfway through execution would be a nice feature, and how to correctly stop the event is the purpose of this post, but I am having trouble understanding the NI page about producer/consumer loops (I've only been working with labview for a couple of months and am still a labNOOB) and most of the responses I have reveived have been short, and either point me to the NI page that I don't understand or assume I know how to do what you are talking about (you can see my fail experiments with the stop button in my first attachment)

0 Kudos
Message 8 of 26
(20,224 Views)

With the main processing in the same code as your event structure your delay/responsiveness is more of a user perception than the code running slower. Whether the main processing is in the loop with the event structure or a loop by itself it will run pretty much the same. The issue with your current code is that the event structure cannot be processed until the main code has been completed. And as I stated, it is human nature to keep pressing the button if they user doesn't get some feedback from your code. Now instead of having one event to handle you have a ton. It is much easier to be able to handle an abort mid-stream if you use a producer/consumer architecture since the consumer (the processing code) can be written as a state machine that can catch the abort in the middle of processing.

 

Ultimately it is up to you how you want to develop your code. I, as well as the others, are simply giving you our advice based on our experiences.

 

With respect to the UI and using the selector value (numeric) to initiate a stop, I still believe this is a bad way to go. An explicit stop button is much more intuitive for the user rather than remembering something like a -1 results in a Stop condition. If your selector is an ENUM then you should use a typedef and your case structure will be more readable. Again IMO though, en explicit Stop control would be prefered over an "Action" selection.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
0 Kudos
Message 9 of 26
(20,214 Views)

So here is my next attempt (see attachment).

 

1 problem that Mark has mentioned that I do want to fix, is that the user can click the boolean button multiple times and que up the code to run multiple times by accident, and I would like to make it so that it won't register another click until the main code has finished.  I played around with a state machine, and attached is what I came up with.  Does this attempt solve that problem? 

 

I made a second event case to handle the click of a stop button, so you dont have to select "stop" then click "continue" in order to stop the code.

 

Again, I realize this is not the standard producer/consumer format, but until one of you posts a picture with a little but of explination specific to this case (or downconverts the .vi that ben64 posted because I only have labview 8.5) I am just going to keep throwing out (probably wrong) guesses because no matter how many times I read the producer/consumer ni tips I still don't understand it.

0 Kudos
Message 10 of 26
(20,168 Views)