The Arduino Servo library: move a hobby servo to an angle
Servo.h ships with the Arduino IDE and turns an angle into the pulse a hobby servo listens for. Every 20 ms the servo wants one high pulse, roughly 1 ms wide for one end of its travel and 2 ms for the other, and the library works that width out from the number of degrees you pass to write(). You never touch the timing yourself.
Built in on Mokxi: #include <Servo.h> and it builds, with nothing to install. Free, and no account needed.
What Servo does
The defaults are the library鈥檚 own: attach(pin) maps 0 to 180 degrees onto 544 to 2400 microseconds, so write(90) sends about 1472. Real SG90 and MG996R servos rarely use that whole window, which is why many sketches call attach(pin, 1000, 2000) or drive the width directly with writeMicroseconds() to stop a servo buzzing against its end stop.
On an Uno the stock library takes Timer1 to make its pulses, so analogWrite() on pins 9 and 10 stops working once a servo is attached, whichever pin the servo is on. The other thing that catches people is power: a servo under load pulls far more current than the 5V pin likes, so a servo that twitches or resets the board usually needs its own supply with the grounds joined.
| Library Manager name | Servo |
|---|---|
| Author | Arduino |
| Include | #include <Servo.h> |
| Boards | every board Mokxi compiles for |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | Hobby servo |
Install it
It builds on every board Mokxi compiles for.
In Mokxi it is built in: #include <Servo.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "Servo" by Arduino from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add Servo to lib_deps in PlatformIO. Mokxi follows the calls of release 1.2.2, so a sketch written here builds there too.
What to know in the simulator: One pulse per write(): the part holds the last width, as a real servo does.
ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 ATtiny85 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
Servo myservo;
Declares one servo. Make one object per servo; an Uno handles twelve on the stock library.
myservo.attach(9)
Connects the object to a pin and starts its pulses there, with the default 544 to 2400 microsecond window.
myservo.attach(9, 1000, 2000)
The same, with your own minimum and maximum pulse width, so 0 and 180 degrees land where your servo really stops.
myservo.write(angle)
Sets the angle from 0 to 180. The call returns at once; the horn takes a few hundred milliseconds to get there, which is why sweeps put a delay() between steps.
for (int angle = 0; angle <= 180; angle++) {
myservo.write(angle);
delay(15);
}myservo.writeMicroseconds(1500)
Sends a pulse width directly. 1500 is center on most servos, and on a continuous-rotation servo it is stop.
myservo.read()
Returns the last angle you wrote, not a measurement: a hobby servo has no wire that reports where it actually is.
myservo.attached()
True while the object has a pin.
myservo.detach()
Stops the pulses. Most servos then go limp, which saves power and stops the hum of a servo holding still.
Example: Servo sweep
On the Arduino Uno R3. It runs in the browser exactly as printed.
// Servo sweep: the horn swings to 0, 90 and 180 degrees, then sweeps back.
//
// servo brown (GND) -> GND
// servo red (VCC) -> 5V
// servo orange (PWM) -> pin 9
//
// A hobby servo turns to an angle and holds it. It reads the angle from the
// width of a pulse sent fifty times a second: about 0.5 ms is one end, about
// 2.4 ms the other. The Servo library sends that pulse for you; write(angle)
// only changes how wide it is.
//
// The horn needs time to get there. This one moves about 60 degrees in a
// tenth of a second, so each jump waits a second before the next.
#include <Servo.h>
Servo horn;
void moveTo(int angle) {
horn.write(angle);
Serial.print("angle ");
Serial.println(angle);
}
void setup() {
horn.attach(9);
Serial.begin(9600);
Serial.println("Mokxi Uno: servo sweep");
}
void loop() {
moveTo(0);
delay(1000);
moveTo(90);
delay(1000);
moveTo(180);
delay(1000);
// A slow sweep back, one degree at a time.
for (int angle = 180; angle >= 0; angle--) {
horn.write(angle);
delay(10);
}
Serial.println("swept back to 0");
delay(1000);
}Open it in the editor, wired and ready to run 路 Servo sweep: the project page
Common errors and how to fix them
The servo jitters, twitches or the board resets when it moves
The servo is drawing more current than the board鈥檚 5V regulator or USB port can give. Power it from a separate 5 to 6 V supply or battery pack, join that supply鈥檚 ground to the Arduino鈥檚 GND, and keep only the signal wire on the Arduino pin.
analogWrite() on pin 9 or 10 stopped working after adding a servo
On an Uno or Nano the Servo library uses Timer1 for its pulses, and Timer1 is also the PWM timer for pins 9 and 10. Move the LED or motor that needs PWM to pin 3, 5, 6 or 11.
The servo buzzes at 0 or 180 degrees and gets warm
The default pulse window is wider than your servo鈥檚 real travel, so it is pushing against its own end stop. Call attach(pin, min, max) with a narrower window such as 1000 and 2000, or keep write() between about 10 and 170.
Servo.h compiles on the Uno but not on an ESP32
The stock Servo library is for the AVR and a few other cores. On an ESP32 most sketches use the ESP32Servo library, whose class and calls are the same, so the change is usually just the #include line.
Questions and answers
Which wire goes where on an SG90?
Brown or black is ground, red is power (about 5 V), and orange or yellow is the signal, which goes to the pin you pass to attach().
Can I use any digital pin for the signal?
Yes. The library makes its own pulses, so the signal pin does not need to be a PWM pin.
Projects that use Servo
Built-in projects that include it. Each page has the full sketch and opens in the editor, already wired.
Try Servo without installing anything
Open the example, change the sketch, and keep your version in a free account.