LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Another question on Local Variables and their usage.

Solved!
Go to solution

I've read many many posts on the forums about how we should avoid the use of Local Variables at all cost because they go against the data flow paradigm of LV. However I've been trying to figure out a way to replace them in my programs and have not.

 

Basic explination:

I use a state machine to run through specific test steps in validating and testing of basic electronic equipment. (Fuse panels, timers, relay moduals) Many of such equipment contain indicator LED's. In the tests I have taken pictures of the products and then used boolean indicators to replicate the LED's on the FP so that the test operators can check to make sure the equpiment LED's turn on when needed. My issue is that many of the products contain 20+ LED's and have no order to how they are lit. Due to this I have ended up making a boolean indicator for each LED, putting all the indicators in a disabled structure, then using Local Variables in each step to display on the FP what LED's should currently be on. This often involved a lot of Local Variables over the whole program.

 

I tried making a very basic sample VI to try and show what is a normal procedure. How can I reduce the amount of Local Variables without increasing the complexity of my VI's?

 

 

Download All
0 Kudos
Message 1 of 11
(4,099 Views)

Hm, nice question:

What is "increasing the complexity of the VI" mean? Does it mean: increased readability and therefore better maintainable? Or does it mean: simpler wiring?

Most often, removing variables require increased amount of shift registers in the code. So complexity of wiring can increase, but the advantage is clear: i see the source of the signal, i see the sink. There is no runtime issue since the wire contains the value

Using variables can decreasing amount of wiring, therefore the code might appear more simple. But you buy yourself the risk of race conditions (not necessarily) and adding functionality might be more difficult since you do not see all signals flowing through your VI.

 

Just some hints:

- Error Case: remove the variable "Error Bar" in the inner case and wire the value from the variable outside into the case. 

- Error Case: remove the variable "Error Bar" completly and use the shift register you already use for "Error" in this case.

- Replace all "Unit Failed" variables using a shift register

- You complicate the code by using two stacked loops. Extend your inner state machine with an "idle case" which essentially contains the functionality of the outer loop

- The LEDs should be updated each iteration after leaving any case of the state machine. You should use a shift register to hold the values (array of booleans)

 

hope this helps,

Norbert 

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
Message 2 of 11
(4,088 Views)

In my case there are never any race conditions for the LEDs, it would just make the diagram very messy by having individual shift registers for every LED. And a Boolean array doesn't work because all the indicator LEDs are not always in a row, sometimes random across the picture.

 

Thanks for the tips on my "Error Bar".  I'm not sure how a shift register would work in this case. I don't want to add code to concatenate a string on every singe test case and I only want to add the Error Code when an error actually occurs.

 

Also I cannot simply align the LED indicators on the right outside of the case structure because there are many situations where the LED configuration changes within the test and I want to make sure to indicate every change as it is made.

0 Kudos
Message 3 of 11
(4,080 Views)

Norbert gave some good thought there. Let me try to express the basic idea and concern another way...

 

Background: 

 

In C and other languages, temporay values where stored in something called local variables.

 

Since controls and indicators having something called Locals, the assumption is that if they have the same name they are the same thing and can be used the same way. in pre-LV 5.1 this was almost the case. But ever since multi-threading was introduced (in LV 5.1) we now have the potential of race conditions (was possible beofer but now it can be worse).

 

Solution:

 

Locals in LV should not be used for storing information. Think of the objects on the FP as just graphic represntaions of COPIES of the data. The real data should only be in a wire.

 

I can think of one subtle exception to this rule and it is when a user changes as setting on a FP control becuase when we read from that object we are getting anew value that should replace a value in a wire somewhere.

 

So terminals and locals are just ways of moving copies of real data to/from the GUI and are NOT intended for storage.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 4 of 11
(4,076 Views)
Solution
Accepted by topic author JonJay

If the LED's change state within the test - within the case statement - then you need a parallel loop.

 

I made a Cluster of your LED's, and made a Producer/Consumer architecture of your "Test 2" case - see attached.

 

Edit: In my picture, on the bottom loop, the text should read "Your 6 LED's are now one Cluster" rather than "Your 6 LED's are not one Cluster". Smiley Wink 

Message Edited by Broken Arrow on 12-16-2009 08:00 AM
Richard






Message 5 of 11
(4,072 Views)
Seems to be much messier than using Local Variables, but I do understand the convention a bit better now. Just wish the "proper" way of doing it didnt involve so much more coding per case as some tests have upwards of 50-75 cases.
0 Kudos
Message 6 of 11
(4,053 Views)

DukeGriffin wrote:
Seems to be much messier than using Local Variables, but I do understand the convention a bit better now. Just wish the "proper" way of doing it didnt involve so much more coding per case as some tests have upwards of 50-75 cases.

 

Changing the oil in my car seemed messy too, so I stopped doing it. It ran GREAT....  for a while.

Richard






Message 7 of 11
(4,047 Views)

DukeGriffin wrote:
Seems to be much messier than using Local Variables, but I do understand the convention a bit better now. Just wish the "proper" way of doing it didnt involve so much more coding per case as some tests have upwards of 50-75 cases.

You should try to understand dataflow better and avoid using all of the local variables. Not only were you ising them for your LEDs but your code is littered with them for most of your controls. As mentioned the controls and indicators should only be there as a GUI copy of the data. I think if you take some of the suggestions given here and apply them to your application you will find that your tests will become easier to maintain and modify. There is a reason that you are being given very similar advice from the many very experienced LabVIEW programmers here. Many of us have learned the hard way over the years. What may appear to be easy or less messy as you put it actually has the potential for causing some very nasty bugs which will be very difficult to track down. You may think that you don't have any race conditions but you have several places where updates to your LEDs occur in parallel. You have no dataflow controlling the sequence they are being updated and your code is not guaranteed to operate left to right. In addition, the decorations you placed over your booleans may be useful for highlighting your comments but they also give a false impression of actual dataflow being used since you have wires running through them.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
0 Kudos
Message 8 of 11
(4,013 Views)

The decorations and coments were put in place of the actual subvi's and tests that I preform. All of my test subvi's have error wires so that everything can be in line with data flow. I mearly represented them in the sample vi so I didnt have to load up all of the subvi's that I use.

I understand dataflow decent enough and am still updating all of the code from a previous programmer who used sequence structures everywhere. Besides the LED indecators and the few Local Variables that I use in my "Stop" and "Error" case I use normal indicators. 

 

I agree that there are several obvious places that I can put in shift registers where I am currently using Local Variables. However don't judge my programming skill on a quick sample vi that I wrote up to give the general impression. 

 

Also question on the Producer/Consumer architect: What do I do if I have 20+ LED's to update? The bundle cluster would be huge and take up enourmous amount of space and I'd have to update each LED ever time I want to change one. Or am I missing something obvious for this?

0 Kudos
Message 9 of 11
(3,981 Views)

I use large clusters with more than 20 indicators (not just booleans) in many of my programs.  If you use the Bundle by Name and Unbundle by Name primitives, you get self documenting code and only expose the particular element you need to update.  A single shift register is all you need.

 

If your Booleans cannot be easily grouped into a Cluster on the front panel, continue to use the individual indicators and wire the Unbundle by Name terminals to the boolean indicator terminals.

 

Lynn 

Message 10 of 11
(3,975 Views)