Example Code

Waveform Averaging to Remove Noise as an Alternative to Using a Filter.

Products and Environment

This section reflects the products and operating system used to create the example.

To download NI software, including the products shown below, visit ni.com/downloads.

    Hardware

  • Data Acquisition (DAQ)

    Software

  • LabVIEW

    Driver

  • NI DAQmx

Code and Documents

Attachment

Overview

This example is designed to show how it may be possible to remove higher-frequency noise from a waveform without explicit use of a filter.

 

Description

The code uses two different methods of averaging that allow waveforms to be cleaned and smoothed out. The first method demonstrates the the use of point-by-point averaging to slightly reduce the noise present in a waveform. It does this by taking a set number of points and averaging them together to create one new point in their place. It does this for each point on the waveform and results in a much smoother curve if enough points are used. Increasing the number of points produces a smoother curve, but as the number increases the phase will slowly begin to shift relative to the input waveform and the amplitude of the waveform will decrease. However, it can be very useful in situations where a perfectly clean signal is not required.

 

The second method produces a much nicer output, but is designed for repeating signals that remain in phase from one iteration to the next. This method adds the previous instances of the waveforms to the new one, creating a "total", and then divides by the number of waveforms added together to acheive an "average" waveform. This example does not limit the number of waveforms that are added together, but an acutal implementation may want to limit this number to prevent overflow errors.

 

Requirements

Software

  • LabVIEW 2010 or compatible


Hardware

  • None required

 

 

Steps to Implement or Execute Code

  1. Download and run the attached VI.
  2. Change the values of the different controls to get an understanding of how some of the averaging code behaves.

 

 

Additional Information or References

 

Screenshot of the front panel while the code is in action:

 

Front Panel.png

 

And a screenshot of the block diagram:

 

Block diagram.png

 

 

**This document has been updated to meet the current required format for the NI Code Exchange.**

Ryan P.
CLA

Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.

Comments
HrvojeM
Member
Member
on

Hi RyanPoPo,

your Waveform Averaging Example.vi is exactly what I have to do in current stage of my work. I'm trying to get magnetic hysteresis loop using LabVIEW 8.5. I've got a pretty good signals but they have some noise that has to be removed to get a hysteresis loop. The idea was to add the same signal for let's say 20 times and then to divide the summed signal by 20 to get the average signal and than to show them on x-y graph. I'm a begginer in LabVIEW so from your VI I saw for the first time the shift register, but obviously I'm using it in the wrong way because I don't get the averaged signal at all. Can you please help me with that? Here are pictures of my Block Diagram and Front Panel. I would also have send you my VI but seems there is no option to attach files here or at least I don't see it

Thank you for your time,

HrvojeMaverage- Front Panel.JPGaverage- Block Diagram.JPG

RyanPoPo
NI Employee (retired)
on

Hey HrvojeM,

The issue could be that you are using a dynamic data type (the blue wire that most Express VIs require). If you convert that to a waveform before doing the add and divide functions, then it may give you the result that you need. You can convert to a waveform using the "Convert from Dynamic Data" Express VI:

http://zone.ni.com/reference/en-XX/help/371361H-01/lvexpress/convert_from_dynamic_data/

Conversely, after you have completed the addition and division (to get the average), you can convert the waveform data back into a dynamic data signal using the "Convert to Dynamic Data" Express VI.

Both the Convert To and Convert From Dynamic Data VIs are in the Express > Signal Manipulation palette in LabVIEW.

Ryan P.
CLA
HrvojeM
Member
Member
on

Hi RyanPoPo,

thank you for your suggestion. I've tried it but still I get an empty grap (first two pictures). Also I tried to put both methods you mentioned in your document in the same for loop but still there's an empty graph. I tried to put graphs for average values outside the loop, same result. Do you have some ideas what I'm doing wrong?

Thank you for your time,

HrvojeM

average 2- Block Diagram.JPG

average 2- Front Panel.JPG

average- signal vs field- Block Diagram.JPG

average- signal vs field- Front Panel.JPG

HrvojeM
Member
Member
on

...and one more question I don't see how you can control the number of waveforms to add in the second method. I would like to average 10 waveforms, than 20, 30, and so on to see which number gives me the optimal result (after the averaging I have to integrate that data to get hysteresis loop).

Thank you for your time,

HrvojeM

RyanPoPo
NI Employee (retired)
on

Hey HrvojeM,

I'm not immediately sure why the graph is remaining blank for you. It might be beneficial to use some of the debugging tools to make sure the code is operating like you expect. For example, you can probe any wire to see its current value by right-clicking it and selecting "Probe" . You can use this to see if the add and divide funcitons are returning any data, or if the arrays are blank.

And to change the number of waveforms that you average, just change the number of times you run the For Loop. If you aacquire and add 5 waveforms using the Add function, and then divide by 5, it gives you the average of those 5 waveforms.

Regards,

Ryan

Ryan P.
CLA
HrvojeM
Member
Member
on

Hi Ryan,

I've tried you suggestion on probing and I see where is the problem but don't know why it is occuring. The problem is with the shift registers, there are no values coming from them (first picture). I tried to use only Dynamic Data type of wires but the result is the same (second picture). Maybe I should configure shift registers in some way?

Also, can you please explain me (third picture) what is the meaning of the 5 cells in the waveform section? Why are only 5 of them, can I change it? Is there a way to change the dt value (0.000017) from LabVIEW or it depends on my hardware (Tektronix AFG320)?

