LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

asynchronous call

Solved!
Go to solution

Dear all

It is the first time that i am using asyncronous call  a sub VI. in my program every thing is OK but when I run it the "run" abort "abort" icons above the Sub VI fliker. What is wrong with my program.

 

Thanks in Advance

Download All
0 Kudos
Message 1 of 7
(6,195 Views)

@V.S wrote:

Dear all

It is the first time that i am using asyncronous call  a sub VI. in my program every thing is OK but when I run it the "run" abort "abort" icons above the Sub VI fliker. What is wrong with my program.

 

Thanks in Advance


Dear V.S.,

     I'm not sure what you mean by:  the "run" abort "abort" icons.  I'm assuming you mean the Black/White Arrow and the red Octagon ("Stop" sign).  Recall that you are running two routines "asynchronously", meaning they are both running as "simultaneously" as LabVIEW can manage, and having to update their (independent) Front Panels at the same time.  Flickering may just be an indication of the switching between the two instances, which LabVIEW will do at its own schedule.

     You also ask "What is wrong with my program".  On the one hand, the simple answer is "Nothing".  But on another level, it may be that you do not understand what it means to have an Asynchronous VI.  There are also some suggestions to make on your Main, which I'll get to in a minute.

     I use Asynchronous VIs a fair amount, particularly when I need to control or monitor independent processes that can (potentially) interact with each other.  There are several ways to run processes in parallel.  Typically, a process will consist of a While loop that is "clocked" in some manner, either because there is a Time function, such as "Wait until Next Multiple" inside it governing its speed (say, once a second, or once a millisecond), or there is a Queue "feeding" data into the loop and the Dequeue function (by design) "waits" for something to appear on the Queue.  For the sake of this discussion, let's bundle each such process into a sub-VI, each with an Error In, Controls that the Process needs to get started, Indicators that might return values when the Process exits (note -- these are frequently not needed), and an Error Out.

     One way to have, say, 5 such Processes run in parallel is to stack the 5 Process VIs vertically, wire all of the input Error lines together, and put them in parallel with the main Process.  Here's a simple example:

Parallel Example.png

Here the main loop of the Main Program and the Parallel Process start at the same time, and in order for the Main Program to stop, the Parallel Process also has to stop.

     One difficulty with this simple way of starting Parallel Processes is controlling when they start.  In this example, they start when I branch the Error line.  Note that I couldn't put the branch inside the While loop, since the Loop couldn't continue until the Parallel Process ended.  But what if I wanted to start it after the While loop ran, say, 3 times?  To do this, you put code wherever you need it to run the Parallel Process asynchronously.

     In all of the asynchonous processes that I've written, none of them utilized a visible Front Panel, hence could not be stopped by pushing a Stop button.  So how do you stop an asynchronous process?  Here are several ways:

  • If it is being "fed" data (via a Queue, for example), send it a special piece of data that tells it to stop.
  • If it is using a Queue or similar structure, and the Main routine destroys the Queue, an error should result, and you can stop and exit on this error.
  • You can use a Global "Stop" variable that you set in the Main.  Note that one such variable can stop all of your Parallel Processes.

     Here's a suggestion for starting the Parallel Process that doesn't rely on wiring a Path into Open VI Reference.  Start with a Static VI Reference, and Browse for Path until you find the Parallel Process VI.  Next, right-click it and change it to a Strictly Typed Reference -- you need this to get the Front Panel connector information.  Now put down a Property Node and wire the Static Reference through it.  The Node should become a VI Interface Type ? node.  Choose the VI Path property, and wire that to Open VI Reference, with the Static Reference (strict) type wired in at the top.  Be sure to wire the Option for Call and Collect (0x100) or Call and Forget (0x80), as you require.  Finally, wire the reference to Start Asynchronous Call.  Here's what I mean:

Spawn Parallel Process.png

This, now, you can "package" as a sub-VI (I named it "Spawn Parallel Process").  Such a sub-VI is very flexible -- you can place it wherever you need to in your Main program, and when it executes, it will "spawn" (start running as a Parallel Process) the routine "Demo Parallel Process", and will exit immediately without waiting for the Parallel Process to do anything.  Thus you could put a (single) call to Spawn Parallel Process inside the Main program's While loop and it would allow the loop to continue executing (unlike putting the Parallel process itself inside the loop).

 

     I realize this may be a bit much to understand all at once.  Read it over several times, think about what it means for sub-VIs to execute in parallel, and look at other examples.

 

     One final suggestion -- try to keep your VIs as compact as possible.  When I opened your Main, I didn't notice the While loop as it was entirely off the edges of my monitor's display.  Small and Neat makes for easier-to-look-at-and-understand LabVIEW code.

 

