Servo does not reach full travel: pulse range 500 to 2500 microseconds

Many servos need a wider pulse range than the library default. Set the minimum and maximum in attach().

What the message means

The default range is 544 to 2400 microseconds. Your servo may use a different range, so the arm stops early or hits its end stop.

Fix it in this order

  1. Use attach(pin, min, max) with values near 500 and 2500, then adjust.
  2. Raise the range a little at a time and listen for the servo pushing against its stop.
  3. Stop widening when the servo starts to buzz at the end.
  4. Use the range your servo datasheet gives.
  5. Check the supply, since a weak supply also limits travel.

Why it happens

A hobby servo reads the width of a pulse that repeats many times a second and turns to the angle that width stands for. The library maps zero to 180 degrees onto a default range of pulse widths, and servos from different makers do not all use the same range.

If your servo expects a wider range than the default, the arm stops before its full travel. If you widen it too far, the servo is told to go beyond its mechanical stop and strains against it, which is why you widen in small steps and stop when you hear it buzz.

If you see this, do this

You seeDo this
Turns about 90 degrees onlyWiden the pulse range.
Buzzes at the endRange too wide. Narrow it.

SG90 servo, servo jitter.

Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.

Why this happens

A hobby servo reads a pulse repeated about every 20 ms, which is a rate of 50 Hz. The width of the pulse is the command. A width near 1500 microseconds usually means centre, shorter pulses move toward one end and longer pulses toward the other. The nominal range is often described as 1000 to 2000 microseconds, but many servos accept something closer to 500 to 2500, which gives more travel.

The Arduino Servo library maps an angle of 0 to 180 degrees onto the minimum and maximum pulse widths passed to attach. The mapping is linear: pulse = min + (max – min) x angle / 180. With the default 544 and 2400 microseconds, 90 degrees gives (544 + 2400) / 2 = 1472 microseconds. With 500 and 2500 it gives exactly 1500. Changing these numbers only changes the command, not what the gearbox can physically do.

How to confirm the cause

  • Command writeMicroseconds(1500) and note where the horn points. This should be roughly centre. If it is far off, the servo may be a different type.
  • Step towards one end in 50 microsecond increments and note where the horn stops moving. Do the same for the other end.
  • Listen for buzzing or feel for the servo pushing against its stop. That means the command is beyond the mechanical travel.
  • Measure the servo supply voltage while it moves. A drop below the rated range limits torque and travel.
  • If you have an oscilloscope or logic analyser, measure the actual pulse width and compare it with the number you commanded.

Worked example

Finding a safe range by writing pulse widths directly, then using the result in attach (the numbers are starting values to adjust):

#include <Servo.h>
Servo s;

void setup() {
  s.attach(9, 500, 2500);       // pin, min us, max us
  s.writeMicroseconds(1500);    // centre
  delay(1000);
  s.writeMicroseconds(600);     // creep toward one end; lower a little at a time
}

void loop() {}

Common mistakes

  • Setting a huge range such as 0 to 3000 microseconds and running the servo into its stops.
  • Ignoring a buzz at the end of travel. A buzzing servo is straining and heating.
  • Assuming every servo can turn 180 degrees. Some turn about 90, and continuous-rotation servos do not take an angle at all.
  • Powering the servo from the Arduino 5 V pin, where a weak supply limits travel.
  • Copying one servo’s range to another of a different model.

If this did not fix it

  • The servo may be a continuous-rotation type, where the pulse sets speed, not angle.
  • Mechanical problem: a stripped gear, or a horn fixed on the spline so that it hits the case.
  • Supply sag from sharing a thin wire with other loads; measure the supply while the servo moves.