Thank you for your time,

Hrvoje

shift register 1.JPG

shift register 2.JPG

signal out.JPG

HrvojeM
Member
Member
on

...hmm, maybe the problem is in the different dt values? Look at (first picture above) [107] Probe's dt (1.000000) and [110] Probe's dt (0.000017).

Thank you for your time,

HrvojeM

RyanPoPo
NI Employee (retired)
on

The 5 cells are just a preview of the elements in the Y array (the Y array are the actual samples that were taken). You can increase the index input next to the array to look at higher sections of the array. And it is definitely possible that the dt is the problem, but the 107 probe doesn't actually have any data to display and is simply showing the default values instead, which is why you see a dt of 1.

Ideally, you want to acquire N sets of your waveform, and then perform the averaging at the end. The code provided in this example does the averaging gradually over several iterations, but this was only to allow people to see the behavior as the averaging happened (you could see the waveform smoothing out as more data sets were acquired and averaged). It might be easier if you do the following steps:

Inside of the For Loop:

1. Acquire your data

2. Do your Field/Signal processing

3. Convert Dynamic Data to a Waveform data type.

4. Use the Get Waveform Components VI to get the Y Array extracted from the waveform.

5. On the FIRST iteration of the For Loop, pass this extracted Y array to a shift register (don't use the Add VI). On every iteration after this, Add the new Y array to the previous Y array coming from the shift register. Pass the results of the add to the shift register. You can acheive this behavior by using a case structure that simply passes the Y array through to the shift register when the For Loop's interation counter equals 0, and performs the add function on every iteration after that. It would look something like this:

Example 1.png

Example 2.png

Outside of the For Loop:

1. After the For Loop has finished executing, you are left with the summed Y values from all of the acquisitions. Just divide the output of the shift register by the number of iterations your For Loop had, and this will give you the average waveform.

2. Since this was all done with arrays of doubles, I recommend rebuilding the Y array into a waveform so that the sampling information is also included. To do this, I would pass the last waveform wire that was present in the For Loop out of the For Loop, and then replace it's Y array with the average Y array you just created.

3. At this point you can leave it as a waveform data type, or convert it back to a dynamic data to plot the results on your graph.

Ryan P.
CLA
HrvojeM
Member
Member
on

Hi Ryan,

thank you very much for the idea and detailed explanation I made the code following your instructions, checked the wire's values to see whether adding and division are working, and they are but there is one problem. I've noticed that my original and averaged xy-graphs look very similar, so I checked the values with the probes and realised that I'm adding the same signal 10 times! I need to add 10 consecutive signals (they are periodic in time, period is approximately 33 ms for this frequency (30 Hz)) so I tried do adjust the DAQ Assistant's timing settings. I've adjusted Samples to Read and Rate (Hz) so that 1 measurement covers 10 periods but than I'm just adding the same 10 signals 10 times. Now on the x-y graphs I get 10 overlapping graphs and I get one additional problem that can be avoided if 1 measurement covers only 1 period, but that is not the main issue right now How can I tell the program to divide 1 measurement that lasts 330 ms into 10 parts of 33 ms each, and then to add that parts into 1 signal which I would divide by 10 to get the average signal? I've noticed that you used some timing VI in your original post (upper right corner of the Block Diagram) so I guess that's how the program knows the period of the signal. Also a Foor Loop covers all of your code.

USREDNJAVANJE.JPG

Thank you for your time,

Hrvoje

HrvojeM
Member
Member
on

Hi Ryan,

I solved the above problem!!! The trick was to remove the two smaller For Loops and replace them with one bigger For Loop that covers the DAQ Assistant. In that way, at every iteration code takes new signal and adds it to the previous signal. After the loop is over the summed signal is passed outside the loop and divided with number of iteration. The same is done for the field signal. Now, I have to integrate output data from AVERAGE XY graph to get hysteresis loop.

average 3 success.JPG

Thank you very much for your help, I learned a lot from you. I hope I'll do the integration part on my own, but if not, I'll be free to ask you for help.

Hrvoje.

Wagih
Member
Member
on

Hi HrvojeM,

Can you please send me you file I am working on the same problem, but I cannot figure out how to solve it.

Regards

HrvojeM
Member
Member
on

Hi Wagi,

please provide me your email adress because it seems I can't upload my VI here.

HrvojeM

Wagih
Member
Member
on

Thank you HrojeM,

Here is my email address

Thanks

ericthemantis
Active Participant
Active Participant
on

Hi Ryan,

I think this example has a mistake in it. The summed waveforms should be divided by i+1, not i.

-Eric H.

Eric H.
Senior Field Applications Engineer
NI
GUAU
Member
Member
on

 

Hi HrvojeM,

 

Can you please send me you file too, or may I send mine to you?! I am trying the procedure you went through but it doesnt work for me:(

 

Thank you in advance!

GUAU
Member
Member
on

I think I solved my problem to a stage, but after smoothing 2 signals I get from my DAQ system I want to substract them to get differential pressure. There is another noise siting on substract signal. I am trying to smooth that individually through same process but the graph remains blank.

I wonder if having two for loop is the problem?

anyone can help please

image.png

don_Micheal
Member
Member
on

Hi HrvojeM,

 

Could you please send me your file. I have the same problem and don't know how to solve it.

 

Regards

abuzahra
Member
Member
on

Hi Ryan,

 

would you mind to send the IV of these works. Now I am trying to reduce noise at low current measurement. May be this is going to help me. thank you.