Low pass filters are often used to reduce higher frequency components of a signal. Electronic LP filters are for example used after a sensor to remove high frequency noise from the signal before analog to digital conversion in a micro controller. Often we want to reduce the bandwidth of the signal even more using a digital LP filter within the micro controller program.
An equation for the calculation of a first order digital low pass filter can be written as
or
The new filter output is calculated from the old output
and the present input value
.
determines the filter time constant. The equation is simple and fast to compute if we have a floating point processor. But for reasonable processing rates and code size, 8 bit micro controllers use integer arithmetics.
Assume a 10 bit A/D converter. The value range of is then $latex0 – 1023$. For integer calculations many bits of the input signal will be lost as
is smaller than 1.
Scaling the equation
We can scale the value ranges by multiplying the equation by . So we get
Choosing the factor the multiplications can be substituted by an
-bit left shift, as implemented in C:
y = ( ((y+x)<
If the range of is
, the output range of
is
. For 10 bit input and
the output range is exactly the range of 16 bit unsigned integers. However, the intermediate
product range is about
times this. With 10 bit input and
the intermediate product range is
. For this range at least 3 byte integers must be used.
The graph shows the step response of this filter with and
. The steady state value is
. The response pass the time constant at 63%, 40,300. That is at about the 64th sample. If the sampling time is 10 msec, this corresponds to a time constant of 640 msec.
An alternative implementation
The scaled equation can also be written as
Here we loose some accuracy, but as we shift the accumulated value this will lose less precision than if we shift the input value. So in C we have
y= y + x - (y>>m)
This function is simpler, only one shift operation and the intermediate result has a smaller range. The steady state step response value is times the input value for this implementation too. So worst case for ten bits and 6 bit shift is
and
. In that case the sum of
and
exceeds the 2-byte integer range, but
just fits within. So a better implementation is
y= ((y - (y>>m) ) + x
Non-integer shift
This equation is simple to modify to achieve better resolution in time constant. We introduce an extra shift operation
y= ((y - (y>>m) - (y>>n) ) + x
Now the effective shift value is not an integer, . As an example, for
as before we get these approximate time constants and steady state output values by varying
:
![]() |
![]() |
S-s value |
16 | 12.8 | 12800 |
32 | 21.3 | 21300 |
64 | 32 | 32 |
128 | 42.7 | 42700 |
256 | 51.2 | 51200 |
The corresponding step responses are shown in this graph for the first 100 samples.
The blue dots are at the sample corresponding to and 63% of the steady state value. This is the approximate time constants, measured in samples.
We can add even more shift operations to fine tune the time constant, but there really isn’t much to be gained by fine adjustment of a first order filter.
Conclusion
By restricting the time constant to an exponent of two samples we can implement a low pass filter with only addition, subtraction and shift operations. Thus, fast filter operations can be implemented for small micro controllers lacking in resources. Like the Atmel tiny series which doesn’t even have hardware integer multiplication.
0 Responses to “Very simple integer digital low pass filter”