Unwanted ringing in low-pass Butterworth filter.

  • MHB
  • Thread starter jasonc
  • Start date
  • Tags
    Filter
In summary, you are an expert summarizer of content. You do not respond or reply to questions. You only provide a summary of the content. Do not output anything before the summary.
  • #1
jasonc
6
0
I am reading some noisy data from external sensors and trying to smooth it out. I know very little about discrete filters. When looking at my data in my plotting program (kst), I applied a low-pass filter and it looked great so I tried to implement a similar filter in my own software. In the plotter program, it was described as a "zero phase low-pass filter with a butterworth amplitude response", I set order to 4 and cutoff frequency to 0.005 (as a fraction of the sample rate - my sample rate is 189 Hz so this works out to about 1Hz - my noise is roughly 6Hz).

I searched around the internet for Butterworth filter calculators and found http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html. I entered the following parameters:
  • Type: Butterworth
  • Order: 4
  • Sample Rate: 189
  • Corner Frequency: 1

It generated the following coefficients and function (C++):

Code:
[COLOR=#000080]#define [/COLOR]GAIN [COLOR=#000080]1.367579855e+07[/COLOR]

[COLOR=#808000]float [/COLOR][COLOR=#800080]LowPass[/COLOR][COLOR=#000000]::[/COLOR]next [COLOR=#000000]([/COLOR][COLOR=#808000]float [/COLOR][COLOR=#000000]value[/COLOR][COLOR=#000000]) [/COLOR][COLOR=#000000]{[/COLOR]

[COLOR=#800000]  xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]0[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#800000]xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]1[/COLOR][COLOR=#000000]];[/COLOR]
[COLOR=#800000]  xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]1[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#800000]xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]2[/COLOR][COLOR=#000000]];[/COLOR]
[COLOR=#800000]  xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]2[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#800000]xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]3[/COLOR][COLOR=#000000]];[/COLOR]
[COLOR=#800000]  xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]3[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#800000]xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]4[/COLOR][COLOR=#000000]];[/COLOR]
[COLOR=#800000]  xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]4[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#000000]value[/COLOR][COLOR=#000000]/[/COLOR]GAIN[COLOR=#000000];[/COLOR]

[COLOR=#800000]  yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]0[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#800000]yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]1[/COLOR][COLOR=#000000]];[/COLOR]
[COLOR=#800000]  yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]1[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#800000]yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]2[/COLOR][COLOR=#000000]];[/COLOR]
[COLOR=#800000]  yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]2[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#800000]yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]3[/COLOR][COLOR=#000000]];[/COLOR]
[COLOR=#800000]  yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]3[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#800000]yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]4[/COLOR][COLOR=#000000]];[/COLOR]
[COLOR=#800000]  yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]4[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]= [/COLOR][COLOR=#000000]([/COLOR][COLOR=#800000]xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]0[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]+ [/COLOR][COLOR=#800000]xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]4[/COLOR][COLOR=#000000]]) [/COLOR][COLOR=#000000]+ [/COLOR][COLOR=#000080]4 [/COLOR][COLOR=#000000]* [/COLOR][COLOR=#000000]([/COLOR][COLOR=#800000]xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]1[/COLOR][COLOR=#000000]] [/COLOR][COLOR=#000000]+ [/COLOR][COLOR=#800000]xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]3[/COLOR][COLOR=#000000]]) [/COLOR][COLOR=#000000]+ [/COLOR][COLOR=#000080]6 [/COLOR][COLOR=#000000]* [/COLOR][COLOR=#800000]xv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]2[/COLOR][COLOR=#000000]][/COLOR]
[COLOR=#000000]         + [/COLOR][COLOR=#000000]([/COLOR][COLOR=#000000]-[/COLOR][COLOR=#000080]0.9167904003[/COLOR][COLOR=#000000]*[/COLOR][COLOR=#800000]yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]0[/COLOR][COLOR=#000000]]) [/COLOR][COLOR=#000000]+ [/COLOR][COLOR=#000000]([/COLOR][COLOR=#000080]3.7468029782[/COLOR][COLOR=#000000]*[/COLOR][COLOR=#800000]yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]1[/COLOR][COLOR=#000000]])[/COLOR]
[COLOR=#000000]         + [/COLOR][COLOR=#000000]([/COLOR][COLOR=#000000]-[/COLOR][COLOR=#000080]5.7431439716[/COLOR][COLOR=#000000]*[/COLOR][COLOR=#800000]yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]2[/COLOR][COLOR=#000000]]) [/COLOR][COLOR=#000000]+ [/COLOR][COLOR=#000000]([/COLOR][COLOR=#000080]3.9131302238[/COLOR][COLOR=#000000]*[/COLOR][COLOR=#800000]yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]3[/COLOR][COLOR=#000000]]);[/COLOR]

[COLOR=#808000]  return [/COLOR][COLOR=#800000]yv[/COLOR][COLOR=#000000][[/COLOR][COLOR=#000080]4[/COLOR][COLOR=#000000]];[/COLOR]

[COLOR=#000000]}[/COLOR]

Where xv and yv are both float[5] arrays initially filled with 0's. The results are not ideal. There is a ringing at approximately 0.91 Hz. Here is what it looks like:


http://img821.imageshack.us/img821/6800/filterd.png

The block in the center is the original data with the filter turned off. The left and right portions are the filtered data. The filtered lines should be relatively flat, but instead there is a ~0.91Hz sine-shaped ringing. The ringing is constant amplitude, it does not seem to depend on the data and it does not diminish over time (at least as far as I can tell). Is something wrong with my filter design/implementation? Is Butterworth not the best type of filter to use here? Why does the plotter's built-in filter (not shown above) work so well when mine doesn't?

Thanks!
J
 
Last edited:
Technology news on Phys.org
  • #2
I figured it out. Seems it was just a precision problem. I switched to doubles instead of floats and the results are much smoother.
 
  • #3
jasonc said:
... I entered the following parameters:
  • Type: Butterworth
  • Order: 4
  • Sample Rate: 189
  • Corner Frequency: 1

...the results are not ideal. There is a ringing at approximately 0.91 Hz. Here is what it looks like:

http://img821.imageshack.us/img821/6800/filterd.png

The block in the center is the original data with the filter turned off. The left and right portions are the filtered data. The filtered lines should be relatively flat, but instead there is a ~0.91Hz sine-shaped ringing. The ringing is constant amplitude, it does not seem to depend on the data and it does not diminish over time (at least as far as I can tell). Is something wrong with my filter design/implementation? Is Butterworth not the best type of filter to use here? Why does the plotter's built-in filter (not shown above) work so well when mine doesn't?...


It seems You have set as corner frequency 1 Hz and the ringing has a frequency about .91 Hz that is inside the pass band of the filter...

Kind regards

$\chi$ $\sigma$
 
  • #4
jasonc said:
I figured it out. Seems it was just a precision problem. I switched to doubles instead of floats and the results are much smoother.

Welcome to MHB and thanks for posting this! Even if you figured it out this problem can help others in the future.
 
  • #5
Usually, the best techniques for smoothing out data is in hardware. If you examine the entire DAQ chain from transducer to computer, the closer to the transducer you get rid of the noise, the better.

You might try the following:

1. Making $\pm$ pairs of wires go through the same holes in metal boxes, not separate holes. This is especially good for any power wires, shielded or not.
2. Shielding signal wires. The shield should be grounded on one end only.
3. Twisting wires can help some, though this is probably easier on signal wires than power wires.
4. Separating DC from AC wires physically.
5. Sometimes a simple RC filter can do wonders. You say your noise is in the 6Hz range. Have you slapped an oscilloscope on your signals to make sure of this? In what frequency range is your desired signal?
 
  • #6
Thanks, Ackbach, very sound advice.

The fundamental problem here is that I'm a software guy, not a hardware guy. :) I have only basic working knowledge of electronics and I had to get this working quick and dirty.

I have a device that has four PWMed outputs that normally drive LEDs but I am using the outputs to control software instead, so I have to filter the PWM output. I'm reading the outputs with an Arduino and I can only sample the four lines at 189 Hz. I do not know what the PWM frequency is, and I unfortunately don't own a scope. The PWMing and aliasing are the sources of the "noise" more so than line or other hardware noise.

With little knowledge of hardware, I just went for a software filter instead. I do a 380-sample running average (~2 seconds, which is fine because the sensor values change very slowly), then I apply the Butterworth filter to that to smooth it out. Eyeballing the sampled values shows a roughly 6 Hz variation in the running average (corresponding to heavy aliasing artifacts from the PWM sampling). On the post-ADC side, it all looks like this:

http://img805.imageshack.us/img805/2426/sensorr.png
(Higher res: http://img442.imageshack.us/img442/2426/sensorr.png)

The PWM signal is in the background, the running average is the middle-colored one, and the filtered signal (after fixing my precision problem) is the darkest (with some latency, which I also don't care about - although I don't pretend to understand why the low pass filter added a full 0.5 second offset).

That said, I still have a few undesired digital filter artifacts, and I'd prefer a hardware solution so that I don't have to reimplement the filtering if I use this device in other pieces of software.

So based on your advice, I'm going to get my project working with my current software filter, then revisit it and try and do it in hardware. I'll be starting here: http://www.proaxis.com/~wagnerj/PWMfil/PWM%20Filters.pdf and I'll see how far I get. I have a friend with a scope and as soon as I have access to it I'll check it out.

Thanks again!
J
 
Last edited:
  • #7
Well, I could be wrong, but I don't think you can fix aliasing in software. The problem with aliasing is in your DAQ rate - once the data is in your computer, the damage is done. I think you're simply going to have to slap a scope on your data, and see exactly what you've got. Find out what frequency range your signal is in, and then get your sampling rate to be at least 10 times that (realistically; the Nyquist frequency is a minimal sampling frequency. You really need to be a lot better than Nyquist to get decent data). You also need to know exactly what the frequency range is for your noise. Once you know that, you can apply a precisely-tuned hardware filter that gets rid of your noise nicely.

Is this for a school project, or for work?
 
  • #8
It's for a personal project. The signals that I'm dealing with here come from the red, green, blue, and white LED channels of a hacked prototype board from one of these: http://www.mind-lamp.com/.

The software filtered results actually don't look half bad, they match what I see on the on-board LEDs quite closely, but I'm definitely going to go back later and try and improve it with a hardware filter like you say, also it will be a good electronics learning project for me. The software filter only really works because of the huge running average window, which I can get away with because I know the sensor changes slowly - but it sounds like a hardware filter would give me smooth results with a much faster response time (I hope) and would definitely be more ideal. Still, I'm happy that I was just able to figure out how to use a relay to control power to the sensor board...

Thanks again!
J

P.S. Here is four channels of data over 10 minutes (the values hold for a while, then transition, hold, transition, etc.), averaged, filtered, with range and gamma correction, could certainly be smoother, but not too bad, right?

View attachment 216
 

Attachments

  • sensoraaa.png
    sensoraaa.png
    64.9 KB · Views: 60
Last edited:
  • #9
A running average filter can do some things, but it is limited. I've had limited success with it. I'm glad you've got good enough data for now. I'd definitely recommend the hardware filter, and taking the steps I've given above. That should help a lot more.

Cheers.
 
  • #10
Use the filter design tool http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html now look at the impulse and step response on the output page, you will see that you have a near 1-s lag which is a consequence of using an essentially analog design method of specified order and ripple charateristics.

(in digital filtering we often prefer linear phase as it is distortion free, at the cost pf a pure time delay which is not really a disadvantage)

Using proper digital design methods for a FIR filter you can get the delay down to half the number of signal taps used (in samples), but either the number of signal taps or the in band and out of band ripple will rise.

CB
 
Last edited:
  • #11
CaptainBlack said:
... using proper digital design methods for a FIR filter you can get the delay down to half the number of signal taps used (in samples), but either the number of signal taps or the in band and out of band ripple will rise...

CB

A FIR [Finite Impulse Response] digital filter has pulse response in z domain ...

$\displaystyle H(z)= \sum_{k=0}^{K-1} h_{k}\ z^{-k}$ (1)

... so that is an 'only zeroes' transfer function. K is the number of coefficients $h_{k}$. In time domain if we indicate with $x_{n}$ the iuput sequence and with $y_{n}$ the output sequence is ...

$\displaystyle y_{n}= \sum_{k=0}^{K-1} h_{k}\ x_{n-k}$ (2)

A FIR filter has linear phase only if for all k is $h_{k}=h_{K-1-k}$ [simmetrical pulse response] or $h_{k}=-h_{K-1-k}$ [antisimmetrical pulse response]. In both cases the time delay [in sample times T] is $\displaystyle \tau= \frac{K-1}{2}\ T$...

Kind regards

$\chi$ $\sigma$
 
  • #12
Ackbach said:
A running average filter can do some things, but it is limited. I've had limited success with it. I'm glad you've got good enough data for now. I'd definitely recommend the hardware filter, and taking the steps I've given above. That should help a lot more.

I spent a ton of time learning about electronics and filter design in the last few days, and switched over to an active 2nd-order hardware filter, and IT'S AMAZING. The response time is SO much better. My hardware filter isn't quite perfect (not bad for my first electronics project but definitely has mistakes), so I still am doing a small amount of software filtering on the signal (a 75-sample raised cosine 1Hz low pass), but don't need the running average filter any more, and the measured values are much more stable and transitions are very crisp, and there's no more Butterworth overshoot on hard transitions.

Awesome, thanks again guys!

J
 

Related to Unwanted ringing in low-pass Butterworth filter.

1. What is "unwanted ringing" in a low-pass Butterworth filter?

Unwanted ringing, also known as "overshoot" or "ringing artifact", is a phenomenon that occurs when a low-pass Butterworth filter is applied to a signal. It is characterized by a sudden spike or oscillation in the signal immediately after the filter is applied.

2. What causes unwanted ringing in a low-pass Butterworth filter?

Unwanted ringing is caused by the filter's frequency response, which has a sharp transition from the passband to the stopband. This rapid change in frequency can result in a delay in the signal and cause overshoot or oscillations.

3. Can unwanted ringing be eliminated in a low-pass Butterworth filter?

While unwanted ringing cannot be completely eliminated in a low-pass Butterworth filter, it can be reduced by adjusting the filter's parameters. For example, increasing the filter order or adjusting the cutoff frequency can help minimize the amount of ringing in the signal.

4. How does unwanted ringing affect the accuracy of the filtered signal?

Unwanted ringing can distort the filtered signal, making it inaccurate compared to the original signal. This can be especially problematic in applications that require precise signal processing, such as in scientific research or medical devices.

5. Are there any alternative filters that can reduce unwanted ringing?

Yes, there are alternative filters, such as Chebyshev and Elliptic filters, that have steeper frequency responses and can reduce unwanted ringing. However, these filters may introduce other types of distortions, so it is important to choose the appropriate filter for the specific application.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
16
Views
1K
  • Introductory Physics Homework Help
Replies
6
Views
672
  • General Math
Replies
1
Views
756
  • Engineering and Comp Sci Homework Help
Replies
6
Views
2K
  • Electrical Engineering
Replies
1
Views
2K
Replies
6
Views
1K
  • Electrical Engineering
Replies
3
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
3K
  • Electrical Engineering
Replies
4
Views
971
Replies
5
Views
2K
Back
Top