Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

SG90 servo with ESP32 — ESP32Servo wiring and sweep code

Drive an SG90 micro servo from an ESP32 DevKit V1 on GPIO18 with the ESP32Servo library, powered properly so the board doesn’t brown out.

Arduino C++Verified — core esp32 3.3.12, ESP32Servo 3.2.1, 3 Nov 2026Compile-only

Community draft — report a mistake

An SG90 needs a 50 Hz pulse between roughly 0.5 and 2.4 ms. On the ESP32 the ESP32Servo library produces that from the LEDC peripheral, so the sketch looks just like an Arduino Uno servo sketch.

The wiring is three wires, but power is the real lesson: the servo’s current spikes are the commonest cause of ESP32 resets, so give it its own 5 V supply as soon as it carries any load.

Wiring

ESP32 DevKit V1Only the pins used are shown · 3.3 V logicSG90 micro servo (9 g)GNDVIND18SIGVCCGND
Every connection
ESP32 DevKit V1SG90 micro servo (9 g)WireNotes
D18SIGorangeA 3.3 V signal is enough for the SG90.
VINVCCredOne unloaded SG90 on a good USB port only. For real loads use a separate 5 V 1 A supply and join its GND to the ESP32 GND.
GNDGNDbrown

4.8–6 V (several hundred mA while moving or stalled) part, 3.3 V board. The signal input is happy with 3.3 V logic, so ESP32 and Pico drive it directly. On ESP32 use the ESP32Servo library — the standard Servo library is for AVR and RP2040.

Board quirks

  • The core Servo library is AVR-only; on ESP32 use ESP32Servo, which drives the pulse from an LEDC PWM channel.
  • A stalled servo can pull several hundred mA. Powered from VIN that drops the board’s supply and causes brownout resets.
  • Any output-capable pin works; GPIO18 is free at boot and not a strapping pin.

Code

servo-esp32.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// SG90 micro servo on an ESP32 DevKit V1 with ESP32Servo (uses an LEDC channel).
// Signal (orange) → D18, red → 5 V supply, brown → GND (shared with the ESP32).
#include <ESP32Servo.h>

constexpr uint8_t SERVO_PIN = 18;
Servo servo;

void setup() {
  Serial.begin(115200);
  servo.setPeriodHertz(50);              // standard 50 Hz servo frame
  servo.attach(SERVO_PIN, 500, 2400);    // SG90 pulse range in µs
  Serial.println("Sweeping 0° ↔ 180°");
}

void loop() {
  for (int angle = 0; angle <= 180; angle += 30) {
    servo.write(angle);
    Serial.printf("Angle %d°\n", angle);
    delay(500);
  }
  for (int angle = 180; angle >= 0; angle -= 30) {
    servo.write(angle);
    Serial.printf("Angle %d°\n", angle);
    delay(500);
  }
}

Library: Servo (Arduino) — compiled with ESP32Servo 3.2.1.

Expected serial output

Serial Monitor · 115200Output
Sweeping 0° ↔ 180°
Angle 0°
Angle 30°
Angle 60°
Angle 90°

Common errors

Servo jitters or twitches

Usually supply noise: give the servo its own 5 V supply and a 470 µF capacitor across it, with a common ground.

ESP32 resets when the servo moves

Brownout from servo current on the USB supply. Power the servo separately.

↑↓ to move · Enter to open