Arduino starter kit servo is shaking

In the example of the arduino starter kit the point is to use a potenciometer to control a servo.

The code is

angle = map(potVal, 0, 1023, 0, 179);

The output in the serial

potVal: 1023, angle: 179
potVal: 1015, angle: 177
potVal: 1023, angle: 179
potVal: 1016, angle: 177
potVal: 1023, angle: 179
potVal: 1023, angle: 179

I noticed that the servo is shaking like trying to go passing over the 179, when it is suppose to use an angle max 180º (0-179)

What could be the problem?

• Does the serial output above occur without changing the pot position? Sep 11 '14 at 8:18
• Yes, when I reach the "top" 1023 it shakes and oscilates between close values. Could it be a mechanical problem? Sep 11 '14 at 8:20
• No, I just included the Servo library. It is a basic example, where a pot controls the servo. Sep 11 '14 at 9:04
• It seems the problem comes from the pot not the servo. Since 2 consecutive reads don't provide the same value, the servo will change its position of a few degrees and looks like it is vibrating. Sep 11 '14 at 9:58

I like this method the best (personal preference) for smoothing signals:

//In setup
#define _TOLERANCE_ 5

//The loop
if(abs(unbufferedVal - bufferedVal) >= _TOLERANCE_ ) {
bufferedVal = unbufferedVal;
}

This finds the error using the abs() function (absolute value; makes sure it is positive).

Another thing you can do is round it to the tenth placeholder (i.e. 88 -> 90, 83 -> 80) so it always is a good number to work with:

val += 5;
val = val / 10;
val = val * 10;

The last two lines work because of the lack of precision that integers offer with decimals. If I divide 88 by 10, it doesn't output 8.8; it outputs 8 instead. We then multiply by ten again so it isn't 8 when it really should be 80. The only problem with this is it only rounds down. We can fix this by adding 5 (the halfway point between 10 and 0). That way, it goes: 88 to 93 to 9.3 to 9 to 90.

NOTE: I'm not sure if the compiler will notice the redundancy of the last two lines. If it acts weird, try using the volatile keyword.

• I had to set the tolerance to 10, but it worked. Sep 15 '14 at 18:13
• Rounding the one's digit is likely to sometimes make the problem quite a bit worse - if the average value is near the rounding threshold, then small noise variations can get substantially amplified +1/-1 can become +5/-5. Nov 10 '14 at 20:02

If the problem is due to jittery pot readings, you may want to smooth the potval data sequence by code like the following, where rawreading stands for what you just read from the potentiometer's input line.

Set alpha to a number (eg 0.8 or 0.9 or 0.95 etc) between 0 and 1. alpha represents the fraction of the old value that you retain, and 1-alpha represents the fractional influence of the new raw reading. alpha closer to 1 causes smoother but slower response.

If you prefer integer arithmetic for faster or smaller code, then represent alpha as a ratio of integers. For example: