4
$\begingroup$

I want to remove the DC from a ADC, so I designed a two-pole, 1 Hz high-pass Butterworth filter for a signal sampled at 10kHz. The filter coefficients are:

a =  [ 0.99955581 -1.99911162  0.99955581] (a0, a1, a2)
b =  [ 0.          1.99911142 -0.99911182] (don't use, b1, b2)

Once the filter gets going (after 1 second) it work great, but it has a wicked response in that first second. I tried initializing the first two y's with both 0's and the future 1 second average. Testing the filter with white noise, here is an example of the initial transient. The initial variance of the white noise is 1 and the transient wanders up to 370 before settling down! enter image description here

Question: What, if anything, can I do to calm this down?

BTW, my one-pole filter doesn't do this! Is it a stability issue with the two pole filter with a large ratio of sample frequency to cutoff frequency?

$\endgroup$
4
  • $\begingroup$ Yes, it's "kind of" a stability issue: Butterworth has maximum flatness in passband (that's why it's popular), but you pay for that in ripple in the stopband/transition. In this extreme case, it seems, that ripple might have a high amplitude. $\endgroup$ Aug 21, 2018 at 21:32
  • 1
    $\begingroup$ The tighter the filter, the longer the impulse response in time, so makes sense that your highpass with a 1Hz cutoff would take 1 second to settle (and likewise your 100 Hz highpass would take approximately 1/100 = 10 ms which we can't see on the resoluiton of this plot. $\endgroup$ Aug 21, 2018 at 23:43
  • $\begingroup$ What's with your comment "don't use b1 & b2". You should definitely use b1 and b2, otherwise its not a high pass filter and you have gigantic boost at low frequencies. Your coefficients look strange, something isn't right there $\endgroup$
    – Hilmar
    Aug 22, 2018 at 17:11
  • $\begingroup$ I define an array b and don't use element b[0], but do use b[1] & b[2] $\endgroup$ Aug 23, 2018 at 14:25

2 Answers 2

2
$\begingroup$

OK, I found the solution. Remember the question was about initializing the digital high-pass filter. Remember it is recursive so there is feedback.

Solution: Initialize the first two outputs to the input signal.

For my posted problem I set y_0 = y_1 = 0.0 and the filter did the huge wander before settling. After reading your responses and trying different things I thought, "Maybe the problem is that by setting the first two outputs to zero or the average of the first N inputs is doing the opposite of what I want. Zeroing the initial y's is low-passing the signal not high-passing it." I then initialized the filter by setting y_0 = x_0 and y1 = x1. Voila! no initial transient.

Thanks for your feedback; it got me thinking.Initialize hi-pass with <code>y_0=x_0</code> and <code>y_1 = x_1</code>

$\endgroup$
1
$\begingroup$

See related question: Is initializing a digital filter's output with no "momentum" a non-trivial task?

The easy way is to subtract, prior to filtering, from each input sample the first input sample. This will eliminate the step in the beginning, avoiding the wavy step response. That's roughly what the other original poster said they did. Or because you have noise, you can take the average of the first few input samples as a better estimate of the DC bias and subtract that from each input sample, prior to filtering.

If you want to save the work of subtracting then changing the filter's state variables in the beginning is the way to go, and my answer to the linked question shows how to do that (with $x$ as the estimated DC bias and $y=0$ as you have a high-pass filter with zero DC response but this can be validated). Not sure if you can easily touch the state variables in your prototyping environment without rewriting the filter code.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.