LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Using static VI references in an application

Solved!
Go to solution

Hello all you helpful forum-goers!

 

I am using 4 different static VI references hooked directly to "Run VI" invoke nodes, with the "Wait Until Done" and "Auto Dispose Ref" parameters both False, to run four VIs dynamically, each of which does nothing except call my re-entrant serial port input/output VI with a different COM port index number.  Overall this is working pretty well.  However, I have a couple questions about improving my setup.

 

1) Is it possible to somehow set an input parameter to the re-entrant serial port VI, and thereby be able to Invoke it directly four times in a for loop, each with a different input value?  I'm not sure how I would do that, except that I've heard that you can set the value of a control of a VI using a reference to it.  I also worry that using the same static VI reference to Invoke the VI 4 times would somehow re-start the same dynamic VI instance 4 times, instead of spawning 4 copies of it.  However, this solution would allow me to delete the 4 VIs which do nothing except call the re-entrant VI, and my code would be simpler and more expandable (e.g. making it easy to interact with 8 serial ports in the future just by increasing the number of for loop iterations).

 

2) It seems to be required for me to add the 4 VIs which I Invoke dynamically to my lvproj file, and then add to the "Always Included" section of my application build properties in order for them to be included in my application executable.  This was what I had to do in previous versions of my code when I referenced the VIs via a path name, but now that I changed to using static VI references, I thought they would be included automatically.  LabVIEW already knows to automatically load them in memory (e.g. when I do a search it searches them even when they are not open), and they are included in the Dependencies list in my LabVIEW project, so why would they not be built in to my executable?  I'd prefer not to have to add them explicitly, as it is just one more thing to forget if I change it in the future.  Is there a setting or something somewhere which I can change so that they will be included in the executable automatically?

 

Thank you very much for your time and assistance, as always!

 

-Joe

0 Kudos
Message 1 of 19
(5,393 Views)
Solution
Accepted by jmorris

Hi Joe,

 

Answer to Q1:  Yes.  Wire an "8" (I32 datatype) to the "options" input of the "Open VI reference" function.  This tells "Open VI reference" that the VI is re-entrant.  It's going to look something like this:

 

open VI ref reentrant.PNG

 

Use the resulting array of references to track your spawned VIs throughout the rest of your application.  Don't forget to close them when you're done with them.

 

For Q2...I've certainly built executables using code similar to what I show above, and have not had to explicitly include the statically called VIs in the build.  You are right, they should be included automatically in the build -- mine always have been, including modules which reside in a different lvproject (called by a main control VI).  Sometimes I've found it necessary to develop modules in one lvproject and then call them from various main VIs which reside in other projects.  If I've used a static reference, they are always included.  What version of LV are you using?

Message 2 of 19
(5,385 Views)

Diane,

 

Thank you very much!  I will try that solution next.  In the meantime, to clarify, you use the "Open VI Reference" function in order to get separate copies of the re-entrant VI, correct?  So I was correct when I said the reference coming out of the Static VI Reference is a single copy but otherwise pretty much identical to what you get out of the "Open VI Reference" function?

 

Also, regarding closing the references, I admit I had overlooked that part.  My serial port VI currently watches a global variable to know when to quit, so I could really set the "Auto Dispose Ref" parameter true, correct?  On the other hand, if the Invoke Node returns an error, it does not auto-dispose of the reference, meaning I need to close it in my Main VI, which means I won't really be able to make my Main code any simpler.

 

Question 3) If I leave the "Auto Dispose Ref" as false, and close the references when my Main VI is exiting, will that nicely shut off my re-entrant VI clones, such that I can write their code to just run forever and save time by not checking the "Time to Quit" global variable on every loop?

 

Re: Q2) I am running LabVIEW 2010 service pack 1.  I'm glad you agree I should not have to manually include static VI reference VIs, but then left wondering why it isn't working.  Hmm...

0 Kudos
Message 3 of 19
(5,371 Views)

This sound suspiciously like trying to launch a VI with an "asynchronous call (by referance)".  And certainly, such a thing CAN be done but, you'll need to upgrade to LabVIEW 2011Smiley Wink

 

