LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Stop a sub VI anytime

Hello!

I searched here before asking this and similar topics were found, but they're only similar.

 

Problem: I start a sub VI from within my main VI. The sub VI runs a loop, controlled by buttons on the main VI front panel, which are referenced into the sub VI. When pressing STOP, the sub VI would still continue the code in the loop until the next iteration. This is not wanted, so my idea was to abort the sub VI via a method and its VI reference. LV denies this by saying like "The VI you are trying to stop is in an illegal state" and of course doesn't stop the VI and its loop immediately.

 

Do I need to set up something special in the VI properties? There are different options under "Execution", but I don't see the connection.

0 Kudos
Message 1 of 11
(1,619 Views)

Your consumer states are improperly defined.

 

Read about  a trip to grandma's house here!  Every state can be defined with a finite time period <200msec.


"Should be" isn't "Is" -Jay
0 Kudos
Message 2 of 11
(1,600 Views)

If you use the "Call By Reference" function instead of a regular subVI call, then you can get away with an abort.  But use caution.

"If you weren't supposed to push it, it wouldn't be a button."
0 Kudos
Message 3 of 11
(1,580 Views)

It is difficult to give specific advice without seeing the code, but your stop button will only get read once per while loop iteration and the loop cannot complete until everything in it has completed.

Can you explain what the loop is doing that prevents is from reading the stop condition at regular intervals? For example if there is a lengthy inner loop (FOR or while), the terminal would belong there. If it is waiting forever for some timeout, that needs to be broken. What does the subVI actually do? Does it really need to stop or would it be sufficient to just hide the panel?

 

I would guess that you have a relatively poor architecture and whatever you need the program to do could be done in much better and different ways.

 

Once you show us a simplified version of your code and tell us how the program should function as it is operated (step-by-step details!), I am sure we we can point you to a much better solution.

0 Kudos
Message 4 of 11
(1,548 Views)

I made a simplified VI. example1 is the one that works, but doesn't exit the sub VI immediately, depending on where the code in the FOR loop currently is. example2 is supposed to exit the subVI anytime, but doesn't do it.

 

Download All
0 Kudos
Message 5 of 11
(1,493 Views)

When you want to stop parallel loops, you need a way to "get inside the loop".  In the "old days", there were "References" that could be passed, but they were clumsy, and did not maintain "data flow" (you had no "wire" for the reference).  In LabVIEW 2016, the Asynchronous Channel Wire was introduced, and makes a very intuitive way to pass things "asynchronously" (here meaning "instantaneously") from one loop to another.  Here's a simple example with a Stream Channel wire:

Parallel Loops Stream Example.png

 

The Stream Channel Wire is created by a "Channel Writer", the rectangular item in the first Loop that takes the Boolean "Stop" control in and exports a "Green Pipe" -- green for Boolean, pipe as a metaphor for Asynchronous Channel Wire which passes over (not tunneling through) the "wall" of the While Loop.  The second (receiving) Loop has a corresponding Channel Reader that takes the Boolean out of the Stream and sends it to the Stop Control of the second loop.

 

The Stream Channel Wire is like a Queue -- everything put in one end is sequentially read at the other end.  If you run this code, you may be surprised at the results -- the second loop will not stop until it reads all the commands from the first Loop, namely "Go, Go, Go, ..., Stop", and as it is the slower loop, it finishes later, and shows it looped as many times as the first loop.

 

To get the two loops to stop at the same time, replace the Stream Channel Wire with a "Tag" Channel Wire, where the Reader only reads the most recent item (if any) that is passed in:

Parallel Loops Tag Example.png

 

This behaves as you would expect -- the two loops stop at the same time (with the second loop showing fewer iterations).

 

I've put both VIs right here on the diagram.  What if the second Loop was a sub-VI and I wanted to pass it the Channel Wire?  Simple -- select the second Loop (including the Tag Channel Wire), go to the Edit Menu and choose "Create Sub-VI".  Try that.  You'll see that the sub-VI has a Channel Wire Reference as an input, so you can pass Channel Wires into and out of sub-VIs.

Parallel Loops Tag with Sub-VI.png

 

See if this works for you.

 

Bob Schor

 

Message 6 of 11
(1,469 Views)

@Bob: Very clever way. Didn't know of the pipe. However, it doesn't help to end the sub VI. I also opened another thread where the topic was to end two loops at the same time. Did you perhaps want to answer there?

0 Kudos
Message 7 of 11
(1,452 Views)

@MaSta wrote:

I made a simplified VI. example1 is the one that works, but doesn't exit the sub VI immediately, depending on where the code in the FOR loop currently is. example2 is supposed to exit the subVI anytime, but doesn't do it.

 


This code is too simple! What does the FOR loop actually do? If it does a hard calculation that takes 10 seconds, it needs to complete. If it just does something quick every 10 seconds, use an inner loop to poll the button. And why is is a FOR loop instead of a while loop? I really doubt that waiting for 100000x 10 second iterations (11+ days!!!!) for a natural termination of the loop is reasonable in any scenario.

 

Here's one possibility (might need some tweaks, depending on if you want the first task a 0s or 10s, etc.):

 

 

altenbach_1-1668623260122.png

 

 

Message 8 of 11
(1,434 Views)

How about this.

"If you weren't supposed to push it, it wouldn't be a button."
Message 9 of 11
(1,418 Views)

@altenbach wrote:

This code is too simple! What does the FOR loop actually do? 


That's the point. It shouldn't matter what the FOR loop does. I know, I could also use a 5 ms loop timer, count 10 iterations to achieve a 50 ms timing and then execute the actual code which, perhaps, takes 5 ms to do everything, so that the FOR loop could end with a max. of 5 ms delay.

In my imagination, even if LV is dataflow based, I think that it would create a process, a task for a sub VI. Tasks can be killed programmatically.

 

I learned from the LV help that the method to abort the VI isn't for sub VIs, but for the main VI. So it's basically the same as the Stop VI.

The conclusion now is to do the counter method.

0 Kudos
Message 10 of 11
(1,394 Views)