LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

control references vs. global variables

I guess my question centers on the appropriate application of control references.

I am writing a complex program that has a state machine at the top level, and, for one frame of the state machine, a while loop containing a couple subVIs, each of which contains many subVIs. The lower-level subVIs are affected by buttons on the top-level VI. Information from the lower-level VIs must be shown on the top-level front panel within the loop. My question is: what is the best way to do this?

(I have a previous version of the program that I wrote that keeps just about everything on the top level so that I can update the front panel, but this is not at all modular.

In addition, I considered breaking things up into more than on
e front panel, but this doesn't seem to be a good option for this section of this program.)

Last week I read about control references, and decided that this could be the way to deal with this issue. I have not worked with them before, so I want to know: Are control references an appropriate solution for this issue? Is it good programming practice to use them, especially to update data on charts and graphs? How do they compare programming-wise and efficiency-wise to global variables?

Global variables are another solution, I think, but I would have way too many variables to update. I think the advantage with global variables is that one could just insert a global variable in a subVI and not have to wire it up through the different subVI levels, which one would have to do (I think) with control references.

Can you offer any advice?

Thanks!
0 Kudos
Message 1 of 5
(4,374 Views)
Paul,

The actual implementation of the solution is up to you. This is indeed a complex question.

I would offer the following advice:

On globals:

Try to avoid them. I try to restrict the use of globals to unidirectional. If you have ever dealt with a race condition, you will know why. Mistakes are often made with globals, and they are quite apt to become the biggest source of bugs in a program, especially in one as large and/or complex as your appears to be. If you must use globals, try using a shift register, or LabVIEW 2 style global instead. Basically, you use an unitialized shift register with two (or more) cases: Read and Write. This prevents race conditions, but only if the VI is non reentrant. However, implementation is still difficult.

Control References:
I also have read and heard about control references. I have had much use for them, for controlling the appearance of controls and indicators (and decoratiopns too, I guess...). However, I would caution you on using them to pass data around. This violates dataflow in a big way, as you are passing around pointers, instead of data. I believe this is difficult to implement, and even more difficult to keep straight. I personally recommend using them only for attributes of FP components, not for passing data.

So, what do I believe is the most elegant solution? I think a data server is your best bet. This is close to a LabVIEW 2 style global, but a little more active. Simply write all of your data into a subVI in any manner, a queue, a FIFO, LIFO, etc. Then, retrieve the data as desired. Buffering, queuing, etc are all handled by the data storage and retrieval subVI. It becomes sort of a small active database. The two sides (storage and retrieval) are independent of each other, and the code is all handled in the function. A basic version is a LIFO, Last In First Out, wherein the data is overwritten constantly. The data is then read by the reading VI, the front panel VI in your case, at any time, and the data is always the latest. You can add complexity as you need, such as making it a FIFO. This is done by simply writing the data to an array, then reading back the oldest value (by reversing the array and reading index 0.)

I believe this is an elegant solution to your problem. It does maintain dataflow, except that time is taken out of the equation, depending on how you look at it. It simplifies your program because you only need to do three things. Write the data handler, then drop in the function into the VI that writes, and the one that reads. It is also flexible in handling the data.

Good luck, and let us all know how you do.
Message 2 of 5
(4,374 Views)
Definitely use control references. This allows you to treat the whole thing in an Object Oriented view. A control then just becomes an object. Be careful of race conditions.

I have entire programs with no wires connected to the controls and indicators. All communication is then controlled through the subVIs. This lets me make the top level program with subVIs that are "Initialize, check RTM, check for button pressing and close". Nice program flow.

I have attached a library that I hope will help you work with the control references. I open the reference in my initialization routine and pass the reference and error cluster down the line to each subVI, then close the reference at the end. You can also pass data between subVIs using this (but REALLY watch
for race conditions this way - I don't actually recommend it).

Have fun using references...

Rob
0 Kudos
Message 3 of 5
(4,374 Views)
Thanks! That sounds good. WinZip gives me an error when I try to open the file, though.
0 Kudos
Message 4 of 5
(4,374 Views)
Interesting. I downloaded and opened it with no problems. But just in case... here is a newly compressed version of that library (with one additional routine anyway).

Rob
0 Kudos
Message 5 of 5
(4,374 Views)