ESP32 UNO - Servo Motor
How do you turn a servo arm to an exact angle with the ESP32 Uno? Plug a hobby servo into the ESP32 Uno form board, add the ESP32Servo library, and a few lines of Arduino code give you full control of the servo motor position and speed.
By the end, you can:
- Wire a servo motor to the ESP32 Uno
- Move the arm with servo.write() from 0° to 180°
- Slow the movement down without blocking the loop
- Power the servo from an external supply

Components You Need
| 1 | × | ESP32 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.
Servo Motor Basics
By the end of this part, you know what the three servo wires do.
A hobby servo holds a shaft at the angle you ask for. Most models turn from 0° to 180°, which suits robot arms, small gates, pan-tilt mounts and pointers.
Pinout
| Servo Wire | Color | Job |
|---|---|---|
| VCC | Red | Power input, 5V |
| GND | Black or brown | Ground, 0V |
| Signal | Yellow or orange | Receives the PWM control signal from an ESP32 Uno pin |

Good to know: the signal wire accepts the 3.3V pulses of the ESP32 Uno, so no level shifter is needed.
ESP32 Uno Pinout
Every Uno header pin of the ESP32 Uno form board has a GPIO number, and your sketch uses that number. Match the labels in the diagram before you plug in any wire.

How to Connect
By the end of this part, the servo is wired and powered in a safe way.
Many online diagrams feed the servo VCC from the 5V pin of the board. A moving servo can pull a lot of current, and that can reset the ESP32 Uno or stress the USB port. Use the external supply wiring below when you can.

This image is created using Fritzing. Click to enlarge image
| Servo Pin | ESP32 Uno Pin |
|---|---|
| VCC (red) | 5V |
| GND (black or brown) | GND |
| Signal (yellow or orange) | D9 (GPIO13) |
Now the safer wiring with an external supply. Connect the servo VCC to the + of the supply and the servo GND to the - of the supply. Keep the signal wire on D9 (GPIO13).

This image is created using Fritzing. Click to enlarge image
WARNING
Join the GND of the external supply to a GND pin of the ESP32 Uno. Without this shared ground the signal has no reference and the servo jitters or does not move.
Good to know: the ESP32 Uno pins are 3.3V logic and are not 5V tolerant. The servo signal goes out of the board, so this is safe here.
Servo Programming in Four Lines
By the end of this part, you know the four calls that every servo sketch needs.
Step 1 — Include the library
Step 2 — Create a Servo object
For more than one servo, declare more objects.
Step 3 — Attach the signal pin
Tell the object which GPIO carries the signal. D9 is GPIO13 on this board.
Step 4 — Write an angle
Send the arm to the position you want, for example 90 degrees.
ESP32 Uno Servo Sweep Code
This sketch sweeps the arm from 0° to 180° and back again, one degree every 10 ms.
| Code Part | What It Does |
|---|---|
| #include | Loads the servo library made for the ESP32 Uno |
| servo.attach(13) | Links the servo object to GPIO13 (D9) |
| servo.write(pos) | Moves the arm to pos degrees |
| First for loop | Counts pos from 0 to 180 to turn the arm up |
| Second for loop | Counts pos from 180 to 0 to turn the arm back |
| delay(10) | Sets the sweep speed, about 1.8 seconds per direction |
The arm now moves slowly in both directions without stopping.
Upload and Test
- First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
- Build the circuit by following the wiring table above.
- Plug in the USB Type-C cable between the ESP32 Uno and your computer.
- Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
- Install the library: open the Library Manager, search for ESP32Servo by Kevin Harrington and click Install.
- Copy the code above into a new Arduino IDE sketch.
- Click Upload to send the code to the ESP32 Uno.

