The other day while playing around with the ADC on the widget I had some problems with noise causing the reading to bounce around, It needed some form filtering to remove the noise. Normally almost everyone seems to take a number of readings and then average the result, unfortunately this takes time.
I came across this simple low pass filter on EDN. A Low pass filter works by blocking the higher frequency (in this case noise) and allowing the low frequency signal (in this case the underlying signal) to pass. hence the name. Perfect in cases where measuring slow moving signals, like temperature etc. The algorithm is fast, simple to implement and works a treats. It can be made to filter faster for a more response to change or slower to give more filtering.
<pre>#define FILTER_SHIFT 3</pre> <pre>int32_t filter_reg;</pre> <pre>int16_t filter_input;</pre> <pre>int16_t filter_output;</pre> <pre> </pre> <pre>filter_input = analogRead(0); // read ADC</pre> <pre> </pre> <pre>// low pass filter to get rid of noise</pre> <pre>filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input; </pre> <pre>filter_output = filter_reg >> FILTER_SHIFT; </pre>
The algorithm is a classified as a leaky integrator, where the latest reading have more weight than the older reading. So you take a single reading each cycle of the sensor loop and feed that into the filter, the output is used you would normally use the raw value.
The response of the filer can be adjusted by the FILTER_SHIFT, to make it more responsive, then lower this value, to give better filtering and hence a slower response then increase this value. For my application I found that a value of 3 to 4 worked well, but will depend on the underlying application.
I suggest you read the full article for an in depth description.