Thank you for the reply. Yes, that code is too much and is not how the original is written. I did it that way to demonstrate how the Local Variables do not work, while the Property Nodes do.
I am still getting my sea legs here. I need to learn a few things, I think:
1) When to use Local Variables, Global Variables, References, or Nodes and their strengths and weaknesses.
2) Structures and shift registers. I am adept with writing lines of code, but am having a bit of a time translating loops to G for some reason.
3) Enums and when to use them.
And, I need to find a definitive function reference. I know there is a function for a given task, but scanning through the Functions Palette and trying to decipher what function does what and how is a steep learning curve.
I'm still working on it!
I am unsure how a shift register (I am unsure of shift registers!) will help. There are three distinct events:
1) User changes control value.
2) User 'sets' that value to be used.
1) Changing the value might be done inadvertently, so the driver cannot read that control.
2) Setting the value immediately calls the driver.
3) Turning on the instrument fires the driver and the set value must be recalled.
If I understand correctly, shift registers are used in Case and While structures. I could nest a While Loop with a shift register inside the "DC Set" event of the Event Structure, but that register (and its value) would not be available for the "DC On/Off" event which requires that value. That is why I am using variables, controls, and nodes.
Additionally, until I can free myself of Local Variables, I cannot use the latch action for the Boolean switch.
Maybe I'm missing something...
One of the more difficult things to embrace when transitioning from text based languages to LabVIEW is to switch from thinking about your program sequentially and begin thinking in terms of data flow. One of the most important things to remember is that in LabVIEW a node is ready to execute as soon as all of it's inputs are available. By using local variables, global variables and property nodes you break data flow and create race conditions. I have been using LabVIEW since the mid '90s and work on some very large applications. I have not used a global variable since the mid '90s when I first started using LabVIEW. To me they don't really exist. If I do need something like that I will create a functional global variable (FGV). They are also called action engines. This is a subVI that contains a while loop with an uninitialized shift register. Uninitialized shift registers retain their value between separate calls to the subVI. FGVs provide a layer of safety to help minimize race conditions. They do not completely eliminate them but they do provide a single copy of the data. Global and local variables can create copies of the data which lead to the race conditions.
More recently I have been using dynamic references or LVOOP objects to encapsulate global data. LVOOP has advantages over action engines in that I can create methods with different connector panes. You cannot do this with action engines. My preferred implementations though are to define explicit APIs between my various components and use that to pass data. This is fairly easy to do using LVOOP. The designs are cleaner and the data stays with the objects. If you have various components all reaching into each other's data then your system is highly coupled and will not be very easy to maintain or extend.
One exception for using local variables and property nodes are for UI specific code. Code that is specifically controlling the UI needs to use local variables and property nodes. Local variables are a bit faster than property nodes so if you are only updating the value of the control/indicator use the local variable. Use property nodes if you are changing attributes of the control/indicator or using them in subVIs specifically used for UI control.
There is one global variable that some people find OK to use. This is known as a WORM. This is a write once, read many value. I personally do not use them but you will not run into race conditions with them since they are effectively a read only value.
Shift registers are used on loops. You cannot put a shift register on a case statement. What they do is pass a value from one iteration to the next. As mentioned above an uninitialized shift register maintains the value between calls if it is in a subVI. If initialized every time you call the subVI it will start with that value and the next iteration of the loop will see the value of the last iteration. Starting in LabVIEW 2009 they introduced the feedback node. This behaves like an uninitialized shift register and does not require a loop. However the behavior is the same. It will contain the value of the last time it was executed.
What you generally want to do is to have your UI control be driven using an event structure within a loop. The out loop would have any shift registers you need (you can combine elements into clusters to reduce the number of wires and shift registers) for the data you need to persist through your execution. The shift register passes the data from one event to the next. Use of "Value change" events for your controls will let you know when a value has changed. You can use user events so that subVIs can send events with a data change as well. These events can be used to update values programmatically. This also helps to separate your processing code from your UI. The user events define a clean API. Queues and notifiers can also be used. Which depends a bit on the particular architecture your are using.
As for when to use ENUMs it depends on the design. However they are very useful for state machine and message IDs as well as other uses. Their use is similar to that of text based languages. There are some valid reasons for using strings where you might use an ENUM. Some prefer to use strings for state machines. I prefer to use ENUMs. The important thing to remember when using ENUMs are to create a typedef for them. If you don't you will defending regret it down the road.