LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Sensors project; Cluster “shift register” data usage.

In one sentence: Is it okay to use a cluster as a shift register in an event structure or is that going to cause memory issues.

 

Longer explanation

Hi everyone.

     I’m currently working on a project that involves collecting data from 20+ sensors (if our supplier ever sends the other 19 to us). Right now I’m cleaning up my code and separating it out into SubVIs /methods but there’s a bit of code that’s been bothering me.

This is it…

garthenar_0-1625607025182.png

 

And here is a view the while loop it’s in…

garthenar_1-1625607025186.png

 

I’m using this “Cluster Shift Register” to store the last 5 elements coming from a sensor (two sensors in this case).

     In other languages (Java, C) I’m used to using an array for this sort of thing because I only need a set space in memory. I read on here that clusters in LabVIEW don’t require the same overhead as structs in C and elected to use the cluster because it was much easier to wire (And it was probably 2am).

     I know that LabVIEW functions differently from other languages and that data is often passed by value as opposed to being passed by reference. This makes me concerned that I’m creating a new cluster and using up more memory every time this section of code runs. Is this the case?

 

I would ask another engineer, but I am the engineer, and our “expert” on LabVIEW, and the intern who didn’t know LabVIEW existed until 5 weeks ago.


___________________________________________________________________________________________________________________________________________________
Upgraded from intern to undergrad automation engineer. Attempting to explain to my employer why I need official training…. since I’m the groups only automation engineer.

I tried. I really did.
0 Kudos
Message 1 of 9
(2,015 Views)

Yes, it is Ok and no, it won't cause memory issues.

The shift register is a single instance in memory; the same memory location is used in every iteration.

"If you weren't supposed to push it, it wouldn't be a button."
Message 2 of 9
(1,991 Views)

Hi Garthenar,

 


@garthenar wrote:

I’m using this “Cluster Shift Register” to store the last 5 elements coming from a sensor (two sensors in this case).

     In other languages (Java, C) I’m used to using an array for this sort of thing because I only need a set space in memory. I read on here that clusters in LabVIEW don’t require the same overhead as structs in C and elected to use the cluster because it was much easier to wire (And it was probably 2am).

     I know that LabVIEW functions differently from other languages and that data is often passed by value as opposed to being passed by reference. This makes me concerned that I’m creating a new cluster and using up more memory every time this section of code runs. Is this the case?


Why don't you use arrays for this very purpose in LabVIEW, too?

  1. Initialize an array of 5 elements.
  2. Rotate the array by one element and replace the oldest element with new data…

No need to unbundle a cluster, build a new cluster with 4 old and 1 new element, convert from cluster to array, and all the other stuff! Simply use an array all the time!

(Btw. when using clusters you should typedefine them and use (Un)BundleByName to improve readability of your code.)

 

Some more ideas/suggestions:

  • You also don't need two IndexArray nodes to index two elements from an array: you can increase the size of that node!
  • You also don't need to wire the "0"/"1" constants: IndexArray automatically indexes starting from element 0…
  • Don't use Bundle followed by ClusterToArray just to create an array! That's what BuildArray is used for!
  • Show the numeric display of those charts! No need for an additional indicator to show the very same value!
  • Use colorbox constants instead of U32 numeric constant to define colors…
  • For writing data to a file it is better to open the file ONCE before the loop, write data to the file inside the loop and close the file ONCE after the loop. By using WriteDelimitedFile you constantly open/write/close the file, which may increase the CPU usage…
  • Try to cleanup the code even more: use straight wires as much as possible, especially for those shift registers at your consumer loop! (It seldomly counts how small you compress your code inside that case structure using bended wires, but it always counts on CODE READABILITY.)
  • You could keep all sensor data in a 2D array and use an autoindexing FOR loop to update all sensor's data (each one kept in a row).
  • I suggest to use the InplaceElement structure to access the data in the array…
  • Depending on the application I would still use a cluster per sensor, but keep more stuff inside this cluster. Example: cluster of [SensorID, channel name, scaling parameters, calibration parameters, array of measurements data]…
Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
Message 3 of 9
(1,959 Views)

@GerdW wrote:

