LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Best practice to pass control around the main vi

Dear all, 

I have been looking for a while I still haven't found a clear picture about the best practice to pass control information around and under which "format". In my case I'd like to use a producer/consumer structure but since I have quite some controls, I did bundle all of them outside the main while loop and then unbundle where needed. For instance inside the event structure I use the "new value" to update the cluster since I use all the controls outside the main while loop to create the cluster.

Is it a good practice? Or by doing so I'm using a lot of memory passing the whole data continuously around with a shift register instead of placing local variables here and there when I need to use the value associated to a control? 

I saw the way Ben initialize the main vi in this thread but using references: is it a better way?

 

Thank you

E

0 Kudos
Message 1 of 6
(126 Views)

"Quite some controls" generally means too many!  That makes me want to warn you about having a busy front panel.  My best advice it to go ask your User to tell you a "User Story" about what they want to do interacting with your code.  Ask some leading questions like;

  • Is this set of controls a logical group of settings?  If so offer a configuration pop-up vi that can change that group and even load/save them to User defined configuration files e.g. look at the pop-up under Tool>>Options.  Imagine if all those controls were always visible at development time.
  • Do you need to change this often? If not, try a menu instead.
  • What is the most important information? Usually that is a very few points (or even None) during the main execution.   A progress bar might be all they want to see rather than being glued to the chair like a couch potato while the vi is doing its thing and they can go about important stuff like drinking coffee!

The point is that your Users can be doing other things BECAUSE the software is working for them!  The machine can run better, faster, stronger than the User's eyes and hands (That's exactly why you wrote the software anyway RIGHT?)


"Should be" isn't "Is" -Jay
0 Kudos
Message 2 of 6
(93 Views)

Thank you for the answer but maybe I should develop a little more: I have a program for the user (me) that it is working but not in optimal conditions: mainly I have local variables I would get rid off and make it more compact in order to be easier to modify in future by a different user if needed (I developed the program to run an experiments as part of my PhD). The "quite some controls" are actually not so many, like 12, then I have othe 10-ish that you rarely need to use....I divided them in different tabs in order to look at the controls you need for the specific experiment. However my question would be in a more general way, what to do if one has something like many controllers, how to handle them in the most efficient way. Should one use references and bundle them? Even if personally I don't like it too much because of the need of property node tools in order to access the value which would slow down the whole process. Would one bundle everything in big cluster and send around using shift register? This I'm already doing in a state machine in order to control a specific tool.

During the execution of the experiment you don't really need any interaction at all with the program, but some graphs are updated and that's it... For this I have implemented a way that I saw on a NI conference (?, maybe was not a conference but, anyway) in order to calculate and predict the end of the execution (that one works extremely well)! Also because the whole process takes several hours so you really don't want to stay there :).

 

Thank you for helping,

E

0 Kudos
Message 3 of 6
(82 Views)

Since we are graphical programmers, an actual VI would show your concepts much better that long wordy paragraphs. Some fantastic LabVIEW programmers are even dyslexic to some degree.

 


@EdoardoA wrote:

Or by doing so I'm using a lot of memory passing the whole data continuously around with a shift register instead of placing local variables here and there when I need to use the value associated to a control? 

I am sensing that you seem to have some misconception about shift registers. 

They operate "in place" and nothing is ever "passed around", so they are the most efficient way to keep data. (Of course if they contain arrays and their size change, some memory allocations need to be made occasionally, but only as needed). 

Local variables and value properties require additional data copies in memory. In addition value property nodes must execute synchronously for significantly more overhead (thread switch, etc.).

 


@EdoardoA wrote:

. For instance inside the event structure I use the "new value" to update the cluster since I use all the controls outside the main while loop to create the cluster.


If you have all controls outside the toplevel loop to initialize the shift register data, you now need either N event frames or an event frame that needs to figure out what actually changed, so you just shift the complications elsewhere. Reading even 100 scalar controls is trivial, and it might be easier to just have an event for all and bundle them hack if any of them changes. Maybe you could have events for a few logical subsets of the controls. Depending on the front panel design, you could even contain all controls inside a cluster right there. (The container can even be made transparent).

 


@EdoardoA wrote:

I saw the way Ben initialize the main vi in this thread but using references: is it a better way?


It is not clear what you mean by "initialize". If you want the program to start with a set of typical control values, make these the default. This guarantees that all are as expected once you built an executable. During development (only!), you have the problem that controls could have been changed at edit time and are thus not predictable. There is a method to initialize all to default that can do it in one swoop. If you need to programmatically change control values at runtime, local variables are most efficient (But don't forget to update the cluster element too. Or you could write to a signaling property to fire the event that updates the cluster if used sparingly). You don't need to worry about initializing indicators, because the VI can be set to "clear indicators when called". This is useful if certain indicators are not in the dataflow early.

 

Sometimes, all initial control values are read form an ini file that can change between applications, and there are tools for that.

 

I would recommend to attach a simple code skeleton (Maybe 10 controls) and shows us exactly what you are doing for a much clearer picture. Save it for LabVIEW 2020 or below. This will give us opportunities for more detailed comments.

 

 

0 Kudos
Message 4 of 6
(64 Views)

@EdoardoA wrote:

Thank you for the answer but maybe I should develop a little more: I have a program for the user (me) that it is working but not in optimal conditions: mainly I have local variables I would get rid off and make it more compact in order to be easier to modify in future by a different user if needed (I developed the program to run an experiments as part of my PhD). The "quite some controls" are actually not so many, like 12, then I have othe 10-ish that you rarely need to use....I divided them in different tabs in order to look at the controls you need for the specific experiment. However my question would be in a more general way, what to do if one has something like many controllers, how to handle them in the most efficient way. Should one use references and bundle them? Even if personally I don't like it too much because of the need of property node tools in order to access the value which would slow down the whole process. Would one bundle everything in big cluster and send around using shift register? This I'm already doing in a state machine in order to control a specific tool.

During the execution of the experiment you don't really need any interaction at all with the program, but some graphs are updated and that's it... For this I have implemented a way that I saw on a NI conference (?, maybe was not a conference but, anyway) in order to calculate and predict the end of the execution (that one works extremely well)! Also because the whole process takes several hours so you really don't want to stay there :).

 

Thank you for helping,

E


So that is your User Story: 

  • at application start load configuration settings
  • Allow some sort of configuration setting via a pop-up dialog
  • Allow a start and, of course abort method 
  • During run display only a Graph and progress bar
  • Indicate completion (with results)

You probably saved some data to a file along the way.  TDMS let's you add group information like configuration settings an Events like Start/end events with useful information like time and results.

 

I really dislike Tab Containers on the Main UI (sometimes they are useful for pop-up dialogs) but, for an experiment running essentially without User interaction, a lean UI that can be glanced in passing is highly preferable.

 

Group your data into logically related clusters...encapsulation, abtraction and data hiding are valuable concepts.  "A Software Engineering Approach to LabVIEW" is a good reference book to learn more.  WARNING: Do not leave that book laying around! The book seams to grow legs and run away from your desk.


"Should be" isn't "Is" -Jay
0 Kudos
Message 5 of 6
(54 Views)

Dear all, thank you so much for the precious advices! I attach a dummy VI with the main part of the dhift register loop and couple of exammple in event structure.

looking forward to hear your recommendation! 

 

E

0 Kudos
Message 6 of 6
(29 Views)