ESP32 S3 UNO - Servo Motor
This ESP32 S3 Uno servo motor tutorial shows you how to wire a servo to the ESP32 S3 Uno form board and turn it to any angle with Arduino code. You will control the servo motor position, sweep it from 0 to 180 degrees, and set how fast it moves. You will also see how to power the servo safely from an external supply.
In this tutorial, you will:
- Wire a servo motor to the ESP32 S3 Uno
- Control the servo motor angle with the ESP32Servo library
- Sweep the servo back and forth with Arduino code
- Control the servo speed with millis() and map()
- Power the servo from an external 5V supply

Hardware Preparation
| 1 | × | ESP32 S3 Uno-form Board | |
| 1 | × | USB Cable Type-A to Type-C (for USB-A PC) | |
| 1 | × | USB Cable Type-C to Type-C (for USB-C PC) | |
| 1 | × | Servo Motor | |
| 1 | × | Jumper Wires |
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Buy Note: For controlling multiple servo motors, use the PCA9685 16 Channel PWM Servo Driver Module to save MCU pins and simplify wiring.
Overview of Servo Motor
A servo motor is the easiest way to move something to an exact position. You tell it an angle, and it turns its arm there and holds it. Most hobby servos turn from 0 to 180 degrees, so they are great for robot arms, door locks, pan-tilt camera mounts and small pointers.
Pinout
The servo in this tutorial has three wires. Their colors tell you what each one does.
VCC (red wire)
This is the power input. Connect it to 5V.
GND (black or brown wire)
This is ground. Connect it to GND (0V).
Signal (yellow or orange wire)
This wire gets the PWM control signal from an ESP32 S3 Uno pin. The width of each pulse sets the angle of the arm.

ESP32 S3 Uno Pinout
The image below shows the pinout diagram of the ESP32 S3 Uno form board. Use it to find the Uno header pins (D9, 5V, GND…) and their GPIO numbers when you wire the servo.

Wiring Diagram
Many online diagrams connect the servo VCC wire straight to the 5V pin of the board. This works for a tiny servo with no load, but a servo can pull a big current spike when it starts to move, and that can reset or harm the ESP32 S3 Uno.

This image is created using Fritzing. Click to enlarge image
| Servo Pin | ESP32 S3 Uno Pin |
|---|---|
| VCC (red) | 5V |
| GND (black or brown) | GND |
| Signal (yellow or orange) | D9 (GPIO46) |
A safer way is to give the servo its own power supply. The diagram below shows the servo powered from an external 5V source, while the ESP32 S3 Uno only sends the control signal.

This image is created using Fritzing. Click to enlarge image
| Servo Pin | Connect To |
|---|---|
| VCC (red) | External 5V supply (+) |
| GND (black or brown) | External supply GND and ESP32 S3 Uno GND |
| Signal (yellow or orange) | ESP32 S3 Uno D9 (GPIO46) |
※ NOTE THAT:
Always connect the GND of the external power supply to the GND of the ESP32 S3 Uno. Without this shared ground, the control signal has no reference, and the servo will not move correctly.
WARNING
D9 is GPIO46, a boot strapping pin on the ESP32 S3 Uno. The board reads this pin at power-up to choose its boot mode. A servo signal wire is normally safe here, but if the board does not boot or cannot upload code, unplug the servo signal wire from D9, upload, and then plug it back in.
※ NOTE THAT:
The servo runs from 5V, but the ESP32 S3 Uno sends only a 3.3V control signal. This is fine, because the signal goes OUT of the board. Most hobby servos read a 3.3V signal without problems.
How To Program For Servo Motor
Servo code needs only a few lines. You load the library, create a servo object, tell it which pin to use, and then send it an angle.
- Include the library. The ESP32 S3 Uno uses ESP32Servo.h instead of the standard Servo.h:
- Create a Servo object:
If you want to drive more than one servo, create one object for each servo:
- Attach the object to the pin that goes to the servo signal wire. Here it is D9, which is GPIO46 in code:
- Turn the servo to the angle you want, for example 90 degrees:
ESP32 S3 Uno Code
This sketch moves the servo to 0 degrees at startup. Then it sweeps the arm slowly from 0 to 180 degrees and back again, one degree at a time, forever. The 10 ms delay after each step gives the servo time to reach the new angle.
The standard Servo.h library does not support the ESP32 S3 Uno. ESP32Servo.h has the same attach() and write() functions, so the rest of the code stays the same as on other Arduino boards.
Detailed Instructions
- New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
- Wire it up as shown in the diagram.
- Connect the board to your computer with a USB Type-C cable.
- Open Arduino IDE, choose the ESP32S3 Dev Module board and the correct COM port.
- Install the ESP32Servo library. Open the Library Manager, search for ESP32Servo, and install the one by Kevin Harrington.
- Copy the code above and paste it into Arduino IDE.
- Upload the code by clicking the Upload button.

