Maker Pro
Maker Pro

digital high pass filter

F

Frank Buss

I have found a very nice low pass filter on the web:

f(x+1)=(f(x)-input)*a+input

where 0 <= a < 1. The higher a is, the lower is the cut-off frequency.

Is there something simple like this for a high pass filter, too?
 
T

Tom Bruhns

I have found a very nice low pass filter on the web:

f(x+1)=(f(x)-input)*a+input

where 0 <= a < 1. The higher a is, the lower is the cut-off frequency.

Is there something simple like this for a high pass filter, too?

Sure...
x(k+1) = (1-c)*x(k) + c*u(k)
y(k) = u(k) - x(k)
c sets the cutoff frequency. There's a zero at z=1 and a pole at z=1-
c.
u(k) is the input; y(k) the output. x is a variable internal to the
filter.
Note that x(k) by itself as an output is just a low-pass function.
This is a first-order filter.
 
F

Frank Buss

Tom said:
Sure...
x(k+1) = (1-c)*x(k) + c*u(k)
y(k) = u(k) - x(k)
c sets the cutoff frequency. There's a zero at z=1 and a pole at z=1-
c.
u(k) is the input; y(k) the output. x is a variable internal to the
filter.
Note that x(k) by itself as an output is just a low-pass function.
This is a first-order filter.

Thanks, that's obvious after reading it :) The high pass filter is just
the input minus the output of the low pass filter.

What I really need is a bandpass filter. I've combined the two filters like
this:

hc = 0.02;
lc = 0.4;
lk = 0;
hk = 0;
loop {
in = nextSensorValue();
lk = lk + lc * (in - lk);
hk = hk + hc * (lk - hk);
out = lk - hk;
writeOut(out);
}

This is already very simple and looks like it does what I want, but I
wonder if I can reduce the number of multiplications and additions even
further, because I want to implement it on a microcontroller, with the
additional complication that it doesn't support floating points. But I
think I can convert it to fixed point math.
 
T

Tom Bruhns

Thanks, that's obvious after reading it :) The high pass filter is just
the input minus the output of the low pass filter.

What I really need is a bandpass filter. I've combined the two filters like
this:

hc = 0.02;
lc = 0.4;
lk = 0;
hk = 0;
loop {
in = nextSensorValue();
lk = lk + lc * (in - lk);
hk = hk + hc * (lk - hk);
out = lk - hk;
writeOut(out);

}

This is already very simple and looks like it does what I want, but I
wonder if I can reduce the number of multiplications and additions even
further, because I want to implement it on a microcontroller, with the
additional complication that it doesn't support floating points. But I
think I can convert it to fixed point math.

I haven't checked the accuracy of your translation of the original
formulas, but assuming they are accurate, if you can arrange to use
constants that are of the form 2^k, where k is a negative integer,
then you can accomplish the multiplication using just shifts. It's
common that the high pass filter is just to block very low
frequencies, and the cutoff frequency is not terribly important.
Sometimes you can use c=1/256, and just shift by a whole byte, which
may be almost trivial to do. You may be surprised to find that
filters implemented with too narrow a data path have strange
behaviour; you likely will need to keep lk and hk around as a byte
wider than your input data (two bytes wide if your input is 8 bits).

Cheers,
Tom
 
H

HapticZ

Top