Let's Make Robots!

sensor jitter problems? Let's fight back.

I wrote a tiny function in Arduino-C for my sensor-jitter problems. You can smooth out your sensor readings with this little function. You can input the smoothness and then get back the smoothed sensor value.

If somebody needs it - here it is:

// Jan Przybilla, Rosk, Farbtonstudio.de
// SSR - Smooth Sensor Readings
// Fight the (((Jitter)))!


#define SMOOTH 10                  // Sensor Smoothness (5 - 50)
int readings[SMOOTH];              // Smoothcounter Variable
int index = 0;                               // Smoothindex Var
int total = 0;                                 // Runcounter
int average = 0;                           // Var average
int readMe = 0;                            // Read this Pin
int p_val;                                      // Smoothed Variable

// Average sensor value
void sensorval(){
  total -= readings[index];               // substract the last value
  readings[index] = analogRead(readMe);   // read the sensor
  total += readings[index];             // add the value
  index = (index + 1);                    // goto next index

  if (index >= SMOOTH)               // if we are at the end of the array
    index = 0;                                 // ...go to the beginning

  average = total / SMOOTH;       // average from all readings
  // ...giveback
  p_val = average;
}

void setup()
{
  // SERIAL OUTPUT
  Serial.begin(9600);             // Serial Output start
  for (int i = 0; i < SMOOTH; i++)
    readings[i] = 0;              // reset all Smoothreadings to 0
}

void loop()
{       
  // Sensor Jitter-average loop
    sensorval();
    Serial.println(p_val);               // Show smoothed value  
}

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I must admit that I can’t follow your program. Your make an array of 10 elements (SMOOTH 10), but as far as I can see you never use the values in the array. The only math is performed on the total variable. The only place you use the value of the array is here total -= readings[index]; Shouldn’t you remove the oldest read value and not the next to last value?
On the first run before the total contains a sum of 10 values is it correct to: average = total / SMOOTH?

Hi Geir,

the array in this function is "readings[]". First of all you assign the smoothnes variable to the array. In our case 10 (#define SMOOTH 10). Values between 5 and 50 are good - lower values produces bad results, higher values will slow down your board. We fill our variable s of the readings[] array in the run with values. If we got all values in our dataarray for our run   if (index >= SMOOTH)   we reset the index for the next cycle, then we give back the average of the SMOOTH values (average = total / SMOOTH; ) to our p_val.
Thats what we want to have - a smoother value to work with, in a new smoothed variable: p_val

Finally we just call the function sensorval(); to start smoothing.

Hi Janson
I’m probably just thick, but I still don’t get it.

As far as I can tell every time you call the sensorval() the p_val gets updated. So I can’t see why the size of the array would change the response time at all. If the sensorval() function had a loop reading 10 or 50 values and averaging those I would understand it, but as far as I can see it doesn’t.


This is how I read your function;

Sensorval()
  - Subtract the last sensorvalue from total
  - Read new sensorvalue
  - Add new value to total
  - Divide the total by 10 and return the value ??

Again I can’t see what the array is doing other than being a place to store the last sensorvalue that you subtract from the total. Couldn’t that just be replaced by a LastValue int and save the RAM?

This is how I think it should work;

Sensorval()
  - Read the sensorvalue into the array
  - Increment the index
  - If we are at the array boundary reset the index to make it a circular array.
  - In a for loop, add up all the values in the array and divide it by SMOOTH to get the correct p_val.

Does this make any sense?

Our jittered sensorvalues we want to smooth are similiar to this for example:

...
119
118
225 -> High Peak Jitter
120
125
127
118
36 -> Low Peak Jitter
120
119
...

Now we take a X number of values of this stream, count them together and divide
it through the number of readings. Every runtime we count our runindex var up. If our index
is == our SMOOTH we make the dividing and then give this value back (the p_val).

In our case this would be ((119+118+225+120+125+127+118+36+120+119)/10) = 122.
If we got our smoothed value, we start to fill our data array again...

I write a better documented version and post in in the tips section.
Greetings!

I've seen another function where there was the extra step of ignoring the highest and lowest readings when taking the average in order to stop really wacky readings skewing the result.

This sound good and is easy to implement. Thanks.

Nice tip. I'm collecting this one.

I suggest you post it as a Tip/Walkthrough instead of a blog.

Sorry for posting it here, I thought this would be the right place. But I'm getting slowly more familar with the lmr boardconcept here. Should I post it in Tips again, o should it stay here?