As for the global stop:  try enqueueing a stop command to a named queue- same functionality except it gets rid of the nasty global.  I'm not religiously opposed to global variables but, in this case the queue would be perfomance enhancing since it never gets lost in the wrong state (stop as soon as started condition)


"Should be" isn't "Is" -Jay
0 Kudos
Message 4 of 19
(5,364 Views)

Jeff,

 

Ironically, I do have LabVIEW 2011 discs ready to install in my desk, but I need to hold off until I can justify the entire program retest that upgrading would entail.  😉

 

Thanks for your suggestion regarding the stop command in a queue, I agree that would work better than the global.  Even better, though, would be checking nothing at all, which is why I was asking if closing the VI reference from the Main VI would stop the referenced VI clone.

 

-Joe

0 Kudos
Message 5 of 19
(5,360 Views)

@jmorris wrote:

Jeff,

 ... I was asking if closing the VI reference from the Main VI would stop the referenced VI clone.

 

-Joe


Nope, it just closes a referance to the vi that is doing whatever the instance of the vi itself is doing.  Absolutly no effect on the instance of the vi.  The only things that could effect the vi instance would be calling the "Abort" method (UNWISE!!!!) or "Control Value Set (By label)" method.  As in Set "Stop" = TRUE (IMHO, even better than a queue if you want the launcher to trigger the shutdown.)  If you want the launcher to wait until the vi instances complete on their own, you just justified the upgrade and can tell you boss just how smart he/she was to invest the SSP $.


"Should be" isn't "Is" -Jay
Message 6 of 19
(5,357 Views)

Oh, if only I could justify the SSP$.  Ours is about to run out (since we got it with our purchase of LabVIEW 2010), and I'm sure it'll be another 5 years or so before we have some critical need to update LabVIEW again, and our IT department is all about limping along with our current resources as long as humanly possible.  Smiley Tongue  But I already went down the list of improvements in 2011 that would affect my program, and none of them are justifiable.

 

Anyway, enough ranting for now.  Is there any reason for me not to immediately close the references after the Invoke method, assuming I am going to stick with the current quitting scheme of a global variable?

 

Thanks for your help.

 

-Joe

0 Kudos
Message 7 of 19
(5,353 Views)

Just set Auto dispose of referance to TRUE and "fohgetaboutit" .  (it one of those refs you don't need to close, LabVIEW takes care of it for you)


"Should be" isn't "Is" -Jay
0 Kudos
Message 8 of 19
(5,344 Views)

But if I do that, don't I have to have logic to close the reference in the main VI anyway, in case the Invoke method returns an error (and therefore does not pass the reference to the subVI to close when it is done)?

0 Kudos
Message 9 of 19
(5,341 Views)

Nope.  If you look at the Help for the "Run VI" method, you find the following information for "Auto Dispose Ref":

 

"If TRUE, the target VI detaches the reference from the main VI.  When the target VI finishes executing, LabVIEW automatically disposes of the reference, along with the parallel data space.  If FALSE, the main VI retains control of the target VI."

 

So by setting "Auto dispose" to T, you pass control of the reference to the subVI itself, and LabVIEW will dispose of the reference when the subVI finishes running.

 

I will second Jeff and urge you to get rid of the global variable!  I haven't used a global variable in something like 14 years.  I haven't needed to.  Myself, I love a good notifier and would urge you to use a notifier instead of a queue if you're going to be spawning VIs.  Why?  Because the first instance of your spawned VI to receive the "stop" message from the queue will remove that message from the queue, thus preventing the other instances from receiving the message.  So you'll have to send the message repeatedly and hope that everyone eventually receives it.  If you use a notifier, anything that contains a "Wait on Notification" with that notifier reference will receive the message.  I think you want multiple listeners here, right?

 

Ok, this afternoon I'll try to write some dummy code with a statically called VI in it, compile it into an exe, and see if I can duplicate your problem...

 

One question, were you just using the static VI reference by itself to call your VI, or were you using it the same way I showed in my earlier post, with "Open VI reference"?  I'm just trying to look for differences between what I've done in the past which has worked, and what you're doing now which isn't working...

 

Jeff, what say you?

0 Kudos
Message 10 of 19
(5,322 Views)