Jump to content
Sign in to follow this  
vinayk

Paused tasks in a high priority VI

Recommended Posts

I have a VI with tasks that need to be running continuously no matter what as these tasks control the valves on a machine. But when I try to open a sub-VI to show the status of all the components on the machine, my main VI tasks were paused until I close the sub-VI window which hinders my application purpose. So I set the main VI priority to 'Time Critical' and the sub-VI to 'Background' but still doesn't work, moreover LabVIEW hung up on me when I called the sub-VI. Then I noticed in the help file this quote: "If another VI with higher priority calls this VI, the priority of this VI rises to match the priority of the calling VI." So when I called the sub-VI its priority is also raised to 'time critical' as that of the main VI.

How else can I call sub-VIs without pausing the tasks in the calling VI?

I created this simple example so that I can explain better.

Block Diag of main VI :

post-9618-1192799177.jpg?width=400

Block Diag of Sub VI :

post-9618-1192799192.jpg?width=400

Main VI Front panel :

post-9618-1192799172.jpg?width=400

Sub VI Front panel :

post-9618-1192800126.jpg?width=400

Share this post


Link to post
Share on other sites

You have two options - either have a separate loop in the main VI and (statically) call the subVI from there (then only that loop will wait for the SubVI to return, the rest of the main VI will continue to run), OR call the subVI dynamically by opening a reference to it and then use the run method on that reference with the wait until done set to false. To set the inputs of the subVI you use the Set Control Value method:

post-1777-1192804037.jpg?width=400

The latter method is great in many situations - I use it to call VI templates (.vit files), then you automatically get a unique instance for each call. A typical use of this is to allow the users to open as many graph windows as he wants...

Regards,

Mads

Share this post


Link to post
Share on other sites

Hi,

What you can do is have the subVI run continously by placing it parallel to your other code in the main=UI VI. Then communicate the status of the subsystem via globals or (usually better) via functional globals to your main VI. The subVI should store its status when it changes into the global or functional global. The main VI should poll the global or functional global at a limited rate (i.e. not continously, but with a wait in a loop).

This is the base of many templates. Instead of polling queues are then usually used to communicate with a subprocess, but that is not required if you want to learn how get a subVI to run independently. In many such templates there is a main VI which calls a UI VI and 1 or multiple hardware interface VI and optionally for example a processing VI. These VI's loop autonomously and when they have all stopped looping the main VI stops.

Joris

Share this post


Link to post
Share on other sites

QUOTE(vinayk @ Oct 19 2007, 06:18 AM)

I have a VI with tasks that need to be running continuously no matter what as these tasks control the valves on a machine. But when I try to open a sub-VI to show the status of all the components on the machine, my main VI tasks were paused until I close the sub-VI window which hinders my application purpose. So I set the main VI priority to 'Time Critical' and the sub-VI to 'Background' but still doesn't work, moreover LabVIEW hung up on me when I called the sub-VI. Then I noticed in the help file this quote: "If another VI with higher priority calls this VI, the priority of this VI rises to match the priority of the calling VI." So when I called the sub-VI its priority is also raised to 'time critical' as that of the main VI.

How else can I call sub-VIs without pausing the tasks in the calling VI?

You've got a couple misconceptions that are common among beginners.

First, setting the priority of a VI or subVI doesn't work the way you think it does. A VI's priority refers (basically) to its execution priority relative to other VIs/subVIs when those other pieces of code are executing in parallel with it. In general, the execution model of LabVIEW is pretty good at doling out execution time, and I find myself changing a VI's priority only in very specific cases. In your example, there's no need to mess with the priorities of the various subVIs, and you should probably set them all back to Normal.

Second, the reason your code seems to "pause" when the dialog opens is because you've got a dataflow dependency between the code that does the "counting" and the code that does the "dialog". The While loop can only iterate when all the code inside it has finished executing. But the dialog subVI doesn't finish executing until you close the dialog. That blocks the While loop from finishing its iteration. What you need to do is restructure the code so that the "count" loop doesn't depend directly on the dialog.

Here's a very simple example of one way you could refactor your code:

post-2992-1192804907.png?width=400

Notice that the two loops (the count loop and the dialog loop) are now completely independent of each other. Information (like "count" and "stop") is passed from the bottom loop to the top loop using Local Variables. This allows the dialog box to be displayed without blocking the execution of the count loop.

