From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Reading/Writing Config text data file of different sizes

I know this is mixing the thread sorry, but I use https://jsoneditoronline.org/  to edit my configurations that use JSON, it gives two way view from tree to text or the other way.  I tried to see how to build this as windows app, but did not find anything.

0 Kudos
Message 11 of 29
(828 Views)

Frankly I like using XML for Config Files this complex. 

 

Using Microsoft's FREE XMLnotepad makes it very easy to manually update config files and the LabVIEW XML vi's are full featured.

 

Here's a sample Config file for our tests systems:

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<Test_Rack_Configuration>
  <AC_Source>
    <Type>
      <!--Valid AC_Source values are "Ci5001" "Elgar" "none"-->Ci5001</Type>
    <VISA>
      <!--VISA Resource or VISA Alias-->GPIB0::3::INSTR</VISA>
    <Vout>
      <!--Output voltage range (VAC)-->
      <Max>300</Max>
      <Min>0</Min>
    </Vout>
    <Freq>
      <!--Output voltage range (Hz)-->
      <Max>70</Max>
      <Min>40</Min>
    </Freq>
  </AC_Source>
  <AC_Load>
    <Type>
      <!--Valid AC_Load values are "Ci3091" "NHR" "none"-->Ci3091</Type>
    <VISA>
      <!--VISA Resource or VISA Alias Ignored for NHR-->GPIB0::1::INSTR</VISA>
    <Vin>
      <!--Input voltage range (Vrms)-->
      <Max>350</Max>
      <Min>50</Min>
    </Vin>
    <Freq>
      <!--Input frequency range (Hz)-->
      <Max>440</Max>
      <Min>45</Min>
    </Freq>
    <CC>
      <!--Load current range (Arms) constant current mode-->
      <Max>30</Max>
      <Min>0</Min>
    </CC>
    <CV>
      <!--Load voltage range (Vrms) constant voltage mode-->
      <Max>350</Max>
      <Min>50</Min>
    </CV>
    <CP>
      <!--Load power range (Watts) constant power mode-->
      <Max>3000</Max>
      <Min>0</Min>
    </CP>
    <CR>
      <!--Load resistance range (Ohms) constant resistance mode-->
      <Max>1000</Max>
      <Min>2.5</Min>
    </CR>
  </AC_Load>
  <DC_Source>
    <Type>
      <!--Valid DC_Source values are "DHP" "SGI" " Aglient" "none"-->DHP</Type>
    <VISA>
      <!--VISA Resource or VISA Alias-->GPIB0::2::INSTR</VISA>
    <Vout>
      <!--Output voltage range (Vdc)-->
      <Max>100</Max>
      <Min>0</Min>
    </Vout>
    <Iout>
      <!--Output durrent range (Adc)-->
      <Max>100</Max>
      <Min>0</Min>
    </Iout>
  </DC_Source>
  <DC_Load>
    <Type>
      <!--Valid DC_Load values are "RBL" "none"-->RBL</Type>
    <VISA>
      <!--VISA Resource or VISA Alias-->GPIB0::10::INSTR</VISA>
    <Vin>
      <!--Input voltage range (VDC)-->
      <Max>100</Max>
      <Min>0</Min>
    </Vin>
    <CC>
      <!--Load current range (ADC) constant current mode-->
      <Max>200</Max>
      <Min>0</Min>
    </CC>
    <CV>
      <!--Load voltage range (VDC) constant voltage mode-->
      <Max>100</Max>
      <Min>50</Min>
    </CV>
    <CP>
      <!--Load power range (Watts) constant power mode-->
      <Max>3000</Max>
      <Min>0</Min>
    </CP>
    <CR>
      <!--Load resistance range (Ohms) constant resistance mode-->
      <Max>1000000</Max>
      <Min>0.5</Min>
    </CR>
  </DC_Load>
  <Yokogawa>
    <Model>
      <!--Valid models are "WT130" "WT230" "WT500"-->WT500</Model>
    <VISA>
      <!--VISA Resource or VISA Alias-->WT500</VISA>
    <I_Scaling>
      <!--Enter mV/Amp scailing factor-->
      <!--Note: Scaling will be ignored if a mV range is not used in I_Range-->
      <E1>0</E1>
      <E2>0</E2>
      <E3>1</E3>
    </I_Scaling>
    <I_Range>
      <!--Enter current range for each element or Auto-->
      <!--WT130 and WT230 Range must be the same for all three elements-->
      <!--Valid ranges for WT130 Auto,1A,2A,5A,10A,20A,50mV,100mV,200mV-->
      <!--Valid ranges for WT230 Auto,0.5A,1A,2A,5A,10A,20A,50mV,100mV,200mV-->
      <!--Valid Ranges for WT500 Auto,500mA 1A,2A,5A,10A,20A,40A,100mV,200mV,500mV-->
      <!--Invalid entries will defalt to AUTO-->
      <E1>40A</E1>
      <E2>20A</E2>
      <E3>100mV</E3>
    </I_Range>
    <V_Range>
      <!--Enter voltage range for each element Auto or 0 for autorange-->
      <!--Valid ranges for WT500 Auto,15,30,60,100,150,300,600,1000-->
      <!--Invalid entries will defalt to AUTO-->
      <E1>300</E1>
      <E2>150</E2>
      <E3>60</E3>
    </V_Range>
    <V_Mode>
      <!--Voltage measurment mode-->
      <!--Valid modes are AC,DC -->
      <!--WT130/230 mode must be the same for all elements E1 will be used E2,E3 ignored-->
      <!--WT500 mode can be set for each element-->
      <!--Invalid modes will default to AC (rms)-->
      <E1>AC</E1>
      <E2>AC</E2>
      <E3>DC</E3>
    </V_Mode>
    <Sync_Source>
      <!--Sync Source-->
      <!--Not applicable to WT130-->
      <!--Valid Settings for WT230 OFF, Voltage, Current-->
      <!--WT230 Sync Source is the same for all elements only E1 will be used E2,E3 ignored-->
      <!--Valid settings for WT500 OFF U1,U2,U3,I1,I2,I3 -->
      <!--WT500 sync source can be set for each element-->
      <!--Invalid settings will default to OFF-->
      <E1>U1</E1>
      <E2>I2</E2>
      <E3>OFF</E3>
    </Sync_Source>
    <Options>
      <!--Options will be ignored on models not applicable to-->
      <!--Linear Averaging-->
      <!--Linear Averaging valid values for WT130/230 are 0,8,16,32,64-->
      <!--Linear Averaging valid values for WT500 are 0,8,16,32,64,128,256-->
      <!--Enter 0 for no averaging invalid values will defalt to no averaging-->
      <Averaging>8</Averaging>
      <!--Line filter and Frequency Fiter-->
      <!--Valid settings OFF or ON See manual for usage details-->
      <!--WT130 only has Frequency Fiter-->
      <Line_Filter>ON</Line_Filter>
      <Freq_Filter>ON</Freq_Filter>
      <!--Update Rate-->
      <!--Not applicable to WT130-->
      <!--Valid settings for WT230 100mS,250mS,500mS,1S,2S,5S -->
      <!--Valid settings for WT500 100mS,200mS,500mS,1S,2S,5S -->
      <!--Invalid settings will default to 500mS -->
      <Update_Rate>500mS</Update_Rate>
    </Options>
    <Efficiecny>
      <!--Efficiency measurment Enter Yes to include efficiecny measurments-->
      <Measure>Yes</Measure>
      <!--Enter Yes to ignore the DC (battery) channel when calculating efficiency.-->
      <Ignore_DC>Yes</Ignore_DC>
      <!--Element designators for efficiency calculations (Wattmeter chanels are referd to as "Elements")-->
      <!--Valid designators are E1,E2,E3,None-->
      <Input_Element>E1</Input_Element>
      <Output_Element>E2</Output_Element>
      <Battery_Element>E3</Battery_Element>
    </Efficiecny>
  </Yokogawa>
  <Data_Logger>
    <!--This Section will define only the Actuator card channles used to control DC power switching relays-->
    <!--Measurment channels and scan setting are defined in seperate data logger config file-->
    <Type>
      <!--Type=34970A or none-->34970A</Type>
    <VISA>
      <!--VISA Resource or VISA Alias-->GPIB0::7::INSTR</VISA>
    <!--DCSW = DC Switch Type "Actuator" for new switch shelf or "DIO" for old switch box Default = Actuator-->
    <DCSW>Actuator</DCSW>
    <!--Slot Enter the slot number actuator (34904A) or DIO (34907A) card is in. Valid entries are 1,2,3 Default = 3-->
    <Slot>3</Slot>
    <!--Actuator "channles" used for DC switch shelf. Ignored for DIO type DCSW-->
    <Battery>1</Battery>
    <DC_Source>2</DC_Source>
    <DC_Load>3</DC_Load>
    <Capacitor>4</Capacitor>
    <Diode_Bypass>5</Diode_Bypass>
    <!--DC Sense uses two channels per device seperate with a comma (310,311)-->
    <DCPS_Sense>6,7</DCPS_Sense>
    <DCLD_Sense>8,9</DCLD_Sense>
  </Data_Logger>
  <Therm_Chamber>
    <Type>
      <!--Enter Thermal Chamber if comunications are possible to querry ambient temperature-->
      <!--Enter 'none' to manually input ambient temperature-->
      <!--Valid Thermal Chamber types are "7800" "8800" "TestEq" "none"-->none</Type>
    <VISA>
      <!--VISA Resource VISA Alias or IP address-->192.168.1.150</VISA>
  </Therm_Chamber>
