user65: I am working on a mobile robot controlled via a wireless 2.4 GHz link.The receiver is connected to the Arduino Uno which serves onboard as the main controller. The most critical (and main) input channel coming from the receiver produces a very noisy signal, which leads to lots of minor changes in the output of the actuators, even though these are not needed.


                    Plot of the input of the Arduino in a 30 second interval.
I am looking for libraries that can perform efficient smoothing. Are there any signal smoothing libraries available for the Arduino (Uno)?

user113: You could filter this digitally using a low pass filter:
int valueFilt = (1-0.99)*value + 0.99*valueFilt;

Change the 0.99 to change the cut off frequency (closer to 1.0 is lower frequency). The actual expression for that value is exp(-2*pi*f/fs) where f is the cutoff frequency you want and fs is the frequency the data is sampled at.
Another type of "digital filter" is an event filter. It works well on data that has outliers; e.g. 9,9,8,10,9,25,9 . An event filter returns the most frequent value. Statistically this is the mode.
Statistical averages such as Mean, Mode etc.. can be calculated using the Arduino Average Library.
An example taken from the Arduino Library page referred to :
#include <Average.h>
#define CNT 600
int d[CNT];

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int i;

  for(i=0; i<CNT; i++)
  {
    d[i] = random(500);
  }  

  Serial.print("Mean: ");
  Serial.print(mean(d,CNT),DEC);
  Serial.print(" Mode: ");
  Serial.print(mode(d,CNT),DEC);
  Serial.print(" Max: ");
  Serial.print(maximum(d,CNT),DEC);
  Serial.print(" Min: ");
  Serial.print(minimum(d,CNT),DEC);
  Serial.print(" Standard deviation: ");
  Serial.print(stddev(d,CNT),4);
  Serial.println("");
  Serial.println("");

  delay(5000);
}


user8: Have you tried a low pass filter? I found an example here an another one here.
Both of these libraries have a list of data being read from the analog sensor of your choice which is averaged. Every new sensor value is added to the list, and the last one is thrown out, like this:
List: 3 4 3 3 4 3 5 3 2 3 4 3 
new reading added. old one thrown out
      /--                     /--
List: 5 3 4 3 3 4 3 5 3 2 3 4
list averaged


user186: I think I see a lot of single-sample noise spikes in your noisy signal.
The median filter does better at getting rid of single-sample noise spikes than any linear filter.
(It is better than any low pass filter, moving average, weighted moving average, etc. in terms of its response time and its ability to ignore such single-sample noise spike outliers).
There are, in fact, many signal-smoothing libraries for the Arduino, many of which include a median filter.
signal-smoothing libraries at arduino.cc:

Paul Badger: smooth digital low-pass filter
Paul Badger: digitalSmooth digital low-pass filter with outlier rejection
David A. Mellis and Tom Igoe: Smoothing tutorial
Majenki: Average Library

signal-smoothing libraries at github:

AsheeshR / Microsmooth
jeroendoggen: Arduino-signal-filtering-library
karlward: Arduino data filtering library
sebnil: FIR-filter-Arduino-Library
daPhoosa: MedianFilter
arc12: A Collection of Digital Signal Filters (intended for use with Arduino)
sebnil: Selfbalancing robot in Arduino. Implemented with PID controllers, FIR filters, complementary filter.

Would something like this work in your robot?
(The median-of-3 requires very little CPU power, and hence fast):
/*
median_filter.ino
2014-03-25: started by David Cary
*/

int median_of_3( int a, int b, int c ){
    int the_max = max( max( a, b ), c );
    int the_min = min( min( a, b ), c );
    // unnecessarily clever code
    int the_median = the_max ^ the_min ^ a ^ b ^ c;
    return( the_median );
}

int newest = 0;
int recent = 0;
int oldest = 0;

void setup()
{
    Serial.begin(9600);
    // read first value, initialize with it.
    oldest = random(200);
    recent = oldest;
    newest = recent;
    Serial.println("median filter example: ");
}

