The ExponentialFilter class implements a simple linear recursive exponential filter for the Arduino. It provides a simple way to smooth noisy measurements from analog sensors without using as much memory as a moving average filter.

How the Filter Works

Every time you provide a new value (xn), the exponential filter updates a smoothed value (yn):

yn = w × xn + (1 – w) × yn – 1

Here:

  • yn is the output of the filter at a moment in time n
  • xn is the new input value at a moment in time n
  • yn – 1 is the previous output value of the filter
  • w is the weighting factor in the range [0, 100].

The filter essentially slows down the response to rapid changes (such as noise) in the input signal.

This plot shows how the response to a step change in the input signal is affected by the filter weight, w.

High values of w (90, for example) favor new data over old data. The output responds quickly to changes in the input but is not smoothed much.

Low values of w (10, for example) favor old data over new data. The filter output is heavily smoothed and responds slowly to changes (noisy or not) in the input.

filter weight effect

The filter slows the response to step changes (such as noise) in the input signal. The thick, red line represents a step input signal. When w is small, the output signal takes many measurements to reach the input signal. When w is large, the response quickly reaches the input signal.

Choosing the Filter Weight

One straight forward method to choose an appropriate filter weight is to experiment.

Plot the raw sensor data and filtered sensor data using the time-plot visualizer. two values in MegunoLink. Select the best filter by observing how different filter weight values affect the signal.

The example below reads a sensor output from ADC channel 0 and sends the raw and filtered signals to a MegunoLink time plot.

ADC data smoothed with an exponential filter

The raw measurements from the ADC (green) are smoothed by an exponential filter (red)

Filtering Multiple Signals

The ExponentialFilter is self contained so you can just use several instances if you want to filter multiple signals. For example, this Arduino sketch sends filtered versions of the first three analog inputs to MegunoLink for plotting. Each filter has a different weight.

Filter Function Reference

The ExponentialFilter is a template class that takes a single parameter: the type of measurement to filter. The current filtered value is multiplied by 10 internally to improve precision of the filter. Normally use either long (to save code space if you haven’t already used float’s) or float (for more accurate results) as the filter parameter.

The constructor takes two arguments:

  1. The initial filter weight. This should be between 0 and 100
  2. The initial value. Typically 0.

Declare a new exponential filter using:

Filter(NewValue)

Applies the filter to a new value. See example below.

SetWeight(NewWeight)

Changes the weight applied when filtering. This value should be between 0 and 100.

High weights (90, for example) favor new data over old data. So, the output responds quickly to changes in the input and is not smoothed much.

Low values of (10, for example) favor old data over new data. So, the output is heavily smoothed and the filter responds slowly to changes (noisy or not) in the input.

GetWeight()

Returns the current value of the filter weight parameter.

Current()

Returns the current value of the filter output.

SetCurrent(NewValue)

Forces the current value to the new value supplied. Typically used to initialize the filter from a measurement.

Availability

The exponential filter is included in our MegunoLink Arduino Library and can be installed using the Arduino integration tool.

Showing 15 comments
  • Matěj Suchánek
    Reply

    Cool! Where can I get it?

  • Derek
    Reply

    How do I use this with two separate analog inputs without affecting each other?
    Sorry if this is a stupid question but I have little OOP knowledge.

    • Paul Martinsen
      Reply

      Hi Derek,

      You can just create separate filter variables. For example:

  • Ambrus Rácz
    Reply

    Hi!
    Can I somehow set with this filter the cutoff frequency? I would like to filter my input signal with a band-pass filter between 20-500 Hz. So e.g. I would use a lowpass filter at 500 Hz, and a highpass at 20 Hz.
    Could you help me with this?

  • Steve
    Reply

    Hi,
    Do you know whether it is possible to replace the initial value in the constructor with a variable. I am using the filter on an ultrasonic level sketch on an ESP8266 board and it works well. When the board restarts for any reason, I want to set the initial level value to the last value recorded when the board shut down. I am using the Blynk app to interface and am pretty sure the level value is being properly recorded and recalled from the Blynk server on restart. When I try to add the variable into the constructor rather than a value, the sketch compiles fine but the level starts at zero rather than the last recorded value.

    • Paul Martinsen
      Reply

      My guess is that you didnt initialize the variable before passing it to the construction. try using the SetCurrent(value) method on the filter variable. Pass the loaded last recoreded value to SetCurrent.

  • Steve
    Reply

    Hi Paul,
    Thanks for the feedback. I have been beavering away on this over the past couple of weeks without success unfortunately. I have confirmed that the variable is pulling through the last recorded value but when I use the variable in the constructor as the starting value, it still pulls through zero. It’s not clear to me how to use the SetCurrent method. Are there any examples you could point me to? I have tried adding lvlFilter.SetCurrent(levelStart) into setup, where lvlFilter is the name of the filter and levelStart the variable for the starting value. Not sure how this would work as the constructor has already been initialised at this point. Clearly something I am missing. Interestingly if I initialise the variable levelStart at the head of the sketch with a value (float levelStart = 25;) and then add levelStart in the constructor, the value is pulled through when the filter is initialised.

  • Paul Martinsen
    Reply

    Hi Steve,

    Where are you getting the value for levelStart from without the initialization? If you post your code to our forums we can take a look at it (https://megunolink.com/discussion/).

    Have a good week,
    Paul.

  • Steve
    Reply

    Thanks Paul for the prompt response. I’ll post on the forum.

    Regards
    Steve

pingbacks / trackbacks
  • […] because you don’t need to make many measurements at once. For this solution, they developed an Arduino filter library so you don’t need to go mad with […]

  • […] process of developing my final project for my MA thesis. While I was diving into something called linear recursive exponential filter for an Arduino + Processing program I am putting together, I randomly remembered the existence of […]

Leave a Comment

Start typing and press Enter to search

Plot Arduino data in real time.

Use our free Arduino library, open our Plotting visualiser and real-time data will come streaming in.
Learn More