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 mini | SG90 micro servo (9 g) | Wire | Notes |
|---|---|---|---|
| D5 | SIG | orange | A 3.3 V signal drives the SG90 fine. |
| 5V | VCC | red | One 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. |
| GND | GND | brown |
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
Servolibrary (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
// 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");
}
}
}// 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
SG90 on D5 - type an angle 0-180
Angle 90
Angle 0
Angle 180SG90 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.