ESP32 · Servo

ESP32 Servo Simulator: Wiring, Code and a Live Circuit

This is an SG90 hobby servo wired to an ESP32 DevKit, sweeping from 0 to 180 degrees and back, live in your browser. The horn on the drawing turns as the sketch writes each angle.

Three wires: brown to GND, red to VIN (5 V from USB) and orange to GPIO 13 (D13). The ESP32’s 3.3 V signal drives a 5 V servo without a level shifter.

  • 3.3 V logic
  • Library: ESP32Servo.h
  • Signal on GPIO 13 (D13)
  • Powered from VIN (5 V from USB)
ESP32 · Servolive0.000 s 0.00x
Click to open it in the editor
The circuit itself, running on the simulator with the sketch below. Press what can be pressed; click anything else to open it in the editor.

Wiring the Servo to the ESP32

Every connection in the circuit above, with the board’s own pin names.

Servo pinESP32 pinWhy
Brown (GND)GNDThe signal is measured against this, so it must be shared with the board.
Red (V+)VIN (5 V from USB)An SG90 wants 4.8 to 6 V. At 3.3 V it barely moves, so it takes the 5 V rail, not 3V3.
Orange (signal)GPIO 13 (D13)Any GPIO with an output driver; the ESP32 makes the pulse in its LEDC hardware.

The servo runs from VIN (5 V from USB) while its signal comes from a 3.3 V pin. That works: an SG90 reads anything above about 2 V as high, so no level shifter is needed. On a real bench, a servo under load can pull more current than USB gives; then power it from its own 5 V supply and join the grounds.

Pins to leave alone on the ESP32

GPIO 34, 35, 36 (VP) and 39 (VN) are input only: they cannot drive a pin or take an internal pull-up. GPIO 0, 2, 5, 12 and 15 are strapping pins, read at power-on, and GPIO 6 to 11 are the flash chip.

On a real bench

The thirty-pin DevKit straddles a breadboard with one row of holes free on each side, which is where the Servo’s jumpers go. Many ESP32 boards are wider and cover both rows; then use two breadboards side by side. Hold BOOT while uploading if the IDE cannot connect.

The code

The sketch the circuit above runs. Open it in the editor, change a line and press Run: it compiles in your browser.

Servo sweep on ESP32 GPIO 13 (D13)
#include <ESP32Servo.h>

const int SERVO_PIN = 13;   // signal, GPIO 13 (D13)
Servo servo;

void setup() {
  Serial.begin(115200);
  servo.attach(SERVO_PIN);        // 544 to 2400 us, 50 times a second
  Serial.println("Sweeping");
}

void loop() {
  for (int angle = 0; angle <= 180; angle += 2) {
    servo.write(angle);
    delay(15);
  }
  Serial.println("at 180");
  for (int angle = 180; angle >= 0; angle -= 2) {
    servo.write(angle);
    delay(15);
  }
  Serial.println("back at 0");
}

ESP32Servo.h is the name ESP32 tutorials use for the Servo library, and it compiles here with the same calls. On an ESP32 DevKit the pulse is made by the LEDC peripheral, so the timing stays exact while the core is busy.

servo.attach(SERVO_PIN) starts a pulse every 20 ms. write(angle) sets its width: 544 microseconds for 0 degrees, 1472 for 90 and 2400 for 180, the library’s defaults and the simulated servo’s too.

The loops step two degrees every 15 ms, about 1.4 seconds for a sweep, which an SG90 can follow; it needs roughly 0.1 s per 60 degrees. Serial.begin(115200) opens the serial monitor. Serial is UART0 on the USB bridge. ESP32 sketches usually run it at 115200 baud, which this one does.

Common mistakes with the Servo on the ESP32

Powering the servo from 3V3

The ESP32’s 3.3 V regulator is sized for the chip, not a motor, and an SG90 at 3.3 V jitters or stalls. The red wire goes to VIN (5 V from USB).

Forgetting the common ground

With the servo on a separate supply and only the signal wire to the board, the servo has nothing to measure the pulse against and twitches at random. Connect the supply’s ground to the board’s GND.

Putting the servo signal on an input-only pin

GPIO 34, 35, 36 and 39 on the ESP32 have no output driver at all. pinMode() to OUTPUT on one of them does nothing and the line never moves, which looks exactly like a dead part. GPIO 4 (D4) is a safe choice; so are GPIO 13, 14, 16 to 19, 23, 25 to 27 and 32 to 33.

Questions and answers

Can I simulate a servo with an ESP32 DevKit online?

Yes. The circuit at the top of this page is an ESP32 DevKit with a servo, running in your browser on a simulated ESP32 (Xtensa LX6). The simulated servo reads the real pulse width the board makes, so a wrong angle in the code is a wrong angle on the drawing. Press Run it in the editor to change the wiring or the code; it is free and needs no account.

Which ESP32 pins can drive a servo?

Any GPIO with an output driver. The pulse comes from LEDC through the GPIO matrix, so only the input-only GPIO 34 to 39 are out.

Why does my servo only turn about 160 degrees?

Many SG90s reach their end stops before 544 or 2400 microseconds. Find your servo’s real limits and pass them to attach(pin, min, max), for example attach(pin, 600, 2300).

How do I control a continuous rotation servo?

Same wiring and the same library: write(90) stops it, smaller angles turn it one way and larger ones the other, faster the further from 90. In the editor, set the servo’s mode property to continuous.

Build your own Servo project

Open this circuit in the editor, change the wiring or the code, and keep your version in a free account.