Bob Schor

Message 2 of 7
(6,159 Views)

Dear Bob Thanks for the comprehensive reply.I read your reply several times and I learned much aboat parallel loops, but as you told it is a bit difficult to understand all of this material at once because I am amature in labview and it is my first time to use asyncronous call. Let me explane more aboat my requirement. It may leed us to a more strightforward solution:

 

The exact problem is:

I have a Main VI which is running continuesly and there are some Sub VIs which I want them to be started asyncronously when I pressed a "Start Bottom" in the "Main VI Front Panel" and the Sub VI must continue running until I pressed a "Stop Bottom" in the front panel of the asyncronously started Sub VI (When I Pressd Stop Bottom in the Sub VI it should be completely stoped).

 

Regards

0 Kudos
Message 3 of 7
(6,130 Views)

@V.S wrote:

The exact problem is:

I have a Main VI which is running continuesly and there are some Sub VIs which I want them to be started asyncronously when I pressed a "Start Bottom" in the "Main VI Front Panel" and the Sub VI must continue running until I pressed a "Stop Bottom" in the front panel of the asyncronously started Sub VI (When I Pressd Stop Bottom in the Sub VI it should be completely stoped).


You can use your code (or the variation in my Snippet) to start the Asynchronous VI.  However, you (generally) want to have only a single Front Panel with controls for the User, namely the Front Panel on your Main.  There you can put a "Stop Sub-VI" button, and now you have only to figure out how to get this button, on the Main Front Panel, to get the asynchronous sub-VI to stop.

 

You need something that has a "global" scope and can be used by both the Main and sub-VI.  The three most common are

  • Global Variables (found on the Structures palette, Block Diagram)
  • Shared Variables (also found on the Structures palette)
  • Functional Global Variables (or VI Globals), a tiny sub-VI used to "set" and "get" a value.

I tend to use Shared Variables (for no really good reason), but I've also used the other two.  The idea is that you define a Boolean Global or Shared Variable with a meaningful name like "Stop Asynchronous VI", and set it to False before you issue the Start Asynchronous Call.  Inside the sub-VI, you wire the output of "Stop Asynchronous VI" to the Stop indicator (if you are using a While loop), and in your Main routine, wire the "Stop sub-VI" control to set "Stop Asynchronous VI".

 

You may have noticed that these Global things are unusual in the fact that they can be both read and written (unlike other LabVIEW controls or indicators).  They need to be used carefully, but for this sort of application (where you basically initialize them, then only write to them once) is pretty safe.

 

BS

0 Kudos
Message 4 of 7
(6,098 Views)

Dear Bob

In the case you mentioned I think that I can also allocate the stop control to one of the input terminals of th Sub VI and then wire the "Stop Asyncronous VI" button in the Main VI to the mentioned input terminal of the Sub VI thus in this case it is not necessary to define a global variable?

Am I Right?

 

Regards

0 Kudos
Message 5 of 7
(6,082 Views)
Solution
Accepted by topic author V.S

@V.S wrote:

Dear Bob

In the case you mentioned I think that I can also allocate the stop control to one of the input terminals of th Sub VI and then wire the "Stop Asyncronous VI" button in the Main VI to the mentioned input terminal of the Sub VI thus in this case it is not necessary to define a global variable?

Am I Right?

 

Regards


You are right, but it would not do what you want.  LabVIEW uses the principle of Data Flow, which implies that data flowing into a VI does so when the VI starts, and flows out when the VI ends.  Suppose you wire Stop Sub-VI to an input (which we'll call "Stop Sub-VI") of the sub-VI.  If you call it with Stop Sub-VI  = True, then the Sub-VI will have its Stop asserted when it is called.  Suppose you call it with Stop Sub-VI = False -- well, the sub-VI will start running with False wired into the Stop terminal (and thus won't stop).  Now the sub-VI is running asynchronously. with its "Stop" input being False.  Nothing that you do in the Main VI will influence this Asynchronous routine (that's why it is Asynchronous -- it is running independently, in parallel -- the only time you can pass data into it on its connectors is when it starts (and is called), and the only time you can get data out is when it exits.

The exception to that, of course, is by using some form of Global, as I explained.  By all means, try doing it your way -- you'll find that you cannot stop the Asynchronous routine using a connector-wired Control.  Once you do this, feel free to try one of the methods that I described, which will work.

 

BS

Message 6 of 7
(6,063 Views)

Dear Bob

Thanks for the valuable helps. The problem solved.

 

Sincerely

0 Kudos
Message 7 of 7
(6,049 Views)