- Watch the servo. The arm turns slowly from 0 to 180 degrees, then slowly back from 180 to 0 degrees, again and again.
- Tip: If the servo shakes or the board resets while the servo moves, switch to the external power wiring shown above.
Code Explanation
Each line of the sketch has a short comment that tells you what it does. Read the comments in the code above to follow the logic step by step.
How to Control Speed of Servo Motor
The sweep code above uses delay(), which blocks the board while the servo moves. A better way is to use map() and millis(). The code below works out the right angle from the time that has passed, so the servo moves at a smooth, fixed speed and your other code keeps running.
To make the servo slower, raise MOVING_TIME. To make it faster, lower it. Change startAngle and stopAngle to set where the movement begins and ends.
Video Tutorial
Watch the video below to see this ESP32 S3 Uno project step by step.
The video demo also uses an HC-SR04 ultrasonic sensor. When an object comes closer than 10 cm, the servo turns to 90 degrees. It goes back to 0 degrees 3 seconds after the object leaves. The demo code is below.
WARNING
In this demo, the ultrasonic sensor TRIG pin goes to D8 (GPIO21) and the ECHO pin goes to D7 (GPIO14). The HC-SR04 ECHO pin gives a 5V signal, but ESP32 S3 Uno pins are NOT 5V tolerant. Use a voltage divider (for example 1 kΩ and 2 kΩ) on the ECHO wire, or use a 3.3V version of the sensor.
Function References
FAQ
Why does the code use ESP32Servo.h instead of Servo.h?
The standard Servo library supports AVR and a few other Arduino boards, but not the ESP32 S3 Uno. The ESP32Servo library by Kevin Harrington uses the board's PWM hardware and keeps the same functions. Code written for the UNO R4 works after you change the include line and the pin number.
Can the ESP32 S3 Uno power a servo motor directly?
A small servo like the SG90 can run from the 5V pin when the board is powered by USB and the servo has little load. Bigger servos, or servos under load, draw more current and can make the board reset. For those, use an external 5V supply and connect its GND to the ESP32 S3 Uno GND.
Does a 5V servo work with the 3.3V signal from the ESP32 S3 Uno?
Yes, most hobby servos accept a 3.3V control signal. The servo still gets 5V on its red wire. Only the signal wire goes to the GPIO pin, and that signal goes out of the board, so you do not need a level shifter.
Can I use a different pin for the servo instead of D9?
Yes. The wiring diagram uses D9 (GPIO46), which is a boot strapping pin. It works in most cases, but if you have boot or upload problems, move the signal wire to another PWM pin such as D5 (GPIO20). Then change servo.attach(46) to servo.attach(20).
How many servos can I control with the ESP32 S3 Uno?
The ESP32Servo library can drive many servos at the same time, one Servo object per pin. The real limit is usually power, not pins. Several servos need an external 5V supply that can give enough current for all of them.
What if my project needs more pins than the Uno headers give?
The ESP32 S3 Uno has two extra rows of holes with more GPIOs: GPIO15 and GPIO16 (I/O, PWM, analog), GPIO45 and GPIO35 to GPIO42 (I/O, PWM), and GPIO47/GPIO48 (output only, PWM). Solder pin headers to use them and write the GPIO number in code. For extra servos, GPIO35 to GPIO42, GPIO15 or GPIO16 are good choices. Be careful with two things. First, GPIO47/GPIO48 may run at 1.8V instead of 3.3V on some modules (especially ones with "V" in the name, like R8V or R16V), so 3.3V devices can be damaged or act strangely, and the servo may not read the signal. Second, GPIO0, GPIO3 (D6), GPIO45 and GPIO46 (D9) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code. Use the other extra pins first.
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No COM port shows up in Arduino IDE | USB driver missing or board not in upload mode | Install the CP210x or CH340 driver. Or hold BOOT, press RESET, then release BOOT and upload again |
| Upload fails or board does not boot | The servo signal on D9 (GPIO46) affects the boot strapping pin | Unplug the servo signal wire from D9 during upload, then plug it back in |
| Compile error "Servo.h - No such file" | The code uses the AVR Servo library | Install the ESP32Servo library and use #include |
| Servo does not move at all | Wrong wiring or no power to the servo | Check that red goes to 5V, brown to GND and the signal wire to D9 |
| Servo does not move with external power | The external supply GND is not joined to the board GND | Connect the supply GND to the ESP32 S3 Uno GND |
| Servo jitters or the board resets | The servo draws too much current from USB | Power the servo from an external 5V supply and join the GNDs |
| Servo hums at the end of its range | The servo hits its mechanical limit | Use a smaller angle range, for example 10 to 170 degrees |