Servo trouble and I am a newbee

There is a bug in the KNOB program. The map should be as follows to keep the servo from spinning at 0 volts input.

val = map(val, 0, 1023, 10, 179); // scale it to use it with the servo (value between 10 and 179)10=starting point to prevent servo from spinning

Full program below:

/*
Controlling a servo position using a potentiometer (variable resistor)
by Michal Rinott http://people.interaction-ivrea.it/m.rinott

modified on 8 Nov 2013
by Scott Fitzgerald

modidied on 1 Feb 2018
by David Brokaw
*/

#include <Servo.h>

Servo myservo; // create servo object to control a servo

int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin

void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop() {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 10, 179); // scale it to use it with the servo (value between 10 and 179)10=starting point to prevent servo from spinning
myservo.write(val); // sets the servo position according to the scaled value
delay(15); // waits for the servo to get there
}

David_Brokaw:
0 volts input.

Seems you think the control is 0V for 0 degrees? It's not, it's a 5V pulse, whose width determines the position. A servo spends most of its time with 0V on the control wire regardless of the position it's been commanded to, since the pulse is narrow compared to the cycle (1000us (0 degrees) to 2000us (180 degrees) in 20000us).

David_Brokaw:
There is a bug in the KNOB program.

Probably not.

val = map(val, 0, 1023, 10, 179); // scale it to use it with the servo (value between 10 and 179)10=starting point to prevent servo from spinning

Not under typical servo behavior.
Typical servos accept a range of inputs, with microsecond values of 1000-2000 being a 'generic' range.
Different servos have different ranges.
Most servos have physical stops that prevent them from spinning around.
There is a small subset of servos, notably some of the ultra-cheap sg90, that some times do not have this physical stop.
On these servos, it has been seen that writing a microsecond value too low does make it spin rather than stopping at a given angle. This is NOT a bug on the program but an odd design in the servo.

As you note, never writing an excessively low value prevents this unwanted spin.

But the servo library actually already provides a solution. servo.Attach()
The first parameter, pin, is mandatory. But is has 2 optional parameters, min and max, With those you can set the servo microsecond range to values other than the defaults. I think the default range is 544 to 2400. Try different values.

servo.Attach(pin, 1000, 2000);

Then try your servo.Write(0) and see what happens.
You can play around with the min and max values to try to determine the actual range that your servo accepts.

vinceherman:
This is NOT a bug on the program but an odd design in the servo.

Agreed.... I was going to say something along those lines too, but decided to limit my contribution to explaining to OP that the signal is a pulse, so position = f(pulse width) not position=f(voltage) kind of thing.

:wink:

The map should be as follows to keep the servo from spinning at 0 volts input.

Servos don't spin. They move to the commanded position and stop there. Unless, of course, you have a so called continuous rotation servo which is not really a servo at all.

UKHeliBob:
Servos don't spin. They move to the commanded position and stop there. Unless, of course, you have a so called continuous rotation servo which is not really a servo at all.

There a few recent posts about sg90s behaving badly as vinceherman said. I read one thread where the servo worked correctly until it got sent to 0 degrees and either didn't have, or broke through, the end stop, and then started to spin.