Close
0%
0%

Integer low pass filter

A lowpass filter algorithm for small controllers without multiplier

Public Chat
Similar projects worth following
2.8k views
Math limited controllers need low pass filters too, sometimes

A micro controller can process a low pass filter function, however floating point and even integer multiplication can take too much time to be useful. The following approach uses shifts instead of multiplication. See the project log.

  • Filtering without multiplication

    oaox06/09/2018 at 23:10 0 comments

    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 then 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

    y(k)= y(k-1) (1-a) + ax(k)

    or, after a little rearrangement

    y(k)= y(k-1)  - a y(k-1)  + ax(k)

    where y(k) is the new filter output value calculated from the old output value y(k-1). k is the sample number and the new input value from the AD converter x(n) and a coefficient a. This filter has short memory, we only use the present and previous sample values.

    If a is set to 0, the new output will not change at all. If equal to 1 the new value will be equal to the new input value only. For a between 0 and 1 this equation will mix a part of the new value with a part of the old value and in this way act as a low pass filter. A larger value of a will weigh new input values more than the old output and the filter will thus react faster. The value of a determines the filter bandwidth or in other words the time constant. If the input x is constant the output will approach this value.

    The filter equation is simple and fast to calculate if we have a controller with a floating point processor. But if we use a simpler controller we are stuck with integer arithmetic or a very slow floating point library. I will use integers for the following description.

    Assume a 10 bit A/D converter. The value range of  x(k) is then 0 - 1023. The coefficient a is smaller than 1, say 0.1. The result of a x(k) will then be in the range 0-102. We see that most of the precision we had from the 10 bit converter is severely reduced. We can remedy this by scaling the equation.

    Scaling

    We want to maintain the resolution we had from the converter by multiplying the equation by a constant b=1/a. We then get

    b y(k)= b y(k-1) - y(k-1) + x(k)

    Instead of reducing the input values we now maintain a corresponding larger y(k) value. To get the correct output the filter output must then be divided by b. We can also write this as

    z(k)= z(k-1) -  z(k-1)/b + x(k)

    where the new variable z= b y. The above implies both multiplication and division, both costly operations even when using integer arithmetic, and some simple controllers don't even have a 8 by 8 multiplier.

    Instead of a standard multiplication I will therefore chose b=2m, that is 2, 4, 8 and so on. This will limit the possible bandwidths we can get but also reduces the multiplication and division to simple  left and right shift operations. Shift operations are fast on any processor.

    z(k)= z(k-1) - z(k-1)>>m + x(k) 

    or equivalently as a C program statement

    z= z - z>>m + x;

    and the filter post processing to scale from z to y

    y(k)= z(k) >> m

    Let's assume the 0-1023 input range from the AD converter as before and m=6. Then b=64 corresponding to a=0.0156. The filter output range is 1024*64=0-65535 which can be maintained in a 16 bit unsigned integer variable. However, watch the sequence of operations: first do the  z(n-1) - z(n-1)>>m and then add x(n), if done in the opposite way, the  z(n-1)  + x(n) can overflow the 16 bit variable.

    The graph shows the step response of this filter with m=6 and  x=1000. The steady state value of z is  1000*64=64,000. First order step responses 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..

    ... Read more »

View project log

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates