NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Launching a never ending vi in sequence

Solved!
Go to solution

Hi!

 

I have a vi that can basically be represented by a while loop that never stops until i press a button.

I want to load and run this vi from a sequence without it hanging up that sequence.

Also, at the end of the sequence it would be great if it could end the loop in the vi.

 

For this last part I made the vi read out a variable in my locals and stop the loop as soon as it is a certain value.

(I think this is a good solution, but any suggestions are of course welcome ;))

 

For being able to run the rest of the sequence, even though the vi never ends, I was less successful.

I tried putting the vi in a subsequence and then running that subsequence in a different thread.

However, stepping through the main sequence, it does steps over the call of the subsequence,

but then the main sequence still freezes until i stop the loop in my vi.

 

What am i doing wrong exactly? Any help would be much appreciated!

 

0 Kudos
Message 1 of 9
(4,296 Views)

Hello,

 

When you put a while loop in a certain step of a sequence, then the sequence waits until while loop is done to go to the next step in the sequence. Ending a while loop from an earlier step in a sequence by a control in a later step of the sequence won't work.

 

So by using a sequence you're actually saying to labview that you don't want to proceed to next step until the one before is done.

 

You will have to use another design pattern . You can find some more information about design patterns in the presentation at http://decibel.ni.com/content/docs/DOC-4817

 

You can also find more specific information about certain design patterns by searching for "design pattern" on http://zone.ni.com/dzhp/app/main

 

If you want, you can always put your VI online so that we can get a better idea of what you're trying to achieve.

 

 

 

 

 

 

Kind Regards,
Thierry C - CLA, CTA - Senior R&D Engineer (Former Support Engineer) - National Instruments
If someone helped you, let them know. Mark as solved and/or give a kudo. 😉
0 Kudos
Message 2 of 9
(4,266 Views)

It is not clear as to your application but in the past when I needed to have something running contentiously in the background (my application needed to generate keep alive messages on a serial data stream ) I produced a separate application and controlled this application  through Active X

 

This has the advantage that the background functions keep running even when single stepping through the test sequences.

 

 

Colin

 

Message 3 of 9
(4,257 Views)
Solution
Accepted by topic author _blackadder_

You were on the right track with the sequence call in a new thread. What you are missing is that you need to use the Thread.ExternallySuspended API in your vi. Set it to true at the beginning and set it to false right before returning back to teststand. This will allow tracing through the other thread of the execution while your VI is still running. Also you should use the Execution.InitTerminationMonitor and Execution.GetTerminationMonitorStatus in your VI as well so that your vi knows when to exit if a user requests that the execution terminate or abort.

 

Also, as far as the main sequence telling your asynchronous VI when to exit. You can pass a local boolean variable as a parameter from your main sequence to your "New Thread" sequence and your vi can then access it from its sequence context as parameter.Myvariable or whatever you named your parameter. Make sure you have the parameter set as "Pass by Reference" (right-click on it in your sequence and make sure that menu item is checked).

 

Hope this helps,

-Doug

Message 4 of 9
(4,254 Views)

I attached a simplified version of the vi.

 

Basically it's a vi I've been running separately of teststand, that handles the datastream coming from some devices.

(in the real vi, it's not constantly polling the uart, but using events, there are multiple com ports and the dataprocessing is quite a bit more complicated but I left that out in this example to keep it clean)

It works fine like that, but it would of course be even better if the sequence itself could start up this vi separately so that the user doesn't have to take care of it....

0 Kudos
Message 5 of 9
(4,253 Views)

Hello,

 

My apologies for mistakingly assuming that you were working in LabVIEW. Please ignore my previous comments.

Kind Regards,
Thierry C - CLA, CTA - Senior R&D Engineer (Former Support Engineer) - National Instruments
If someone helped you, let them know. Mark as solved and/or give a kudo. 😉
0 Kudos
Message 6 of 9
(4,248 Views)

Blackadder,

 

Please see my previous post. It explains how to do this.

 

-Doug

Message 7 of 9
(4,245 Views)

Thanks Doug!

 

That did the trick!

Is this in fact the same as what "Run asynchronous vi" does behind the scenes? (except for the fact you can't specify a new thread that possibly also does other things)

Also, this termination monitor is completely new to me but that seems to work great.

I noticed that this still doesn't work if the sequence just ends normally without an abort/termination.

I guess thats where passing this "stop" variable (reading it out in the vi) comes in.

Or is there also a way for a vi to monitor that the other thread is at the end.

(pass a reference to the first thread to the second one and then getting some kind of status field?)

 

And thanks again for the help!

Sebastiaan

0 Kudos
Message 8 of 9
(4,215 Views)

Run Asynchronous VI basically uses a sequence call module with the "New Thread" option, but I don't think it does much more than that. I think you still have to do ExternallySuspended and/or Termination monitor in your vi. At any rate, I recommend against using Run asynchronous vi as there have been issues with using that step type (confusion over what passing ThisContext means for the most part). See the following link for more details about the issues with Run asynchronous vi if you are interested:

 

http://forums.ni.com/ni/board/message?board.id=330&message.id=28101&query.id=753835#M28101

 

As far as termination monitor not detecting whether or not the original thread has completed normally, that is not its purpose and not always what a user might want. For example, you might have a worker thread that you want to keep running even after the thread that launched it completes. There might even be more than two threads in the execution and the execution technically isn't complete until all threads are done, including the asynchronous ones. The purpose of the termination monitor is to give the code module a way to detect when the user is requesting a terminate or abort so that it can return and allow the execution to terminate or abort normally (an execution cannot terminate or abort while a code module is still running).

 

Like you are suggesting, you can probably pass in the original caller's thread as a parameter to the asynchronous sequence and your VI and call Thread.WaitForEnd on it with a 0 ms timeout to check if it's done in your loop. You need to make sure that you unchecked the "Automatically Wait for the Thread to Complete at the End of the Current Sequence" setting on the advanced panel of your sequence call step though or your threads will both be waiting for each other and never complete. Also the sequence view of the execution is likely to switch to your asynchrous thread at the end because it will be the last thread running, so if you don't want that you should probably just go with passing a boolean variable instead and leave the setting "Automatically Wait for the Thread to Complete at the End of the Current Sequence" checked. Do not ever pass ThisContext from one thread to another though as that is the source of the problems people are having with Run VI Asynchronously.

 

Hope this helps,

-Doug

0 Kudos
Message 9 of 9
(4,179 Views)