void loop()
{
    // drop oldest value and shift in latest value
    oldest = recent;
    recent = newest;
    newest = random(200);

    Serial.print("new value: ");
    Serial.print(newest, DEC);

    int median = median_of_3( oldest, recent, newest );

    Serial.print("smoothed value: ");
    Serial.print(median, DEC);
    Serial.println("");

    delay(5000);
}


user65: Microsmooth is a lighweight signal smoothing library currently being developed by me.
It is still being worked on and the aim is to make it lightweight in terms of memory and fast. The library provides multiple filters for smoothing:

Simple Moving Average
Exponential Moving Average
Cumulative Moving Average
Savitzky Golay Filter
Ramer Douglas Pecker Algorithm
Kalmogorov Zurbenko Filter

To use the library, download and add it to the source directory. Also, add the following line to your source file:
#include "microsmooth.h"


65: <p>I am working on a mobile robot controlled via a wireless 2.4 GHz link.The receiver is connected to the Arduino Uno which serves onboard as the main controller. The most critical (and main) input channel coming from the receiver produces a very noisy signal, which leads to lots of minor changes in the output of the actuators, even though these are not needed.</p>

<p><em><pre>
<img src="https://i.stack.imgur.com/Z1yB0.png" alt="enter image description here">
                    Plot of the input of the Arduino in a 30 second interval.</pre></em></p>

<p>I am looking for libraries that can perform efficient smoothing. Are there any signal smoothing libraries available for the Arduino (Uno)?</p>
 113: <p>You could filter this digitally using a low pass filter:</p>

<pre><code>int valueFilt = (1-0.99)*value + 0.99*valueFilt;
</code></pre>

<p>Change the 0.99 to change the cut off frequency (closer to 1.0 is lower frequency). The actual expression for that value is exp(-2*pi*f/fs) where f is the cutoff frequency you want and fs is the frequency the data is sampled at.</p>

<p>Another type of "digital filter" is an event filter. It works well on data that has outliers; e.g. 9,9,8,10,9,25,9 . An event filter returns the most frequent value. Statistically this is the mode.</p>

<p>Statistical averages such as Mean, Mode etc.. can be calculated using the <a href="http://playground.arduino.cc/Main/Average" rel="nofollow">Arduino Average Library</a>.</p>

<p>An example taken from the Arduino Library page referred to :</p>

<pre><code>#include &lt;Average.h&gt;
#define CNT 600
int d[CNT];

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int i;

  for(i=0; i&lt;CNT; i++)
  {
    d[i] = random(500);
  }  

  Serial.print("Mean: ");
  Serial.print(mean(d,CNT),DEC);
  Serial.print(" Mode: ");
  Serial.print(mode(d,CNT),DEC);
  Serial.print(" Max: ");
  Serial.print(maximum(d,CNT),DEC);
  Serial.print(" Min: ");
  Serial.print(minimum(d,CNT),DEC);
  Serial.print(" Standard deviation: ");
  Serial.print(stddev(d,CNT),4);
  Serial.println("");
  Serial.println("");

  delay(5000);
}
</code></pre>
 8: <p>Have you tried a low pass filter? I found an example <a href="http://arduino.cc/en/Tutorial/Smoothing" rel="nofollow">here</a> an another one <a href="http://playground.arduino.cc/main/smooth" rel="nofollow">here</a>.</p>

<p>Both of these libraries have a list of data being read from the analog sensor of your choice which is averaged. Every new sensor value is added to the list, and the last one is thrown out, like this:</p>

<pre><code>List: 3 4 3 3 4 3 5 3 2 3 4 3 
new reading added. old one thrown out
      /--                     /--
List: 5 3 4 3 3 4 3 5 3 2 3 4
list averaged
</code></pre>
 186: <p>I think I see a lot of single-sample noise spikes in your noisy signal.</p>

