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 20
(630 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 20
(595 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 20
(584 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 20
(566 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 20
(556 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 20
(531 Views)

I forgot to mention that this is a very "skinny" vi compared to what I have since many subvi from different instruments are not available unless i share all the installation file as well...companies would not appreciate 😅. Very quickly, the initial subVI is the action engine that controls one of the instruments. While the event structure does manage few controls and actions in this simplified version. But once it is optimized for one should be quick to generalized for other inputs or actions.

 

E

0 Kudos
Message 7 of 20
(485 Views)

Understood. I'll be on the road for most of the weekend. Might have time to look at it tomorrow.

0 Kudos
Message 8 of 20
(471 Views)

Don't modify the tables via front panel references, you have all the data in your main cluster, just send that (the table, not the full cluster) to your table-vi and then update the indicator via the output.

Also the Steps in Exp1 should hide the From To Steps-label and have it as a table heading (just copy the text outside the list and then hide the labels in the list)

 

Otherwise it looks like a decent start!

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 9 of 20
(423 Views)

Thank you for the recommendation! Is there a way to avoid using all the controls in the very beginning? Because I realised that would be better to place them inside the event structure otherwise I would need to create many cases for each control separately in order to avoid variant data type...you have any tip on this side?

Thanks,

E

0 Kudos
Message 10 of 20
(395 Views)