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: 

Using Only X Amount of Latest Input in Array

Solved!
Go to solution

Hello,

 

I'm working on a VI that needs to analyze and display samples of an input in real time . For simulation I'm using a generated sine wave though. It also needs to save these values in an array for the entirety of its runtime. Problem is, the program begins to lag over time so I'm assuming it's using the entire array for analysis on every iteration. Is there a way I could take X amount of the latest samples to analyze and display at a time? I've read about queues and running averages, but I'm wondering what would be best and how to implement it.

 

main_queue_testd.png

0 Kudos
Message 1 of 12
(3,565 Views)

Your continually slowing down is actually caused by your growing array.  If you only want to analyze the last x samples, then make yourself a circular buffer.  You will need to preallocate your aray.  But from there you just keep the array in a shift register, rotate the array, and replace the first element.  This will keep you from growing the array and hopefully faster processing.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 2 of 12
(3,540 Views)

@JLHart wrote:
simulation I'm using a generated sine wave though. It also needs to save these values in an array for the entirety of its runtime. 

 


This is your problem.  You should ask yourself "Why?"  If you're only processing the most recent X data points, it doesn't make sense to create an infinitely growing array.  You can use logging to maintain all of your data without creating the data structure that's causing your issues.  So, why do you need the data to be maintained in an array during runtime versus logging it for later use?

0 Kudos
Message 3 of 12
(3,526 Views)

I'd like to export the values that are building up the arrays at the end of the program. And I'm not aware of a better way other than using arrays with feedback to store everything as I'm recieving them. Data logging looks really useful, but I'll also be merging the arrays of phase and frequency values when I'm finished.

0 Kudos
Message 4 of 12
(3,515 Views)

Here's my attempt at using the circular buffer. Following this article, I figure I'd want the "Read (most recent)." Although on the initializer outside the loop, I get a cluster with with Samples per Channel and Channels. If for example I'm taking 50 values at a time, how do I configure the circular buffer? I tried putting in 50 for Samples per Channel and 1 for the number of Channels but I still get an error saying "Attempted to read more samples than configured in buffer."

main_queue_testd.png

0 Kudos
Message 5 of 12
(3,505 Views)

So log them together?  There's plenty of examples in the example finder to show you how to log data.  Just save both values together as you go.  I'd suggest doing so after every 20 data points and again at the end of your program.

Message 6 of 12
(3,502 Views)

Logging looks nice, but is there a way to control what kind of file I'm writing to? For this I'm exporting to a .csv for Excel. Also, how would I control how often it writes the data? And the only logging example that looked helpful was the Database Logging.vi (attached).

 

I'd still like to try and learn how the circular buffer works as well, so if anyone could tell me what's wrong with the vi I posted above, it would be appreciated.

0 Kudos
Message 7 of 12
(3,489 Views)

A circular buffer is an array that YOU create (ahead of time), and an associated index that YOU manage.

 

Let's say you want the 50 most recent samples.

 

1... Initialize an array of 50 zero values and wire that to a shift register in your loop. (we'll call it "Buffer")

2... wire a constant 0 to another shift register in your loop.  (We'll call it "Index").

In your loop:

3... Get a sample somehow.

4... Store the sample in Buffer[Index] (Replacing whatever is there).

5... Add 1 to the INDEX.  If INDEX = MAX (50), then set INDEX to 0 and store back in the shift register.

 

So, at any time after 50 samples, the BUFFER always contains the most recent 50 samples, and the INDEX always points to the OLDEST of those 50.  You can just average the whole buffer without regard to order, or use the index to put them in order if you must.

 

If you need to manage the first fifty specially, then keep another shift register which starts at 0 and counts up to MAX and stays there. That can be your "how-many-are-in-the-buffer" number, for averaging or whatever.

 

The point is to allocate the array ONCE and never again.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 8 of 12
(3,483 Views)
Solution
Accepted by topic author JLHart

You should look at using the Data Queue PtByPt VI.  It does the circular buffer for you.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 9 of 12
(3,450 Views)

An easier way to implement a circular buffer of size X is to use Quotient and Remainder.

 

Let's look at X =5 as an example.  Wire the iteration terminal into the 'x' input and a constant of 5 into the 'y' input.  After the first iteration, the remainder is 0.  After the second, it's 1, then 2, then 3, then 4, then 0. 

 

As you can see, this will repeat.  You'll forever index in a circular pattern between 0 and 4.

 

While the other way works given this scenario, it's generally bloat.  You have additional logic required to verify the index is greater than 4 so you need to set it back to 0.  In this case, you'll want to check for 4 to know that's when you log your array.  Anytime the remainder is 4, log the data.  Any other case, just wire the array through.  This is a simple two-case Case Structure.  4 and 0 (Default)

 

Instead of asking if you can choose the file type, why don't you tell us what file type you would like to use.  That makes it easier to tell you how possible your desires are.

Message 10 of 12
(3,433 Views)