ESP32-S3 Servo Simulator: Wiring, Code and a Live Circuit
This is an SG90 hobby servo wired to an ESP32-S3 DevKitC-1, 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 5V and orange to GPIO 5. The ESP32-S3’s 3.3 V signal drives a 5 V servo without a level shifter.
- 3.3 V logic
- Library: ESP32Servo.h
- Signal on GPIO 5
- Powered from 5V
Wiring the Servo to the ESP32-S3
Every connection in the circuit above, with the board’s own pin names.
| Servo pin | ESP32-S3 pin | Why |
|---|---|---|
| Brown (GND) | G | The signal is measured against this, so it must be shared with the board. |
| Red (V+) | 5V | 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 5 | Any GPIO with an output driver; the ESP32 makes the pulse in its LEDC hardware. |
The servo runs from 5V 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-S3
GPIO 19 and 20 are the USB port’s data lines, GPIO 35 to 37 belong to the PSRAM on octal-PSRAM boards such as the N8R8, and GPIO 0, 3, 45 and 46 are strapping pins.
On a real bench
The DevKitC-1 has two USB sockets: UART for uploading and the serial monitor, USB for the S3’s own USB device. Plug into UART while you work with the Servo. The board is wide, so a single breadboard leaves only one row free on one side.
The code
The sketch the circuit above runs. Open it in the editor, change a line and press Run: it compiles in your browser.
#include <ESP32Servo.h>
const int SERVO_PIN = 5; // signal, GPIO 5
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-S3 DevKitC-1 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 board’s UART socket, at 115200 baud in this sketch.
Common mistakes with the Servo on the ESP32-S3
Powering the servo from 3V3
The ESP32-S3’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 5V.
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.
Using the USB or PSRAM pins
GPIO 19 and 20 are the USB port’s data lines and GPIO 35 to 37 belong to the PSRAM on N8R8 boards. Wire the servo signal to one of those and the USB socket or the memory stops working on a real board, even though the simulator carries on. Stay on GPIO 4 to 18.
Questions and answers
Can I simulate a servo with an ESP32-S3 DevKitC-1 online?
Yes. The circuit at the top of this page is an ESP32-S3 DevKitC-1 with a servo, running in your browser on a simulated ESP32-S3 (Xtensa LX7). 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-S3 pins can drive a servo?
Any GPIO with an output driver. The pulse comes from LEDC through the GPIO matrix, so there is no fixed list of PWM pins.
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.