LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

'Half' -vs- 'Full' Call of Global Variables?

I'm trying to get the hang of these 'Global Variables,' and I can do okay if I only make what I call 'half' a call to a Global VI.

Cf. Master VI HALF CALL OF GLOBAL.vi, Sine Function HALF CALL OF GLOBAL.vi, Global Variable.vi

The idea of those three VI's is that the input to the Sine Function comes from a Global Variable, but the output from the Sine Function goes to a standard wired connector, i.e. only one the control 'half' of 'Global Variable.vi' gets used.

There is some educational material [c.f. Basics/Basics 2/Lesson 13/Display Global Data.vi, also known as 'Exercise 3-4'] which indicates that I should be able to make a 'full' call to 'Global Variable.vi' and bypass the standard wired connector inputs and
outputs altogether.

Unfortunately, the 'Solution' for the aforementioned exercise doesn't work, and I haven't had any luck with something similar.

C.f. Master VI FULL CALL OF GLOBAL.vi, Sine Function FULL CALL OF GLOBAL.vi, and
Global Variable.vi.

Now the idea is that the input to the Sine Function should be able to come from a 'Global Variable' and the output from the Sine Function should be able to go to a 'Global Variable,' rather than a standard wired connector. Unfortunately, this doesn't work.
0 Kudos
Message 1 of 9
(3,486 Views)
MISTAKE: In 'Master VI FULL CALL OF GLOBAL.vi,' the Waveform Chart is incorrectly labeled 'Sine Function via Half Call of Global.'

It should be labeled 'Sine Function via Full Call of Global'

Sorry.
0 Kudos
Message 2 of 9
(3,486 Views)
Your VI called Master VI Full.. would work the same as the other if you actually called the subVI that modified Global Variable Indicator. Without something writing to it, it stays the same defalut value and all you plot is a straight line. You could add a sequence after the first one and drop Sine Function Full Call there and everything would work fine. However, what you're attempting to do is not very good in the first place. You will have much better performance if you avoid the use of globals and better style if you avoid the sequence structure as well. It is always more effecient to modify the data in a wire as opposed to a global. So, if this were a real-world exercise, just placing the sine function between the calculation of the index count
and the graph indicator would be the best way to go. If you're just trying to learn about globals, then try the exercise with just one. You can both read and write to a single global. Delete the one named Global Variable Indicator and in the Sine Function Full Call subVI, write the output of the sine function to Global Variable Control. Make a copy of the global you already have, right click on it, and select Change to Write.
0 Kudos
Message 3 of 9
(3,486 Views)
You forgot to call Sine Function FULL CALL OF GLOBAL.vi in your master vi. The global indicator never gets set. Here is a corrected version of the master vi.
- tbob

Inventor of the WORM Global
0 Kudos
Message 4 of 9
(3,486 Views)
Okay, that starts to make sense.

Just working my way through the educational material [and there doesn't seem to be much in the way of educational material that addresses the topic of global variables], I had been wondering, "How in the world does the global know to call back to the ambient vi?"

Apparently it doesn't, although the educational material would lead you to believe that it does [which of course would explain why the 'solutions' in the educational material don't work].