Hi Garthenar,

 


@garthenar wrote:

I’m using this “Cluster Shift Register” to store the last 5 elements coming from a sensor (two sensors in this case).

     In other languages (Java, C) I’m used to using an array for this sort of thing because I only need a set space in memory. I read on here that clusters in LabVIEW don’t require the same overhead as structs in C and elected to use the cluster because it was much easier to wire (And it was probably 2am).

     I know that LabVIEW functions differently from other languages and that data is often passed by value as opposed to being passed by reference. This makes me concerned that I’m creating a new cluster and using up more memory every time this section of code runs. Is this the case?


Why don't you use arrays for this very purpose in LabVIEW, too?

  1. Initialize an array of 5 elements.
  2. Rotate the array by one element and replace the oldest element with new data…

No need to unbundle a cluster, build a new cluster with 4 old and 1 new element, convert from cluster to array, and all the other stuff! Simply use an array all the time!

(Btw. when using clusters you should typedefine them and use (Un)BundleByName to improve readability of your code.)

 

Some more ideas/suggestions:

  • You also don't need two IndexArray nodes to index two elements from an array: you can increase the size of that node!
  • You also don't need to wire the "0"/"1" constants: IndexArray automatically indexes starting from element 0…
  • Don't use Bundle followed by ClusterToArray just to create an array! That's what BuildArray is used for!
  • Show the numeric display of those charts! No need for an additional indicator to show the very same value!
  • Use colorbox constants instead of U32 numeric constant to define colors…
  • For writing data to a file it is better to open the file ONCE before the loop, write data to the file inside the loop and close the file ONCE after the loop. By using WriteDelimitedFile you constantly open/write/close the file, which may increase the CPU usage…
  • Try to cleanup the code even more: use straight wires as much as possible, especially for those shift registers at your consumer loop! (It seldomly counts how small you compress your code inside that case structure using bended wires, but it always counts on CODE READABILITY.)
  • You could keep all sensor data in a 2D array and use an autoindexing FOR loop to update all sensor's data (each one kept in a row).
  • I suggest to use the InplaceElement structure to access the data in the array…
  • Depending on the application I would still use a cluster per sensor, but keep more stuff inside this cluster. Example: cluster of [SensorID, channel name, scaling parameters, calibration parameters, array of measurements data]…

Yep, there is a lot of work to do. Right now I've got the code as is running on one machine and I'm improving it / studying more LabVIEW on another. once I get this consumer loop cleaned up I think I'll finally be willing to show the.... screw it, I'm going to post my full code so that I can get the rest of my c*** code pointed out and just work on it all at once. Post will be up within the next few hours.


___________________________________________________________________________________________________________________________________________________
Upgraded from intern to undergrad automation engineer. Attempting to explain to my employer why I need official training…. since I’m the groups only automation engineer.

I tried. I really did.
0 Kudos
Message 4 of 9
(1,927 Views)

Hey GerdW

 


@GerdW wrote:

 


Why don't you use arrays for this very purpose in LabVIEW, too?

.......


Ok, I put up my full code but asked the mods to pull it down (The post was long, the code was bad, it was embarrassing) but here my modified consumer loop after working through your suggestions.

 

garthenar_0-1625754884771.png

 

I came up with two ways to write my file without using WriteDelimitedFile. One creates an array each time while the other uses an initialized array in a shift register.

 

Here is the subVI used with the array and shift register approach.

garthenar_1-1625755141232.png

My Main Question

From my understanding, every time the code with Build Array it's creating a new array in memory in a new spot in memory which isn't good practice. While initializing the array and using a shift register uses the same array and the same space in memory which is good practice. Is this right or am I just throwing my C/Java thinking onto LabVIEW again?

 

As always, please feel free to point out anything else you see. I'm all ears and there's a lot the tutorials didn't cover (or did but it didn't sink in).


___________________________________________________________________________________________________________________________________________________
Upgraded from intern to undergrad automation engineer. Attempting to explain to my employer why I need official training…. since I’m the groups only automation engineer.

I tried. I really did.
0 Kudos
Message 5 of 9
(1,891 Views)

Jumping in late and not reading the whole thread....

