Certification

cancel
Showing results for 
Search instead for 
Did you mean: 

CLD 2 and Functional Globals

Solved!
Go to solution

Hello,

 

I'm having trouble with CLD 2, and I hope you all can shed some insight.  This is my first look at functional global variables (FGVs), but I understand they maintain their values from call to call using the unitialized shift register. 

 

Here's my confusion: When looking at the solution, the caller vi simply calls the FGV many times with the exact same parameters in the while loop, and the counter works as planned.  However, if I simply run the FGV by itself vi many times with the exact same parameters, the counter stays set to zero. 

 

What sort of black magic is being used to cause this behavior?  I'd like to be able to test the functionality of the FGV vi on its own, without being called from anothe vi.

0 Kudos
Message 1 of 15
(6,872 Views)

I'll give you some hints:  Which values are being stored in an unitialized shift register? Which values are not? 

 

Additionally, the Elapsed Time VI is an express VI... have you tried creating an indicator for the "Get Start Time (s)" output and watching that when you run it individually and when you run it as a subVI?

0 Kudos
Message 2 of 15
(6,870 Views)

It has to do with the VI being in memory.  When you run it individually, the First Call? will always be TRUE (which could be your problem).  I could also be that the shift register is losing it value when execution is complete.

 

The short answer is that you really need to use another VI to test your Action Engines/FGVs.  It is very simple to create a test VI.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 3 of 15
(6,865 Views)

Expanding on what crossrulz posted: One of the strengths of LV is the ability to test modules of code (subVIs) independently.  However, the FGV is an exception - it cannot be effectively tested except as a subVI. Fortunately it is very easy to create the calling VI for those tests.

 

Lynn

0 Kudos
Message 4 of 15
(6,850 Views)

Of course the best way to test a FGV in a calling main VI, but when I just want to have a quick test on a simple FGV timer subVI, I can test it on its own: I set the enum to reset, and I run the subVI once. After this I set the enum to "check time" mode, and I run repeatedly the subVI.

I can see how the elapsed time indicator value is increasing... So at least for me, this is OK for a quick test...

So this means to me that the shift register actual value is preserved in the RAM? Since there is no calling MAIN VI here...

 

edit: oh yes, and I do not use the "First call?" in this FGV, I guess that is why it works as it does...so testable as standalone subVI...

0 Kudos
Message 5 of 15
(6,846 Views)

So, this is an example of a functional global, correct?

FGV.PNG

 

I can test this on its own, and the shift register maintains its memory through multiple stand-alone calls.  This FGV does not require a caller for testing.  What is the difference between the behavior of this VI, and the behavior of the FGV in CLD 2?

 

I'm guessing this has more to do with the express VI.  When the main caller loads the subvi containing the express VI, it must create and maintain a single instance of the express vi in memory.  When I call the subvi by itself, it creates and destroys a new instance of the express vi each time it's run.  The shift registers behave as expected; it's the express VI that's not maintaining its values.

 

Does anyone disagree?  Thanks for the comments!

0 Kudos
Message 6 of 15
(6,832 Views)

No! The FGV has also an enum input with two modes: SET and GET (or WRITE and READ).

You need to store the data, and read it out!

 

So a Functional Global Variable has two modes:

GET.png

SET.png

0 Kudos
Message 7 of 15
(6,830 Views)

@Blokk wrote:

No! The FGV has also an enum input with two modes: SET and GET (or WRITE and READ).

You need to store the data, and read it out!


Not exactly true.  A FGV just stores data in an Uninitialized Shift Register or Feedback Node.

 

But let me say this.  If all you are doing is a Get and a Set, just use an actual global variable.  It has the exact same issues as a global (race conditions) but is slower.  There's an excellent article on this concept on the LabVIEW Field Journal.  If you really want some good use of a FGV, then go look at the Action Engine.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 8 of 15
(6,826 Views)

"Not exactly true.  A FGV just stores data in an Uninitialized Shift Register or Feedback Node."

 

Yes, but that is the common way to store data, using a case, no? You set your data and read it out. Of course you do not necesserely need the two modes for this with a case structure...But if you want  to read the previously stored value, you will overwrite it with the input value... So I do not get how you could have a FGV without Enum case...?

 

 SubVI_1d.png

 

 

 

edit: but of course, usually we just use Action Engines, so you have more modes, like in the case of a timer...

 

Edit2: but it is also true that a FGV can still have race conditions. You need to protect the data manipulation part inside the FGV, so we just arrived to the Action Engine with several modes...

 

0 Kudos
Message 9 of 15
(6,818 Views)

Sure, I understand that to do anything useful you need to have at least an enum...for an FGV to behave like a standard global anyway.

 

But that's really irrelevant to the question at hand.  I don't think that the enum is affecting the behavior I was describing.  I think that Daniel was on to something when he asked his question below.  When running the subVI on its own, the "Get Start Time (s)" continually changes, even if reset is false.  When the main caller is used, the "Get Start Time (s)" changes only on the first run and when the reset switches.

 


@Daniel_H1 wrote:

I'll give you some hints:  Which values are being stored in an unitialized shift register? Which values are not? 

 

Additionally, the Elapsed Time VI is an express VI... have you tried creating an indicator for the "Get Start Time (s)" output and watching that when you run it individually and when you run it as a subVI?


 

0 Kudos
Message 10 of 15
(6,808 Views)