LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamic call of a vi with a reference stored in a global variable

Hello,
I am trying to program a VI which calls DAQmx functions in some cases, in other cases DAQmx may not even be installed. To prevent a broken arrow on machines where DAQmx is not installed, I want to use a sub-VI containing the DAQmx function calls which is called dynamically by a main VI. For speed I want to prevent continuous opening and closing the VI reference, so I want to store the reference to the sub VI in a global variable. In this variable I also want to store the Analog Input Task. I want to use an initialization VI to write the VI reference of the sub VI and to configure and start the Analog Input Task and write the Task ID to that Global, too. In that way I was hoping to be able to improve the performance of the dynamic calls and the Task calls. BUT - when I write the refererence and task to the Global and read it out from another VI, the reference is not valid anymore and the Analog Input task is also not valid, even if both the initialization VI and the Global are still open (but not running). Does somebody have an idea how to solve that? It is a bit difficult to describe, so here is what I want to do in a shorter description Smiley Wink:
 
- run a initialization VI which
  defines a reference to a sub VI which will be called dynamically later on
  and a AI task ID definining a DAQmx physical channel configuration to use for subsequent read cycles
  and writes both (VI reference and AI task) to a global variable
- run another VI which
  reads the VI reference of the VI to call dynamically from that global
  runs the corresponding VI dynamically
  the dynamically called VI performs an AI task corresponding to the DAQmx task ID read from that global (it reads an analog value for instance from the  
  physical channel configured by that AI task) 
 
Why all that? To prevent creating and destroying the VI reference for each call of the sub VI for speed. And to use the configured DAQmx channel for subsequent read tasks only if the subVI is called dynamically - if it is not, then the application will not see the DAQmx calls and therefore no broken arrow will occur if no DAQmx is installed on the machine.
 
Can somebody help me with this? Why can't I store and read out the reference to the sub VI to/from a global, and why is the AI task not valid when read out from the dynamically called sub VI? I am somewhat lost with all that...
Thanks in advance,
Gabs
0 Kudos
Message 1 of 13
(3,443 Views)
Hi Gabs, I've done a similar sort of thing but using functional global variables as apposed to global variables. I don't know if it will help or not as the problem may be nothing to do with using Global variables, but I've attached one of the .vi's that I use to do this that I know works if you want to give it a try.

Best of Luck,
David Clark
CLA | CTA
IDEX Biometrics UK Ltd
Hampshire, England
Download All
0 Kudos
Message 2 of 13
(3,411 Views)

Hi,

thanks, but this did not solve the problem, unfortunately. Please find attached a little test VI. The library contains a VI which works as a functional global variable. The second VI is just to make sure that the reference works, it is the VI to call dynamically. When you open "Analog LSGlobal.vi", set a probe to the incoming and outgoing wires for the VI reference. Then start the VI. It will write the contents of the inputs (num. value of 46 and reference of the VI) to the shift registers of the VI. Then, switch the boolean switch to FALSE and start the VI again. The outcoming numerical value is updated successfully, but the reference returns "not a reference". The same happens if I store a DAQmx Task ID in that way. Am I doing something wrong or is there something I'm missing?

Regards,

Gabs

0 Kudos
Message 3 of 13
(3,402 Views)
Oops, typical error, I forgot the attachment Smiley Indifferent
0 Kudos
Message 4 of 13
(3,397 Views)
I think I know what your problem is. In your Analog LSGlobal.vi you are calling the Analog Functions.vi vi reference, but then as soon as the Analog LSGlobal.vi finishes its execution it will automatically close the reference to Analog Functions.vi, and effectively remove Analog functions.vi from memory.

To fix this you need a really simple VI (attached) that will maintain your Analog Functions.vi in memory. Simply run this vi as a daemon by opening a reference to it and setting the 'wait until done' property to 'F'. This will then just run in the background. Just open another reference to it and kill it when you're finished, but in the meantime your data should be successfully held in the Global.
David Clark
CLA | CTA
IDEX Biometrics UK Ltd
Hampshire, England
0 Kudos
Message 5 of 13
(3,393 Views)
Hmmmm, thanks David, but this is a bit difficult, because these VIs are part of a driver set for our customers. When wiring the VIs together in an application, everything works fine. Just when running the VIs itself for test reasons, then this problem occurs. Therefore it is not my preferred solution to have such a dummy VI running, in a real application it may just be disturbing, I think. Isn't there any other way to tell LabVIEW not to destroy the reference? There is a "Close Reference" function, so what is that needed for if the reference is always closed automatically? Is there any other setting or solution?? Also, the same happens to my DAQmx Task ID Smiley Sad
Gabs
0 Kudos
Message 6 of 13
(3,386 Views)
I *think* the problem you're having is that the initialization vi runs to completion before you start up the other vi, right?  And you're starting both manually from the front panel, one after the other?
 
If so, then you're probably being bitten by a feature of DAQmx that will automatically clear tasks that were still active after all vi's holding a reference to that task have stopped running.  The initialization vi configures the task and starts it.  Then the vi finishes execution.  In the background, LabVIEW and/or DAQmx "notice" that there's a dangling task out there still trying to run, so it stops & clears the task.  Then when you run your 'Run' vi, it retrieves a reference to a no-longer-existing task and gets flagged with an error.
 
Solution: simply make a higher level vi that first calls the Init vi and then calls the Run vi.  This way, there are references to the task held by vi's that are still in execution mode, and it won't be automatically cleared.
 
-Kevin P.
CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 7 of 13
(3,385 Views)
Sounds like a good idea to me.Smiley Happy

Message Edited by davidpcl on 05-31-2006 10:49 AM

David Clark
CLA | CTA
IDEX Biometrics UK Ltd
Hampshire, England
0 Kudos
Message 8 of 13
(3,376 Views)

Uh - I am almost getting crazy with that Smiley Mad

Kevin, that solution is the right one for programming an application. In that case everything will work fine. But during testing, it is more convenient to call all VIs from their front panels one after another. That's how I'm doing it for everything that needs to be exchanged between such VIs: store them either in a global or in a functional global variable. In that way the user can "play around" with the VIs without wiring them together in a main VI. Therefore, after some thinking I liked Davids idea with that daemon VI (I solved that by adding a boolean in the initialization VI to choose if that daemon is necessary - during testing phase - or not - when using the VIs in a main application). BUT:

David: It does not work!!! Smiley Sad I have exactly done what you proposed and this daemon VI is really running, having a True/False frame with a constant of False wired to the selector and holding both the functional global and the dynamically to call VI in the True frame. In that way, after initialization is finished, both VIs are still running but idle. Anyway, when I read back the value of the reference or the DAQmx task, it is invalid again!

That really costs just too much time. Does anybody have any idea what to do now? David, I was hoping that your suggestion would solve the problem, because it would be logical that it would - why then is LabVIEW destroying the reference and task anyway even if that daemon VI containing the functional global is still running???

Regards,

Gabs

0 Kudos
Message 9 of 13
(3,364 Views)

After all that tests and your helpful answers it looks like that to me: When I create a reference or DAQmx Task in a main VI and this VI finishes execution, LabVIEW destroys the reference and task ID. So far, so good. But even if that main VI gives that reference or task to a sub VI which keeps on running even when the main VI has finished execution, LabVIEW seems to do the same. Isn't that a little weird? What can I do about that???

Regards,

Gabs

0 Kudos
Message 10 of 13
(3,356 Views)