11-06-2009 12:47 PM
Hi,
I am developing a utility that allows a user to configure up to 2 devices (both use same driver with a different board number), click initialize, which then brings up a file dialog and displays arrays for the data to be collected and some error messages for each measurement. The user then clicks the Start/Stop button to begin collecting and logging data. Currently i have a Wait(ms) block to allow the user to set often the measurement should be made. Currently the Start/Stop button allows collection to be started, paused, and started again. My problem is trying to have a master stop button that should stop all loops immediately when it is pressed.
I tried using a global variable for the stop button, but the measurement and logging while loop doesnt stop until after the wait(ms) block times out. Can anyone give suggestions. If i need to restructure the VI into different loops, I can do that. I just want to understand the right way to program something like this.
The VIs are attached. I removed the device specific measurement VI so that anyone can open the vis and run them to see how it works.
11-06-2009 01:15 PM
Use a notifier, not a global. Whichever loop contains the stop button will send the notifier. Any loops that need to stop when the button is pressed will receive the notifier. You can also have sub-VIs obtain the same notifier and listen for notifications...that way, they will also stop when the button is pressed.
Go to the LabVIEW help...Find examples...and look at the notifier examples.
11-06-2009 04:03 PM
Ok. I had a chance to take a look at your code and I think you don't quite understand the concept of "dataflow". Let me see if I can help.
First of all...when I refer to your upper structure, I am referring to the first while loop, sequence structure, and subsequent while loops. When I refer to your lower structure, I am referring to the while loop containing the event structure. Just so we get our terminology straight.
I believe that you are under the illusion that your upper structure contains three parallel while loops. It does not. It contains three SERIAL while loops. There is dataflow dependency between the while loops. The sequence structure requires data that is not available until the first while loop has finished executing, so the sequence structure cannot start executing until the first while loop has terminated.
The second while loop requires inputs from the first frame of the sequence structure (which, by the way, you don't need and should get rid of...the sequence structure, I mean), so it cannot start executing until the first frame of the sequence structure has terminated. The third while loop requires inputs from the second while loop...so, again, the third while loop cannot run until the second while loop has finished executing.
Now, for your stop button. You have that global stopping all three loops. So here's what is happening in your program:
Your program starts. The first while loop executes in parallel with the loop which contains the event structure.
At some point you press the "stop" button. Both the first while loop and the loop containing the event structure finish executing.
The first frame of your sequence structure executes.
The second frame of your sequence structure executes. The second while loop reads the "stop" value from the global, so it executes once and then finishes.
The third while loop starts executing. Again, the loop reads the "stop" value from the global, so it executes once and then finishes.
Then your program terminates.
You need to restructure your program, because right now it doesn't make any sense at all. Your block diagram would benefit from some serious tidying up as well, your wiring is a mess. I suggest you look into a state machine architecture for this program.
11-06-2009 04:20 PM - edited 11-06-2009 04:29 PM
Oh yes, by definition, the loops will not stop until everything inside them has finished executing...which includes your "Wait" function. So the delay between when you press "stop" and when your loop actually stops will be whatever time you specify for your "Wait" function...in this case, 3sec.
Why is it 3sec, anyway? That seems rather long.
I do see that you can terminate your first loop with the "initialize" button and your second loop with the "start/stop" button, so you're not entirely dependent on the "stop" button. However, if you never press "initialize", your program will do what I described in my earlier post. Oh and why is that second loop in there? You don't need it...all it's doing is repetitively writing the titles to the spreadsheet file. If you only need to write the titles once, get rid of that loop and put your "start/stop" control in the next loop instead of that local variable that's in there now.
I really do think a state machine is the way to go here. And nicer wiring. 🙂
11-06-2009 04:23 PM
I agree, your programming style is a mess !
When you hit the stop button your program is at the wait function, so you must wait 0 to 3 secs for the loop to stop.
Actually it will be always 3 sec, i think, in this instance.
Delete all unnecessary staf and use highlight execution to understand why.
A quick fix, (and dirtry): Set the Milliseconds to Wait to 100msec and send the number of iterations to a shift register.
When the iterations are 30 (30 x 100msec = 3 sec), then execute your program, and reset to zero the shift register.
You can use this trick for that, also
11-06-2009 04:40 PM
You need to combine all upper code into a state machine with a single loop. Currently, you have three while loops serialized, complicating everything.
Get rid of the global, you don't need it. Place the terminal of the STOP button on the loop condition of the upper code parts and wire a TRUE out of the "STOP value changed" of the lower event structure directly to the loop condition of the lower loop. You can also delete the timeout case of the event stricture, it does nothing. Your lower loop also has a race condition because the stopglobal leading to the loop terminal is read before the event structure will write the new value, requireing one extra iteration.
You have some serious CPU burners on the upper code. How many times do you actually write the titles??? Once should be enough!
Instead of a 3000ms wait, use an event structure with a 3000ms timeout. This way it can react right away, breaking the timeout, if something needs to be done, e.g. react to the stop button.
You have many hidden controls that have only one purpose: to serve as local variables. They are not needed. For example you can eliminate the "titles" terminal, place a wire between the two local variables of it, then delete the locals. Right? All better! 🙂