- Watch the arm: it turns slowly from 0° to 180° and then slowly back to 0°.
- Pro tip: fix a small piece of tape on the servo horn. It makes the movement much easier to see from a distance.
Video Tutorial
See the ESP32 Uno build in action in the video below. The demo moves the servo when an ultrasonic sensor sees an object.
WARNING
The demo sketch uses D8 (GPIO12) as the trigger pin. GPIO12 is a boot strapping pin, so unplug the trigger wire while you upload. Most ultrasonic sensors answer with a 5V echo pulse, so lower it to 3.3V with a voltage divider before it reaches D7 (GPIO14).
How to Control the Speed of a Servo Motor
By the end of this part, the servo moves from one angle to another in a time you choose, and the loop stays free for other work.
The sketch maps elapsed time to an angle with map() and millis(). No delay() blocks the code.
| Value | Effect |
|---|---|
| MOVING_TIME | Total time of the move in milliseconds, 3000 means 3 seconds |
| startAngle | Where the arm begins |
| stopAngle | Where the arm ends |
| map() | Converts the elapsed time into a matching angle |
Change MOVING_TIME to make the move faster or slower.
ESP32 Uno vs UNO R4 for This Project
By the end of this part, you know what changes when you move this servo project from the UNO R4 to the ESP32 Uno.
| Item | Arduino UNO R4 | ESP32 Uno |
|---|---|---|
| Logic voltage | 5V | 3.3V |
| Servo signal pin | D9 | D9 (GPIO13) |
| Servo library | Servo.h | ESP32Servo.h |
| Pin number in code | 9 | 13 |
| Wireless | WiFi on the WiFi model only | WiFi and Bluetooth built in |
| Arduino IDE board | Arduino UNO R4 WiFi | ESP32 Dev Module |
The wiring stays the same, and only the library and the pin number in the code change. The servo is powered from 5V, so keep the separate supply for bigger servos.
Go Wireless: Servo From Your Phone
By the end of this part, you know how to move the servo without touching the board.
The ESP32 Uno has WiFi and Bluetooth, so you can send the angle from a phone. A slider on a web page or in a Bluetooth app can set the angle, and a rotator widget can show the arm position.
Function References
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No COM port appears | CH340 driver missing or a charge-only USB cable | Install the CH340 driver and use a data USB cable |
| Upload says Failed to connect or Waiting for download | The board did not enter download mode | Hold the BOOT button while the upload starts |
| Servo does not move at all | Signal wire on the wrong pin or no power | Check that the signal wire is on D9 (GPIO13) and VCC has 5V |
| Servo jitters or twitches | Weak power or no shared ground | Use an external supply and join its GND to the ESP32 Uno GND |
| Board resets when the servo moves | The servo pulls too much current from USB | Power the servo from an external 5V supply |
| Error Servo.h not found or wrong board | The AVR Servo library does not support this board | Install ESP32Servo and use #include |
| Arm hits the end and buzzes | Angle outside the real range of the servo | Keep angles between 0 and 180 or use a smaller range |
| Servo is hot | It pushes against a stop or a load | Free the arm and check the angle limits |
| Wrong speed in the speed sketch | MOVING_TIME value not what you expect | Set MOVING_TIME in milliseconds, 3000 is 3 seconds |
| Board does not boot with the demo sensor wired | The trigger wire on D8 (GPIO12) is a boot strapping pin | Unplug the module while uploading, then plug it in again |
FAQ
How does a servo motor know which angle to go to?
It reads the width of a repeating PWM pulse on the signal wire. A short pulse means 0° and a long pulse means 180°. The ESP32Servo library makes this pulse for you.
Can I power a servo from the 5V pin of the ESP32 Uno?
A tiny servo with no load can work from 5V, but it may reset the board when it starts or stalls. An external 5V supply with a shared GND is the safe choice.
Do I need a level shifter for the servo signal?
No. The signal flows from the ESP32 Uno to the servo, and servos read a 3.3V pulse as HIGH. Only 5V signals going into a pin need a shifter.
Why do I use ESP32Servo and not Servo.h?
The standard Servo library is written for AVR and Renesas chips. ESP32Servo uses the PWM hardware of this board and has the same calls, so only the include line changes.
Which GPIO number do I use for D9?
D9 on the ESP32 Uno is GPIO13, so write servo.attach(13). Never write D9 in the code.
How can I run two or more servos?
Create one Servo object for each servo and attach each one to a different PWM-capable pin, for example D9 (GPIO13) and D6 (GPIO27). Power them from an external supply.
Can I use the input-only pins A2 to A5 for the servo signal?
No. Those pins (GPIO35, 34, 36, 39) are input only and cannot send the PWM pulse. Use a pin such as D9 (GPIO13).
How do I change the sweep speed?
Change the delay(10) value in the sweep sketch, or change MOVING_TIME in the speed sketch. A bigger number gives a slower move.
What does the UNO R4 code need to change for the ESP32 Uno?
Replace #include <Servo.h> with #include <ESP32Servo.h> and use GPIO13 for D9. Everything else in the sweep sketch stays the same.
Can I control the servo from my phone with the ESP32 Uno?
Yes. The board has WiFi and Bluetooth, so a web slider or a Bluetooth slider app can set the angle. See the Go Wireless section for links.
What if my project needs more pins than the Uno headers give?
The ESP32 Uno has a few extra holes near the power header. GPIO32 and GPIO33 are I/O, PWM and analog on ADC1, so they also work while WiFi is on. GPIO15 is I/O, PWM and analog on ADC2. Solder pin headers to use them and write the GPIO number in code. For a second servo, GPIO32 or GPIO33 is a good choice. GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC position) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code, so use GPIO32/33 first. Never use the six holes under the digital header (SD0–SD3, CMD, CLK = GPIO6–GPIO11), because they are wired to the flash chip and using them crashes the board.