<p>The median filter does better at getting rid of single-sample noise spikes than any linear filter.
(It is better than any low pass filter, moving average, weighted moving average, etc. in terms of its response time and its ability to ignore such single-sample noise spike outliers).</p>

<p>There are, in fact, many signal-smoothing libraries for the Arduino, many of which include a median filter.</p>

<p>signal-smoothing libraries at arduino.cc:</p>

<ul>
<li><a href="http://playground.arduino.cc/Main/Smooth">Paul Badger: smooth digital low-pass filter</a></li>
<li><a href="http://playground.arduino.cc/Main/DigitalSmooth">Paul Badger: digitalSmooth digital low-pass filter with outlier rejection</a></li>
<li><a href="http://arduino.cc/en/Tutorial/Smoothing">David A. Mellis and Tom Igoe: Smoothing tutorial</a></li>
<li><a href="http://playground.arduino.cc/Main/Average">Majenki: Average Library</a></li>
</ul>

<p>signal-smoothing libraries at github:</p>

<ul>
<li><a href="https://github.com/AsheeshR/Microsmooth">AsheeshR / Microsmooth</a></li>
<li><a href="http://github.com/jeroendoggen/Arduino-signal-filtering-library">jeroendoggen: Arduino-signal-filtering-library</a></li>
<li><a href="http://github.com/karlward/Filter">karlward: Arduino data filtering library</a></li>
<li><a href="http://github.com/sebnil/FIR-filter-Arduino-Library">sebnil: FIR-filter-Arduino-Library</a></li>
<li><a href="http://github.com/daPhoosa/MedianFilter">daPhoosa: MedianFilter</a></li>
<li><a href="http://github.com/arc12/LibSimpleFilters">arc12: A Collection of Digital Signal Filters (intended for use with Arduino)</a></li>
<li><a href="http://github.com/sebnil/Selfbalancing-robot">sebnil: Selfbalancing robot in Arduino. Implemented with PID controllers, FIR filters, complementary filter.</a></li>
</ul>

<p>Would something like this work in your robot?
(The median-of-3 requires very little CPU power, and hence fast):</p>

<pre><code>/*
median_filter.ino
2014-03-25: started by David Cary
*/

int median_of_3( int a, int b, int c ){
    int the_max = max( max( a, b ), c );
    int the_min = min( min( a, b ), c );
    // unnecessarily clever code
    int the_median = the_max ^ the_min ^ a ^ b ^ c;
    return( the_median );
}

int newest = 0;
int recent = 0;
int oldest = 0;

void setup()
{
    Serial.begin(9600);
    // read first value, initialize with it.
    oldest = random(200);
    recent = oldest;
    newest = recent;
    Serial.println("median filter example: ");
}

void loop()
{
    // drop oldest value and shift in latest value
    oldest = recent;
    recent = newest;
    newest = random(200);

    Serial.print("new value: ");
    Serial.print(newest, DEC);

    int median = median_of_3( oldest, recent, newest );

    Serial.print("smoothed value: ");
    Serial.print(median, DEC);
    Serial.println("");

    delay(5000);
}
</code></pre>
 65: <p><a href="https://github.com/AsheeshR/Microsmooth">Microsmooth</a> is a lighweight signal smoothing library currently being developed by me.</p>

<p>It is still being worked on and the aim is to make it lightweight in terms of memory and fast. The library provides multiple filters for smoothing:</p>

<ul>
<li>Simple Moving Average</li>
<li>Exponential Moving Average</li>
<li>Cumulative Moving Average</li>
<li>Savitzky Golay Filter</li>
<li>Ramer Douglas Pecker Algorithm</li>
<li>Kalmogorov Zurbenko Filter</li>
</ul>

<p>To use the library, download and add it to the source directory. Also, add the following line to your source file:</p>

<pre><code>#include "microsmooth.h"
</code></pre>