NOTE 1: There are about 1000 ways to skin this particular cat, and the example above is one of the simplest. The above example may work well in a very small application, but for anything more serious you will find that it may not scale well. There are more advanced techniques that are necessary for bigger applications.

EDIT: The other posts above this one touch on some of those techniques...

NOTE 2: I suspect this is your first exposure to Local Variables. PLEASE DO NOT FALL IN LOVE WITH LOCAL VARIABLES. They're going to seem like the solution to all your problems, but they're not. The excessive use of Local Variables is considered poor style and their use in large or complicated VIs can make the code buggy, unreliable, and (most importantly) almost impossible to debug.

Attached Example: Download File:post-2992-1192804918.vi

Share this post


Link to post
Share on other sites

Thank you all. I was banging my head all evening yesterday trying to figure out how to get the main tasks running on my NI Panel PC. Your replies were very helpful.

Vinay

Share this post


Link to post
Share on other sites

As suggested, I used a parallel while loop to seperate the calling of the sub-VI and it was working great, like said in the above posts, for very small applications. But for my actual application this method of calling sub-VIs is not working great. So I was trying to implement the 'Call by reference' method as suggested. But my 'Open VI reference' is giving an error 4001 which I could not figure out why.

This is what I did to the 'Open VI reference':

1. created a constant at 'Type specifier VI refnum' by right clicking at that terminal

2. right clicked on the constant -> 'select VI server class' -> 'browse..' -> selected the sub-VI that was supposed to be opened

3. created a constant at 'file path' terminal and specified the location of the sub-VI

post-9618-1192817535.jpg?width=400

This is the sample application...

Download File:post-9618-1192817648.zip

Share this post


Link to post
Share on other sites

QUOTE(vinayk @ Oct 19 2007, 01:14 PM)

As suggested, I used a parallel while loop to seperate the calling of the sub-VI and it was working great, like said in the above posts, for very small applications. But for my actual application this method of calling sub-VIs is not working great. So I was trying to implement the 'Call by reference' method as suggested. But my 'Open VI reference' is giving an error 1004 which I could not figure out why.

This is what I did to the 'Open VI reference':

1. created a constant at 'Type specifier VI refnum' by right clicking at that terminal

2. right clicked on the constant -> 'select VI server class' -> 'browse..' -> selected the sub-VI that was supposed to be opened

3. created a constant at 'file path' terminal and specified the location of the sub-VI

http://lavag.org/old_files/monthly_10_2007/post-9618-1192817535.jpg' target="_blank">post-9618-1192817535.jpg?width=400

This is the sample application...

The error means as the error handler VI can tell you, that the VI is not in memory. Why you may ask!

Because you think you provide a path to the VI to the Open VI primitive, but you don't. This VI will interprete a string input as VI name and nothing else. And when you provide a VI name only the VI must be already in memory.

What you want to do is change the string constant into a path constant instead!

And with that we are at the next problem. Using absolute path names to refer to VIs is ABSOLUTELY the worst you can do. This will immediately break when you move your project, or build an executable and/or install this on another machine.

So reconsider how you want to refer to those dynamic VIs. The way I do this is having a VI somewhere whose location is relative to the dynamically called VIs, for instance in the same directory. Then this VI queries its own path and strips its name from that path and returns that. Now append to that path the VI name you want to load et voila.

Rolf Kalbermatter

Share this post


Link to post
Share on other sites

+ If you want the subVI to run in parallell with the main VI you need to run it using the run method like I showed in the previous reply, not a call by reference node.

Share this post


Link to post
Share on other sites

The path does not refer to the correct VI in the sample, however I'm not sure why you insist on using a call by reference node :question:

I've updated your sample to a working one. As you will notice I've also added a wait in the subVI loop, you should always have something that prevents the loop from running as fast as possible, otherwise it will use up all the CPU time. On a side note I would also recommend sticking to dialog controls and colors, that will give the users a familiar and professional looking interface, the advantage of using a OS-standard interface should not be underestimated. I also noticed that you are using the place as icon feature for the diagrams...that is the default and it's probably easier to read for beginners, however it takes a lot of space so in the long run it's a good idea to not use that, just a tip :)

The example can easily be expanded to show cool ways to use the run method...you could e.g. make the subVI a template and have as many of them running in parallell as you want. You can also use e.g. a notifier or read the front panel properties in the subVIs to close all windows when the main app window is stopped.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.