By the way, do you know what to call the 'Ambient' VI in relation to the Global VI? Is it the VI's 'parent,' or its 'owner,' or some sort of abstract [not-necessarily-instantiated] class, or what? Here I'm using 'Ambient' in the sense of the construction of a Global: Within the block diagram for the Ambient VI, you go to the structures palate, grab a Global variable, drop it in the Ambient VI's block diagram, double click the icon for the Global, and voila - you have your Global VI's front panel [global's being forbidden to have block diagrams, as I understand it].

Anyway, the best guess I had was that this sort of 'parent/child' or 'ambient/member' relationship might have set up some sort of a [doubly linked] pair of pointers between the member global variable and the ambient VI, so that if the member global variable were ever called, it would automatically check its ambient VI's logic to see whether any code needed to be run there. [At least that was about the best guess I could come up with using the flawed educational material I had access to.]

But given your solution of the problem, it looks like there's almost no relationship between the Global and the Ambient VI which created it, at least not from the Global's point of view [the Ambient keeps a list of pointers down to the Global, but the Global doesn't keep a list of pointers back up to the Ambient]. That would seem to indicate that the Global can then be used by any number of Ambients, so long as each Ambient gets a pointer down to the Global.

PS: Does anyone sense that the terms "Local Variable" and "Global Variable" are used in LabView almost exactly the opposite of the way they're used in the C-languages [C, C++, Java, C#]? A LabView "Local Variable" appears in subVIs as though it were a C-language global variable being encountered in a function call [object method], whereas a LabView Ambient VI stares down at a "Global Variable" as though it were a C-language function [object method] staring down at one of its local variables.

Or am I completely off base?
0 Kudos
Message 5 of 9
(3,486 Views)
 

> Your VI called Master VI Full.. would work the same as the other if you actually called the subVI that modified Global Variable Indicator.

Right; see my response below.

> However, what you're attempting to do is not very good in the first place. You will have much ... better style if you avoid the sequence structure as well.

I've been having a bit of trouble with non-deterministic behavior in my VIs, so I took to using sequence structures in an effort to try to force events to occur in a predictable order.

As an aside, I have witnessed non-deterministic outcomes when I call a property node from within a case structure. When we start to tax our system [and the kind of Doppler sampling we're doing taxes the he11 out of a system], I won't get a result back from one wire's call to a property node within a case structure until AFTER some other wire has performed a little logic and then EXITED the case structure. But I was able to force the system back into deterministic behavior by putting the first wire's call to the property node in the first panel of a sequence structure [within the ambient case structure] and the logic on the second wire in the second panel of the same sequence structure [before the second wire then exits that sequence structure and the ambient case structure]. My guess is that calls to property nodes invoke [by default] the spinning off of separate threads, but that even child thread calls are required to terminate before a sequence structure panel can be exited. But that's just a guess on my part; I haven't gotten that far yet.

Another reason I took to using sequence structures was that I seem to have wires all over the d@mned place, and they keep going, and going, and going, almost interminably. Even when I subVI the he11 out of a block diagram, I'm still getting things like shift registers within shift registers within shift registers, and, before I know it, I'll start a wiring run and find that I can't get to where I need to go because I've run out of intermediate stopping points where I can temporarily attach the wire. However, if an ambient sequence structure dominates the block diagram, then not only does it help me organize my work, but it has the added benefit of providing a physical infrastructure to which I can attach wires temporarily until I can find their ultimate destinations.

This also gets back to why I took up the study of local and global variables in the first place: I had thought that I might be able to use 'Global Variables' so as to minimize my use of constants and these seemingly interminable wiring runs. However [as I note below], to my ear at least, I find that the National Instruments folks misnamed the terms 'Local Variable' and 'Global Variable,' and that what I really need are things that behave more like 'Local Variables.'

Along those lines, I found a KnowledgeBase document last night which indicates that property nodes and refnums are really the way to go [and that was the way I had been headed anyway, because property nodes and refnums feel more like pointers to me]; it turns out that 'Local Variables' [as opposed to e.g. Property Nodes] do funky things with the underlying User Interface display engine, at least so long as those 'Local Variables' are called in 'non-synchronous' mode [which seems to be the default]:

What is the Difference Between a Local Variable and a Value Property Node?
http://digital.ni.com/public.nsf/3efedde4322fef19862567740067f3cc/74ecb57d3c6df2ce86256be30074ec47






0 Kudos
Message 6 of 9
(3,486 Views)
> PS: Does anyone sense that the terms "Local Variable" and "Global Variable" are used in LabView almost exactly the opposite of the way they're used in the C-languages [C, C++, Java, C#]? A LabView "Local Variable" appears in subVIs as though it were a C-language global variable being encountered in a function call [object method], whereas a LabView Ambient VI stares down at a "Global Variable" as though it were a C-language function [object method] staring down at one of its local variables.

Now that I think about it, if you were to take a picture of a bunch of Ambient VIs with pointers pointing down to a single Global VI, and then flip that picture upside down, you'd have a picture of a bunch of Ambient VIs with pointers pointing up to a
single Global VI, and then the terminology might make more sense.
0 Kudos
Message 7 of 9
(3,486 Views)
The best way to get deterministic behavior is to make use of the error in/error out connections that are on most of the functions. The sequence structure does it but it has it's own problems (such as no data available from it until the last sequence executes) but I do use it in certain limited situations. Without dataflow enforced by something, the abilityy of LabVIEW code to execute in parallel can be a huge advantage but I will agree that it takes some getting used to when moving from text based languages. Your long runs of wires and multiple shift registers could perhaps be eased with different programming architectures such as state machines and the event structures. Notifiers, semaphores, queues, etc. can also be used to great
benefit. As far as as your confusion between global and local variables, a global variable can be accessed by any VI running in a single instance of LabVIEW whereas a access to local variable is limited to that VI in which created it. I don't think that definition is any different in other programming languages. I use local variables a lot in writing UI code but never to eliminate long wires and in your case, you should have used a local and not a global. They create copies of data and I don't like wasting memory when I don't have to and there's always the danger of a race condition when multiple operations are modifying the same global. Property nodes and refnums are great for subVIs but again, not as desirable as working with the wires directly.
0 Kudos
Message 8 of 9
(3,486 Views)
The Global vi is just a holding place to hold all global variables. In C you must declare global variables. The global vi is a place where they are declared, no need for a block diagram since this is a declaration section only (sort of like a ".h" file in C). It is "global" in the sense that any vi can read or write to the global. Vi1 can write to it, and vi2 can read the new value. Locals, on the other hand, are local only to the vi in which it is constructed. If vi1 has a local, that variable is not accessible by vi2, unless it is passed by connector pane. So in my opinion, globals and locals are just like in C or VB or any other programming language. When you put a reference to a global in a vi, the vi contains a pointer to the global variab
le which is stored inside the global vi. That reference can be created in any vi, which makes it truly global. Is this clear enough?
- tbob

Inventor of the WORM Global
0 Kudos
Message 9 of 9
(3,486 Views)