Understanding servo's pulse width and control signal period

I'm trying to figure out how to control a servo without libraries, but I ran into a thing I don't understand.

Everywhere I read it says that the typical control signal period for servos is 20ms and the typical pulse width range should be in 1ms to 2ms range. However, on practice for me the actual pulse width range with which I managed to drive servo from 0 to 180 degrees is 0.5ms to 2.5ms. The 1ms - 2ms visibly doesn't drive servo all the way to 0 and 180 degrees. I also tried changing from digital pin to PWM pin but result is the same.

Is there a way I can for sure test the control signal period of my servo? I'm very new to electronics so I'm completely clueless.
Here's the code I used as well:

#define SERVO_PIN 8
int control_period = 20000;
int angle = 1000;

void setup() {
  pinMode(SERVO_PIN, OUTPUT);
}

void loop() {
  digitalWrite(SERVO_PIN, HIGH);
  delayMicroseconds(angle);
  digitalWrite(SERVO_PIN, LOW);
  delayMicroseconds(control_period - angle);
}

Your observation about the relationship between pulse width and servo position is correct, it's a function of the design of each servo's electronics and unfortunately will vary from design to design.
For any given servo, it's best to empirically test it's pulse-width to position range. I've found that, to within a degree or two, items of the same design will generally respond the same, but changing suppliers can be a headache.

A relatively simple code can be written, using Serial Monitor, to allow incrementing/decrementing either a pulse width in microseconds, or an angle in degrees, to approach the end positions to 'feel' your way to numbers you can trust.

For example, receiving a + might increment your pulse width by 5 us, > by 25, ] by 100, and obviously -, <, [ would change in the opposite direction. You, of course, still have to determine when the horn is at 0, or at 180, which in itself can be tricky; I'd start with the servo at 1500 us, and work my way down or up to 90 degrees of rotation. If either end doesn't seem reachable, then the 'center' value of 1500 may need modification.

1 Like

A relatively simple code can be written, using Serial Monitor, to allow incrementing/decrementing either a pulse width in microseconds, or an angle in degrees, to approach the end positions to 'feel' your way to numbers you can trust.

Could you please elaborate on this part or tell me what to research? It would really cool to know how to do it.

If what I just sent isn't enough, perhaps someone else can chip in. I've got to go away shortly.

Hint: In the code you posted, simply check Serial monitor for the characters I mentioned, and modify "angle" appropriately. Don't forget to Serial.begin(9600) in setup, and reading serial characters is amply described in the examples.

1 Like

What does the datasheet say?

I know that you said you were not using any libraries, but the examples 'knob' and 'sweep' that come with the Servo library could give you some ideas.

20 ms cycle time allows to cover 10 channels of 0.5 to 1.5 ms in one cycle. In a multi-channel RC at least one of these channels should be unused and give a sync mark for the last of 10 channels.

Of course only conforming servos can be used in such a multi-channel control. Servos for single channel use can have any period and pulse width, as long as the receiver can decode.