</Test_Rack_Configuration>

 

 

 

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 12 of 29
(828 Views)

I'm putting aside the JSON and XML suggestions aside for the moment since I've never worked with them and other programs are already  running and I don't want to change every previous configuration file (using flattened text files and saved as .ini files) already written. 

 

Yeah, my GUI is exactly as you describe it, it being a cluster where the elements are arranged in a 'geographical' order independent of actual order. 

 

I think my problem with step 1 to 3 is that I cannot type def a cluster which I want to change the size (number of elements it has) of. Because after some searching changing the size of cluster programmatically is almost impossible.

 

One idea is to have it an array and add elements to it that could be bundled into a cluster later on but I need something more complex than that because it's not a single element that I need adding.

 

For example, the start GUI has a field for e.g. pressure parameters : A boolean (to indicate if the parameter will be used), a numeric value field, yet another boolean (to toggle active tolerances) and two more numeric fields for the upper/lower tolerances in percentage (if that boolean is unchecked, the value is absolute then)

 

Now let's say the user want to adds a second pressure parameter (or more), in my head it goes like this: the user clicks an "add" button, another cluster appears on the GUI (containing the two booleans and 3 numeric fields). And this cluster is then added to the existing start cluster.

 

I don't know if I can work with arrays because they always only hold the same type (boolean, string, etc)

 

Or maybe someone can suggest a better way to go about this?

0 Kudos
Message 13 of 29
(782 Views)

@nikvl wrote:

 

 

I don't know if I can work with arrays because they always only hold the same type (boolean, string, etc)

 

Or maybe someone can suggest a better way to go about this?


No.  An array can hold clusters.  Then the cluster can have the various types within it.  So have an array of clusters where a cluster can hold a boolean, string, numeric, ...  So it is an array of the same type of cluster, but the cluster is a combination of elements that will logically group together for your application.

0 Kudos
Message 14 of 29
(778 Views)

1. Be sure to make a typedef of your cluster!

2. Goto 1

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 15 of 29
(772 Views)

but my cluster is constantly changing its size when running....

0 Kudos
Message 16 of 29
(767 Views)

It is impossible for a cluster to change its size while running.

 

Unless you have an array in that cluster that is sometimes short and sometimes long.  Or a string that is sometimes short and sometimes long.

 

But whatever defines the structure of the cluster is constant for the life of your VI.

 

 

Message 17 of 29
(764 Views)

So, if say I create a programmatically changing array of cluster, this can hypothetically be wired into 'Write Anything' and saved as a config file, and later read using 'Read Anything', right?

 

Attached is a sample of vi i made.

 

The only thing I can type-def then is the ClusterAdd and/or Start Cluster?

Also, how i differentiate all the clusters in the final array, since I cannot change the label? However, renaming individual elements seems complicated

0 Kudos
Message 18 of 29
(720 Views)

I haven't played around with those openG variant functions and am not familiar with their workings.

 

It isn't clear to me what your "end game" goal is here.  MGI Read/Write Anything will pretty easily handle an array of typedef'ed clusters.  The code you posted mushes 2 individual clusters into a single cluster containing all elements from both, but as you pointed out, it then becomes difficult to differentiate the original individual clusters.

 

I don't understand why you want to work so hard to avoid working with an array of typedef'ed clusters.  It's natural for an array to contain a variable number of elements.  Clusters *cannot* change their # of elements at run-time.  The openG functions seem to do some clever stuff, but in the end, you had to call "Variant to Data" with a *pre-defined* cluster as the type before you could operate on it as a mushed-together cluster.

 

   This approach doesn't extend to a situation where you'll need to mush together an unknown # of clusters.  Arrays of clusters *would*.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 19 of 29
(685 Views)

I'm not trying to avoid them, it's just that I'm still not quite sure what you mean. I know it's a lot to ask, but maybe you could modify the VI / write notes on it of what I should be type-def-ing?

 

In this case I should type-def the Start Cluster and ClusterAdd?  The initial shift register is already an array of cluster. 

Or do I make them both an array of cluster (thus the increasing the dimension of the array which I don't know if it will help me)? And in an Array of Cluster I cannot change the caption of each cluster to differentiate them either because all will change accordingly. So by having them as all elements in a single cluster, I thought I could have a chance to define the captions individually but of course that can't work either since the property node for a caption has to refer to an element in the cluster that may or may not exist.

 

I don't know if any of that makes sense...

 

So to iterate, first I have a tab control. The first three tabs each contain a cluster of different elements (can be type-defed if you will) and are fixed and will not change. The fourth tab however is where this spiel comes in because I don't know how many parameters is going to be added by the user. To illustrate:

Tab A - Parameters of Motor : 1) Voltage limit 2)Current limit (optional Tolerance) 

Tab B - Controller Parameters: PID values

Tab C - Duration for each Test step (eg "Pressure" and "Flow" step)

Tab D - Test Parameters:

1) Pressure limit with optional tolerance input

2) Flow limit with optional tolerance input

3) a Boolean button if user wants to add more pressure or flow parameters or maybe two Booleans to differentiate between adding a pressure or flow parameter

 

All tests must have at least one pressure limit and flow limit parameter which are independent 'test steps'. A possible scenario is that a user wants to run the test at different pressures limits and/or flows.

 

Originally I didn't have this problem because I could define all the clusters (Tab D having only a fixed number of 1) and 2)) and write/read them into an ini file. But if I were to manage the above step, the program has to be able to write and read ini files of different sizes. 

0 Kudos
Message 20 of 29
(663 Views)