But this seems a whole lot simpler than your sub-vi

Frozen_0-1625780091930.png

 

---------------------------------------------
Former Certified LabVIEW Developer (CLD)
0 Kudos
Message 6 of 9
(1,877 Views)

@Frozen wrote:

Jumping in late and not reading the whole thread....

But this seems a whole lot simpler than your sub-vi

Frozen_0-1625780091930.png

 


I'm kicking myself because I didn't think about it that way. I think your right, I'll change up my subVI.

 

Edit: Here's what I came up with.

garthenar_0-1625770132756.png

 


___________________________________________________________________________________________________________________________________________________
Upgraded from intern to undergrad automation engineer. Attempting to explain to my employer why I need official training…. since I’m the groups only automation engineer.

I tried. I really did.
0 Kudos
Message 7 of 9
(1,873 Views)

Hi Garthenar,

 


@garthenar wrote:

Edit: Here's what I came up with.

garthenar_0-1625770132756.png


To create a delimited spreadsheet string there is a function called ArrayToSpreadsheetString!

  • no need for that FOR loop
  • no need to ConcatString with a comma
  • no need to ConcatString with a trailing LF/CR
  • no need to autoindex an array at the input of the FOR loop just to build an array from the elements by autoindexing at the output…

@garthenar wrote:
From my understanding, every time the code with Build Array it's creating a new array in memory in a new spot in memory which isn't good practice. While initializing the array and using a shift register uses the same array and the same space in memory which is good practice. Is this right or am I just throwing my C/Java thinking onto LabVIEW again?

When the array always consists of those 5 strings then I would use a simple BuildArray node.

Don't think so much about the internal of the LabVIEW memory manager - not in this stage of your development! LabVIEW is quite good at re-using already allocated memory. Also you are handling strings here: they require memory allocations because their length is not fixed: LabVIEW has to allocate some memory each time you create a string - but will probably get this memory from its internal pool of already allocated memory marked for re-use…

(I don't know so much about C/Java memory handling, but I guess they also need to allocate memory for data structures of variable length like strings…)

 

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
Message 8 of 9
(1,860 Views)

Thanks GerdW

 


@GerdW wrote:

Hi Garthenar,


To create a delimited spreadsheet string there is a function called ArrayToSpreadsheetString!

  • no need for that FOR loop

When the array always consists of those 5 strings then I would use a simple BuildArray node.

 


Got it. I'll go with option one from my earlier post post but replace 1D String Array to Delimited String with Array to Spreadsheet String. Still, all that was worth the experience.


  • no need for that FOR loop
  • no need to ConcatString with a comma
  • no need to ConcatString with a trailing LF/CR
  • no need to autoindex an array at the input of the FOR loop just to build an array from the elements by autoindexing at the output…

 

I'll experiment even more with the arrays auto indexing and writing to files. I thought commas were the standard delimiter though? Oh well.

 

Don't think so much about the internal of the LabVIEW memory manager - not in this stage of your development! LabVIEW is quite good at re-using already allocated memory. Also you are handling strings here: they require memory allocations because their length is not fixed: LabVIEW has to allocate some memory each time you create a string - but will probably get this memory from its internal pool of already allocated memory marked for re-use…


That makes me feel better (that it will probably get memory from its internal pool)

 


(I don't know so much about C/Java memory handling, but I guess they also need to allocate memory for data structures of variable length like strings…)


Java has a "Trash Collector" that cleans up anything you stop referencing. It's useful but provides it's own problems.

 

C allows me to choose pass by value or pass by reference and manage memory manually. On the micro-controllers I have/am working with the memory has to be managed manually. If I let the system go and it starts creating new arrays without telling it where to do so it'll run out of space and crash. Very ungracefully to boot.

 

Now that I think about it. My experience with the limited memory and processing power of micro-controllers is probably why I'm so concerned about these things. 


___________________________________________________________________________________________________________________________________________________
Upgraded from intern to undergrad automation engineer. Attempting to explain to my employer why I need official training…. since I’m the groups only automation engineer.

I tried. I really did.
0 Kudos
Message 9 of 9
(1,844 Views)