LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Adding a table to the front panel which displays time averages of preceding data samples

I want a table which stores averages for 30sec,1min,3min, and 6min of data every 6 min. So once it computes the 6min average that resets the data clock so to speak and the next 30sec average starts a new line in the table. What does this look like? or can someone direct me to an example that does this? I haev attached a vi I posted in another thread which has my general data acquisition set up if that helps. I am still trying to figure out the arraying of the incoming data, but this might need to be stored in a separate array.

0 Kudos
Message 1 of 7
(3,115 Views)

labview12110,

 

From your data aquisition code that you provided, I see that you are doing an analog input data aquisition with a clock speed of 10Hz.  I also notice that you are reading only 1 sample at a time from your DAQ device's onboard FIFO.  Are you interesting in seeing any other data besides the averages?  If not, one way you could accomplish what you are trying to do is to start your data aquisition, then have your code wait 30 seconds for your data to aquire.  Since you are aquiring 10 samples / second, you could then set your DAQmx Read VI to read back 300 samples from the DAQs onboard FIFO by setting the "number of samples per channel" to 300.  Run those 300 samples through the Mean VI and you have the mean for that 30 seconds of data.  Put that mean into your table and save it for the next iteration of the loop with a shift register.  Repeat the above steps (wait 30 seconds to aquire, etc..) so that you have the next 30 seconds of data.  Take the mean of the first 30 seconds of data and the mean of the second 30 seconds of data and viola, you have the mean for 1 minute of data and you can insert that into your table.  You would probably need to add a case structure that looks at what iteration of the loop you are on so that you can avoid inputing data you don't want, like an average for 1:30 of data.  For example, your case structure could read something like: "If it is the second iteration of the loop, take the mean of the means for the first 30 seconds of data and the second 30 seconds of data and put it in my table.  If it is the third iteration of the loop, take the mean of the means for the first 1:00 of data and the new 30 seconds of data but do not put it in my table." 

 

For the above explanation, I assumed that you are looking for a running average taken at different "snapshots" in time, rather than averages taken at specific intervals of time.  If I misunderstood your application please let me know.

0 Kudos
Message 2 of 7
(3,041 Views)

 

From your data aquisition code that you provided, I see that you are doing an analog input data aquisition with a clock speed of 10Hz. 

 

Correct

 

I also notice that you are reading only 1 sample at a time from your DAQ device's onboard FIFO.

 

Correct, but I am not sure how this works exactly, since in the data file I have i get 10 samples per second recorded and all voltages sampled are different.

 

 

For the above explanation, I assumed that you are looking for a running average taken at different "snapshots" in time, rather than averages taken at specific intervals of time.  If I misunderstood your application please let me know.

 

Well not specific intervals in time, but triggered by an action of some sort. Like every time a button is pressed the vi looks into the stored array, and captures 3600 data points and finds the 6min average. Since I am reading at 10 samples/sec.

 


 

0 Kudos
Message 3 of 7
(3,032 Views)

labview12110,

 

When you run the DAQmx Start VI, your DAQ device begins taking samples at the rate you specify and storing these samples into an onboard FIFO buffer.  When you call the DAQmx Read VI, you are telling LabVIEW to move however many samples you specify into LabVIEW's Application Development Environment (ADE) memory.  Essentially, you are moving this data from the DAQ device into your computer's RAM.  Here is a paragraph I pulled from this link: http://www.ni.com/white-paper/2835/en/

 

Instances of the NI-DAQmx Read function that are capable of reading multiple samples include an input to specify the number of samples per channel to read when the function executes. For finite acquisitions, by specifying a number of samples per channel of -1, the function waits for all of the requested samples to be acquired and then reads these samples. Specifying a number of samples per channel of -1 for a continuous acquisition results in the function reading all of the samples that are currently available in the buffer when the function executes. In the following LabVIEW block diagram, the NI-DAQmx Read VI has been configured to read multiple samples from multiple analog input virtual channels and return the data as waveforms. Furthermore, since the number of samples per channelinput has been wired to a constant value of 10, each time the VI executes it will read 10 samples from each virtual channel.

 

Therefore, since you specify the DAQmx Read "number of samples per channel" to 1, you are moving 1 sample from the DAQ's FIFO into your LabVIEW ADE memory.  You could increase this number and read back more samples each time you run the loop, or just set it to -1 and read back all of the samples that are currently in the onboard FIFO and append them to the and of your array.

 

I would then suggest that you write some math that does some manipulation on your array of data.  Such as "When I press a button, pull the last 3600 values from my array and compute the mean".  You could do this by adding a case structure in your loop that checks a button to see if it has been pressed every iteration of the loop.  Some things you may want to consider is to keep your array at a maximum of 3600 samples.  Therefore, you could do some math to determine how large your new set of samples are, remove that many samples from the beggining of the array, then append those samples to the end of your array.  The only time you would need to do that is if you are planning on running your code for an indefinate amount of time, so that your computer's memory does not overflow.  Similarly, you could look back at the last 300, 600, 1800 samples and so forth.  Perhaps maybe some case structures that do something like "if there are 50 samples in my array and the button is pressed, only compute the 30 second average".

0 Kudos
Message 4 of 7
(3,000 Views)

So based on some examples I found online before your response I changed my vi to have two queues and it seems to have solved my buffering issues (another thread) and added the table I want with headers. Basically every time the button is pressed it adds a row of data to the table by grabbing however many poitns from the array I select for that graph. Since i am sampling at 10hz the last 300 data points is 30 sec of data. If I make more of those I can have some for 1min, 3min, etc.

 

This is probably a terrible way to do this, but it has solved my problems (running at ~2hrs now and no buffer errors and table works) what can I do to make it better?

 

(edit: i dont think i wired the stop button properly in this so i wouldnt recommedn running it)

0 Kudos
Message 5 of 7
(2,988 Views)

labview12110,

 

What you have implemented is a producer / consumer architecture and I highly recommend it.  This is a good practice in code architecture when doing calculations on DAQ data.  Can I ask you why you implemented the second queue?  We're you noticing a delay in your graphs updating when you pressed the "record data" button?  TDMS files are optimized for speed, and shouldn't case too much overhead.  Especially when your only writing to the file every now and then.  For instance you could create the file when your code starts (outside the second while loop) and keep it open while your program is running.  Then just write to it whenever you press the "record data" button.  Then, once you press the stop button and exit the second while loop, close the TDMS file.  Much like you already have in your third loop.

 

I would like to recommend that you release your second queue after the second loop rather than the third.  This will result in your stop button releasing the queue in loop 1 which will throw an error in loop 2, thus stopping the loop.  Then, releasing the queue after the second loop will throw an error in the 3rd loop and cause that one to stop.  A domino effect if you will.  Other than that, I don't see anything at first glance that you need to change in your current architecture if it is working for you.

0 Kudos
Message 6 of 7
(2,967 Views)

Yes I was experiencing a delay, but now it is not there or has lessened considerably. I got the idea for the double queue from this:

 

https://decibel.ni.com/content/docs/DOC-26558

 

I almost went triple Smiley Tongue

0 Kudos
Message 7 of 7
(2,955 Views)