2

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?

blfuentes
  • 221
  • 2
  • 7
  • 18

3 Answers3

5

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.

potval = alpha*potval + (1-alpha)*rawreading;

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:

potval = (potval*12 + rawreading)/13;

The technique mentioned above is called exponential smoothing or exponential moving average.

James Waldby - jwpat7
  • 8,920
  • 3
  • 21
  • 33
4

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

//In setup
int bufferedVal = analogRead(A0);
int unbufferedVal = analogRead(A0);
#define _TOLERANCE_ 5

//The loop
unbufferedVal = analogRead(A0);
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:

int val = analogRead(A0);
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.

Anonymous Penguin
  • 6,365
  • 10
  • 34
  • 62
1

Since the previous answers were all code-related, let me suggest you use a smoothing capacitor. In noisy environments, or where you want to get more consistent readings, place a capacitor across your signal lines (signal to ground). The result is less "spikes" in your readings, and can sometimes cause a slight delay in signal changes, as charge has to build up in the capacitor before the voltage goes up.

http://www.learningaboutelectronics.com/Articles/What-is-a-smoothing-capacitor

Ian M
  • 121
  • 5