01-20-2009 05:31 AM
Hello,
I need to structure my program and I'd like to ask for some help.
I have a main VI that deals with a big text file, where some registers are defined. It looks like this:
#REGISTER_NAME# (#REGISTER_NUMBER#)
#Field1# (#default_value#) // #field1_information#
#Field2# (#default_value#) // #field2_information#
.....
//INIT #Field1#
...TEXT_CODE1...
//END #Field1#
...
//INIT #FieldN#
...TEXT_CODEN...
//END #FieldN#
A sub-VI will generate the register code (using Controls), and the register field data. If this SubVI is called to edit a predefined field in register, it will read the
field information and load the values in the SubVI controls.
The problem is that this is becoming VERY messy. If I have 8 values to set for one field, I have to read 8 property values, build a string .... and same story if
I want to edit a field, I have to read the long string, change the control values .... nightmare.
The SubVIs perform different code generation, depending on the external "type", given by the main VI. But different field types can be in the same register.
As well, some SubVIs will generate more than one field ...
Of course, I need to check that size is not overflown ... each field uses a number of bits, ans the maximum is 16 per register.
Default values have to be managed as well ... and masked to make up the global register default value.
In summary, I have done this but it's really messy, so I would like to change the structure of the software so it's more readable and easy to upgrade in the future ...
Any suggestion?
Thanks.
01-20-2009 05:57 AM
Save and load file functions are usually messy 😛
First, I would create a datatype of the chunks of data, like a cluster, with items FieldName, DataText, Information. Then when reading or writing data I would buffer it all in an array of the datatype, allowingme to easily insert, delete or reorder the elements
01-20-2009 07:24 AM - edited 01-20-2009 07:25 AM
Could you post an example of your file(the text file). I maybe be able to help. To be sure I need a sample.

01-20-2009 08:13 AM
Sure. Two registers, with only one field per register.
// REG: MAIN_VOLUME
REG(1):*0050*:
0[8:0],
LEVEL[6:0]; // @Single 1:MAIN_VOLUME:LEVEL:20.000000:-80.000000:0.000000:1.000000: // Single 1 , 0h: -80 dB , ... , 80h: 0 dB , ... , 100h: 20 dB
//INIT LEVEL
<param_base> = (LEVEL>100.000000)?(stop):(0);
<safeload> = 1;
<slew> = 1;
<Single1_0> = (LEVEL>100.000000)?(nochange):(db(((LEVEL-80.000000)*1.000000)));
<Single1_1> = (LEVEL>100.000000)?(nochange):(db(((LEVEL-80.000000)*1.000000)));
//END LEVEL
ENDREG
// REG: MISC
REG(2):*0000*:
0[14:0],
OUTPUT_MUTE[0:0]; // @Mute1:MISC:OUTPUT_MUTE:0:0: // Mute1, 0h: Unmuted , 1h: Muted
//INIT OUTPUT_MUTE
<slew> = 1;
<Mute1_0> = (1 -OUTPUT_MUTE);
<slew> = 0;
//END OUTPUT_MUTE
ENDREG
01-20-2009 08:33 AM
It would be most managable to use a cluster to define a register and a cluster to define a field, then include an array of fields in the register. If the data needs to be polymorphic you can use a variant type and use an enum to store what the datatype is. Your main data would then simply be an array of registers which could be neatly looped through
I cannot quite determine which part of your data are fields, but here is a general outline:
register
{
string RegisterName;
field Fields[ ];
*other data*
}
field
{
string FieldName;
enum DataType{string, I32, bool};
variant Data;
*other data*
}
01-20-2009 11:21 AM
REG(1) has 2 fields, an empty field 0[8:0] (9 bits length) and LEVEL[6:0] (7 bits length), 16 bits in total.
REG(2) has 2 fields, an empty field 0[14:0] (15 bits length) and OUTPUT_MUTE[0:0] (1 bits length), 16 bits in total.
Empty fields have no code. The code for the fields is delimited by //INIT FIELD_NAME //END FIELD_NAME.
Your suggestions sound good - one question, what is the boolean in the enum Datatype for?
Im going to try to implement this, I will get back to you.
Thanks.
David.
01-20-2009 11:32 AM
To handle NULL data, include a 'no data' item in the enum
The boolean was just another item added to the enum list in the example. I don't know your data, so I just padded it out a bit for completeness.
When looping through fields, you can append the //TAG data to the data file, and omitt it when reading it into your software - You know where the data begins and ends as it is in the cluster!
Remember that when you read in data which is 1 bit long it will be extended to 1 byte (8 bits) to fit into the operating system.
01-22-2009 04:35 AM
I have implemented the structure you suggested .... looks good. Just some questions now:
- I think the best will be to generate the code after all parameters in the register map are set. Depending
on the register type, and the variant data, I should call a subVI that generates the code.Does itmake sense?
- Each type of field will have a panel, with different controls and indicators. Basically, I need to store this data (the settings of the VI).
This data will be used to edit the field (if the user wants to change any parameter), so the values of the controls/indicators will be
loaded into the subVI, and to generate the Register Code (output a text file). Can I store this values in the variant datatype?
Thanks,
David.
01-22-2009 04:48 AM
Yes makes good sense! Generating the code and then processing with it would be the neatest way of doing it. You use a couple of for loops to buffer it all into memory, in a consistent format, but with the possibility of different data and datatypes.
If each field has the same number of parameters in it, then create that number of controls in the field cluster. Similarly, if they have the same datatypes then avoid the variant and go straight for that.
01-22-2009 05:07 AM
Unfortunately, each field has different number of parameters / types ... so I can't create those controls in the field cluster.
Should I use the variant then? Im not very familiar with it, is there any document I should read?
Thanks,
David.