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 Wemos D1 mini — full 180° on the ESP8266

Drive an SG90 servo from a Wemos D1 mini on D5 with the ESP8266 core’s Servo library, set the 500–2400 µs range for a full sweep, and power it safely.

Arduino C++Verified — core esp8266 3.1.2, 3 Nov 2026Compile-only

Community draft — report a mistake

A servo on a D1 mini is the core of a Wi-Fi blind opener, a pet feeder or a remote switch-presser. Signal on D5, power from the 5V pin for a single light-duty SG90, and a common ground.

The ESP8266 has its own built-in Servo library, and it differs from the Arduino Uno one in a way that catches everyone: a narrower default pulse range. This guide sets it right so the SG90 swings the full 180°.

Wiring

Wemos D1 miniOnly the pins used are shown · 3.3 V logicSG90 micro servo (9 g)D5GND5VSIGVCCGND
Every connection
Wemos D1 miniSG90 micro servo (9 g)WireNotes
D5SIGorangeA 3.3 V signal drives the SG90 fine.
5VVCCredOne unloaded SG90 from a good USB port. For a loaded servo, use a separate 5 V 1 A supply and join its GND to the D1 mini’s 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 ESP8266 core ships its own Servo library (no install needed), but its default pulse range is 1000–2000 µs, which turns an SG90 only about 90°. servo.attach(D5, 500, 2400) gives the full sweep; narrow it if your servo buzzes at the ends.
  • The core generates the pulse in software from a timer, on any pin except D0 (GPIO16). D5 is used because it is quiet during boot — a servo on D3/D4 can twitch when the board resets.
  • A moving or stalled SG90 pulls a few hundred mA. Drawn from the USB 5 V the D1 mini also runs from, that can dip the 3.3 V rail and reset the ESP8266 — the classic “board reboots every time the servo moves”.
  • Type an angle and press Enter. Serial.parseInt() waits up to a second for digits but yields while it waits, so the watchdog stays fed.

Code

servo-d1mini.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// SG90 servo on a Wemos D1 mini (ESP8266), using the Servo library built into the ESP8266 core.
// SIG → D5 (GPIO14), VCC → 5V, GND → GND.
// Type an angle (0-180) in the Serial Monitor and press Enter.
#include <Servo.h>

const uint8_t SERVO_PIN = D5;  // GPIO14 - not a boot pin, and quiet during reset
Servo servo;

void setup() {
  Serial.begin(115200);
  Serial.println();
  // The ESP8266 core's Servo defaults to 1000-2000 us, which moves an SG90 only about 90 degrees.
  // 500-2400 us gives the full sweep on most SG90s; narrow it if yours buzzes at the ends.
  servo.attach(SERVO_PIN, 500, 2400);
  servo.write(90);
  Serial.println("SG90 on D5 - type an angle 0-180");
  Serial.println("Angle 90");
}

void loop() {
  if (Serial.available()) {
    int angle = Serial.parseInt();  // waits up to 1 s for digits; yields to the system meanwhile
    while (Serial.available()) Serial.read();  // drop the line ending
    if (angle >= 0 && angle <= 180) {
      servo.write(angle);
      Serial.printf("Angle %d\n", angle);
    } else {
      Serial.println("Use 0-180");
    }
  }
}

Library: Servo (Arduino).

Expected serial output

Serial Monitor · 115200Output
SG90 on D5 - type an angle 0-180
Angle 90
Angle 0
Angle 180

Common errors

Servo only moves about half way

You used attach(pin) with the core’s 1000–2000 µs default. Use attach(pin, 500, 2400).

Board resets when the servo moves

Supply dip. Power the servo from its own 5 V supply with a common GND, and add a 470 µF capacitor across the servo supply.

Servo jitters at rest

Supply noise or a long signal wire. Full fix.

↑↓ to move · Enter to open