# Extremely low frequency filters

I have a data acquisition board(A/D+Digital Signal Processor) and I want to check if a digital high-pass filter(implemented in DSP) at an extremely low cut-off frequency(0.05Hz) is actually working.

If this was a frequency I could generate with a signal generator it'd be easy to check, but 0.05Hz is too low and I can't generate it. How do engineers check this kind of filters?

• this sounds to me like a DC blocking filter. is that what it's meant to be? – robert bristow-johnson Jan 30 '19 at 22:30
• depending on what the sample rate is, it's likely you're gonna have the so-called "cosine problem" with a HPF and a ridiculously low corner frequency. – robert bristow-johnson Jan 30 '19 at 22:32
• @robertbristow-johnson What is "cosine problem"? – doubleE Jan 30 '19 at 22:33
• I discuss it a little in this answer. essentially the problem is with $\cos(\omega)$ when $\omega \ll 1$ and $\cos(\omega)$ gets so close to $1$ that, with finite precision, you cannot tell the difference. – robert bristow-johnson Jan 30 '19 at 22:45
• why not measure the step response? – user28715 Jan 30 '19 at 22:55

if this is a first-order HPF DC blocking filter, this is the recommendation i have for it in fixed-point, and i think it would be a good idea in floating point, too.

while (n<something)
{
y[n]   =  x[n]  -  w[n]*( 2^(1-N) );
w[n+1] =  w[n]  +  y[n]*( (2^(N-1))*(1-p) );
n = n+1;
}


where p is the pole (in the z-plane and inside the unit circle) and $$0<1-$$p$$\ll 1$$. N is a big integer. with fixed-point you would perform the w[n]*(2^(1-N)) multiplication with arithmetic shift right (ASR) or the (w[n]>>(N-1)) operation. in float you can just multiply it and that simply changes the exponent in the floating point value. the constant coefficient (2^(N-1))*(1-p) should be precomputed and N chosen so that this is between $$\frac12$$ and $$1$$.

the -3 dB corner frequency $$\omega_0 = 2\pi\frac{f_0}{f_\mathrm{s}}$$ (as normalized angular frequency) is a function of the pole p and is:

\begin{align} \cos(\omega_0) &= 1 - \tfrac{(1-p)^2}{2p} \\ &= 2 - \tfrac12 \left(p + \tfrac1p \right) \\ &= 2 - \cosh(\ln p) \end{align}

the pole p is

\begin{align} p \ &= \ e^{\operatorname{arccosh}(2-\cos(\omega_0))} \\ \\ &= \ 2 - \cos(\omega_0) - \sqrt{\big(2 - \cos(\omega_0)\big)^2 - 1} \\ \\ &= \ 1 - 2\sin\left(\tfrac{\omega_0}{2}\right) \left(\sqrt{1 + \sin^2\left(\tfrac{\omega_0}{2}\right)} - \sin\left(\tfrac{\omega_0}{2}\right) \right) \\ \end{align}

so $$0 \ < \ 1-p \ = \ 2\sin\left(\tfrac{\omega_0}{2}\right) \left(\sqrt{1 + \sin^2\left(\tfrac{\omega_0}{2}\right)} - \sin\left(\tfrac{\omega_0}{2}\right)\right) \ \ll \ 1$$

and the shift or exponent change N is an integer and should be about

$$N \approx 1-\log_2(1-p) \approx 1 - \log_2(\omega_0)$$

someone can check my math.

this is an improvement by Tim Wescott to my DSP guru trick. it deals with both the cosine problem and the limitations of fixed point arithmetic.

latest thinking: i am not sure, but this might work fine for floating-point operation x, y, and w are all single-precision floats (double-precision floats should be no prob). (1-p) is a coefficient calculated in advance and is very close to zero.

while (n<something)
{
y[n]   =  x[n]  -  w[n]*(1-p);
w[n+1] =  w[n]  +  y[n];
n = n+1;
}