LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to save and recall configuration data in sub-VIs?

I am interested in refining how I deal with configuration data and configuration files.  Dealing with config files is a real pain, because the files need to be read at start-up, saved when something changes or at exit, and routed all over the place to get used by any routine that needs configuration information (I do a lot of converting data from volts to meaningful units, so there is a lot of conversion factors running around).
 
Here's some options, from simplest (and broken) to more complex (and better).  Needless to say, I have questions and want input on the latter
:
0.  Have a subroutine that reads or writes (based on an enum) a custom file format from the hard disk and outputs all configuration data as a cluster.  Wire this cluster to a global in the top level routine and use the Globals whenever they are needed.  This is #0 because I've had terrible luck with Globals and I now avoid them all together.
 
1.  Same as above, but instead of using globals, wire the cluster directly to all sub-VIs that need it.  This makes for a mess of wires for large applications.
 
2.  Same as above but use TDM instead of a custom file format.  I haven't done this yet, but TDM seems pretty useful.  Does it have any major problems?
 
3.  Use the TDM file format and create a subroutine that reads from disk, writes to disk, reads to functional globals and writes to functional globals based on an enum.  Bundle all of the data into a cluster and use it locally in every VI that needs it.  Only use the reading and writing to the hard disk for start-up and exit.  I haven't done this yet, but because functional globals are reasonably efficient, and I no longer have to pass the clusters all around, there shouldn't be too serious of a performance hit here.  Is that right?
 
4.  Is there a way to load only the data that is needed?  For example, if there are 100 different pieces of configuration data (ints, doubles, strings, arrays, enums, bools, ... the works) and I only want 1 of them.  I could use an enum to select which I wanted and then use functional globals and polymorphic VIs, however I think the enum would have to have the same items for each polymorphic instance, which would mean that a number of bogus states exist (for example, if the enum is for an int type, but a string is wired up).  Variants also seem like an option, except they would have to be cast outside of the calling routine, which is not good.  It seems like polymorphic VIs could be a good way to go, but then all of the routines need the same number of inputs and outputs, so this could get difficult if I want a group of configuration items, for example 20 of the 100.
 
The behavior I'm after is like a DLL.  I want to call a specific function from a sub-VI and have each function have it's own inputs and outputs.  Some limitations (like the number of inputs and outputs) would be okay.  I'd like to not have to actually build a DLL out of many VIs because it's easier to code, and actually possible to debug, without the application builder step.
 
What's the right thing to do?  If #4 doesn't work out, I guess I could just make a different routine (TDM, read/write to disk, read/write functional globals) for each piece of configuration data and use them all locally.  That would add a bit of extra work, but it would get rid of the clusters.  Then, when all the bugs are worked out I could make one DLL out of all of my many routines.  Then again, I could just skip making the DLL and leave it all in Labview.  However, the clusters method seems efficient, so breaking up the clusters might cause a performance hit.
 
Is there a better way?  Are there any serious pitfallls here?  What's easy?  What's fast?  Any comments, conjecture, heckling or sage-like enlightenment is welcomed.
 
Thanks,
Casey
 
 
 
 
 
0 Kudos
Message 1 of 5
(3,060 Views)
Hello,
 
How about this as an alternative:
 
Use a functional global which has 3 cases:
 
1. open config file - it opens the config file and reads the contents into a string (which is the functional global data), and you only do this one time at the beginning of the program.
 
2. edit config data - it edits the string, which are really the contents of the file, but doesn't worry about writing to the file.  you could even get fancy here, and allow an array of tags and an array of values as input, and it would go update/edit all the tags to have the corresponding values.
 
3.  close config file - it writes the current string data (the functional global data) to the file and closes it.
 
Using the functions in the string palette, I think you'll find most of the code for that module/functional global will be easy to write.
 
I hope this helps!
 
Best Regards,
 
JLS
Best,
JLS
Sixclear
0 Kudos
Message 2 of 5
(3,050 Views)

I haven't thoroughly read your post (it's quite long), but have you looked at the OpenG config file VIs?

Also, if you use an enum or a set number to extract each parameter, you could define for the parameter what its type is and if the type doesn't match the type wired into your polymorphic type input return an error (or default data).


___________________
Try to take over the world!
Message 3 of 5
(3,041 Views)
JLS-

I think that might be the simplest way to go.  If more files are needed, then I would just make another functional global open/ edit/ close routine to handle it.  It wouldn't be quite as clean as finding a way to handle all parameter in one DLL like routine, with many sub-functions.  However, it also steers clear of polymorphic VIs and variants, which would both add quite a bit of headache for not a lot of benefit.

Let me know if you think of a way to easily take it to the next step.  Thanks,
Casey

0 Kudos
Message 4 of 5
(3,025 Views)

Hello,

I am not familiar with the OpenG config file VIs, but I think the string functional global I suggested is a good working solution with a simple implementation.  On the downside, if anything crashed during your program execution, you would not be writing to disk all the time so you can lose information.  However, many solutions have this same problem, and are harder and more expensive to implement 🙂 

Even if you find a better way, you won't have lost much time programming a cute little generalized version of that functional global 🙂

Best Regards,

JLS

Best,
JLS
Sixclear
0 Kudos
Message 5 of 5
(3,006 Views)