ESP32 UNO - Motion Sensor - Servo Motor
Need a servo arm that reacts when a person walks past? Hook an HC-SR501 PIR motion sensor and a hobby servo to the ESP32 Uno form board, and the arm swings by itself. The PIR sensor spots body heat, and the servo moves between 0 and 90 degrees as the motion starts and ends. Use the build for a pet gate, a moving camera mount or a small robot arm.
What you will do:
- Wire a PIR motion sensor and a servo to the ESP32 Uno
- Tune the HC-SR501 time delay, range and trigger jumper
- Catch the moment the sensor output changes with digitalRead()
- Drive the servo angle with the ESP32Servo library

Hardware Preparation
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.
Meet the Two Parts
After this part, you know the job of each part in the build.
| Part | Role in This Build | Signal |
|---|---|---|
| HC-SR501 PIR sensor | Input. Senses infrared heat from a moving body | OUT pin, HIGH or LOW |
| Servo motor | Output. Turns its horn to a set angle from 0 to 180 degrees | PWM pulse on one wire |
For the full pinout and basics of each part, open its own page:
ESP32 Uno Pinout
Your sketch talks to GPIO numbers, while the board labels show Uno names like D2 and D9. Look up both in the picture below before you plug in a wire.

How to Connect
At the end of this part, the sensor and the servo share power and each has its own signal pin.

This image is created using Fritzing. Click to enlarge image
| Component Pin | ESP32 Uno Pin |
|---|---|
| Motion Sensor VCC | 5V |
| Motion Sensor OUT | D2 (GPIO26) |
| Motion Sensor GND | GND |
| Servo VCC (red wire) | 5V |
| Servo GND (brown or black wire) | GND |
| Servo Signal (orange or yellow wire) | D9 (GPIO13) |
Good to know: the HC-SR501 takes 5V power, yet its OUT pin swings only to about 3.3V, so D2 (GPIO26) can read it directly with no level shifter.
※ NOTE THAT:
ESP32 Uno pins use 3.3V logic and are NOT 5V tolerant. Here no 5V signal reaches a board pin: the servo gets 5V on its red wire, but its signal wire only listens to the 3.3V pulse from D9 (GPIO13). Almost every hobby servo accepts that pulse.
Sensor Setup
Set the two screws and the jumper once, and the sensor reacts fast with its widest reach.
| Time Delay Adjuster | Rotate it all the way anti-clockwise. |
| Detection Range Adjuster | Rotate it all the way clockwise. |
| Repeat Trigger Selector | Set the jumper to match the picture. |

ESP32 Uno Code - PIR Sensor Moves the Servo
This sketch watches D2 (GPIO26) for a change in the sensor output, prints a line, and sets the servo on D9 (GPIO13) to 90 or 0 degrees.
Good to know: the classic Servo.h library does not build for the ESP32 Uno. The sketch includes ESP32Servo.h instead, which keeps the same attach() and write() calls.
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).
- Add the servo library. In the Library Manager, type ESP32Servo and install the release by Kevin Harrington.
- Paste the sketch into a new Arduino IDE window.
- Click Upload and wait for "Done uploading".
- Open the Serial Monitor and set it to 9600 baud.
- Walk past the sensor about one meter away, then stand still.
- Watch the servo horn swing and read the lines in the Serial Monitor.
- Pro tip: tape a paper flag to the servo horn. The bigger arm makes each move easy to see from across the room while you test the range screw.
Video: Motion-Activated Door
See the ESP32 Uno build in action in the video below.
The end of the video shows an automatic door: a servo opens it and a buzzer beeps when someone comes close. Here is that sketch for the ESP32 Uno.
| Part | ESP32 Uno Pin |
|---|---|
| Motion Sensor OUT | D2 (GPIO26) |
| Door Servo Signal | D5 (GPIO16) |
| Buzzer | D6 (GPIO27) |
When someone arrives, the servo opens to 180 degrees and the buzzer gives two short beeps. When the area is clear, the door swings back to 0 degrees with two more beeps.
Code Explanation
| Code Part | What It Does |
|---|---|
| #include | Loads the servo library made for the ESP32 Uno PWM hardware |
| MOTION_SENSOR_PIN 26 and SERVO_PIN 13 | Name the GPIO numbers behind D2 and D9 |
| servo.attach(SERVO_PIN) | Starts the PWM signal for the servo on GPIO13 |
| prev_motion_state and motion_state | Hold the old and the new sensor reading |
| if / else if checks | Run only when the reading changes, then print a line and call servo.write() |
Because the sketch reacts only to a change, the servo moves once per event and stays still in between.
ESP32 Uno vs UNO R4 for This Project
Moving this build from the UNO R4 to the ESP32 Uno changes the library line and the pin numbers in code.
| Item | Arduino UNO R4 | ESP32 Uno |
|---|---|---|
| Logic voltage | 5V | 3.3V |
| Sensor pin in code | 2 | 26 (D2) |
| Servo pin in code | 9 | 13 (D9) |
| Servo library | Servo.h | ESP32Servo.h |
| WiFi and Bluetooth | WiFi model only | WiFi plus Bluetooth Classic and BLE |
| Arduino IDE board | Arduino UNO R4 WiFi | ESP32 Dev Module |
The same wiring works as-is, because the wires stay on D2, D9, 5V and GND. Only change the two pin numbers and the include line.
Go Wireless: Remote Servo Override
After this part, you have an idea for a phone control on top of the sensor.
The ESP32 Uno has WiFi and Bluetooth built in. Keep the PIR sensor as the automatic trigger, and add a slider or a rotator on your phone to open the gate by hand. This helps when a visitor stands too still for the sensor to see.
Try These Next
- Hold the servo at 90 degrees for 5 seconds after the last motion, then close it.
- Sweep the servo slowly with a for loop instead of one big jump.
- Add an LED on another pin that lights while the servo is open.
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No COM port appears in Arduino IDE | CH340 driver missing or a charge-only USB cable | Install the CH340 driver and use a USB cable that carries data |
| Upload stops at "Failed to connect" or "Waiting for download" | Board did not enter upload mode | Hold the BOOT button while the upload starts, then release it |
| Error "Servo.h - No such file or directory" | The sketch still uses the AVR servo library | Install ESP32Servo and include ESP32Servo.h |
| Servo never moves | Signal wire on the wrong pin, or no 5V on the red wire | Put the signal on D9 (GPIO13) and check 5V and GND |
| Servo buzzes or the board restarts when it moves | USB port cannot give enough current | Feed the servo from a separate 5V supply and join its GND with the board GND |
| Sensor reacts with nobody in front | The PIR is still warming up, or a heat source is nearby | Wait one minute after power-up and aim it away from heaters and sunny windows |
| Servo moves late or stays open long | Time delay screw turned up | Turn the time delay screw fully anti-clockwise |
| Messages appear but look like random symbols | Serial Monitor baud does not match | Set the Serial Monitor to 9600 baud |
FAQ
How far away can the HC-SR501 notice a person?
Up to about 7 meters with the range screw turned fully clockwise. The view angle is about 110 degrees. Turn the screw the other way to shrink the reach to about 3 meters.
Do I need a resistor between the PIR OUT pin and D2?
No. The OUT pin gives about 3.3V when HIGH, which is a safe level for the ESP32 Uno input. You can wire it straight to D2 (GPIO26).
Can the 5V header pin power both the servo and the sensor?
Yes, for one small servo like the SG90. The 5V pin takes its power from USB. A bigger servo or two servos need an external 5V supply with a shared GND.
Will my old UNO R4 sketch run on the ESP32 Uno without changes?
Not quite. Change Servo.h to ESP32Servo.h and use the GPIO numbers 26 and 13 instead of 2 and 9. The rest of the logic stays the same.
Can I plug Uno shields into the ESP32 Uno for this build?
Many shields fit the headers, but the board runs at 3.3V logic. Check that the shield does not push a 5V signal into a board pin. Also note that A4 and A5 are not I2C on this board.
Which Arduino IDE setting do I use to upload to the ESP32 Uno?
Install the "esp32 by Espressif Systems" core, then pick ESP32 Dev Module and the CH340 COM port. The board uses a CH340 USB chip, so Windows may need its driver first.
How do I change how far the servo turns?
Edit the numbers inside servo.write(). For example, write servo.write(120) to open wider. Keep the value between 0 and 180.
Can I add a second servo that moves at the same time?
Yes. Create a second Servo object, attach it to another PWM pin such as D3 (GPIO25), and call write() on both in the same if block.
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 (I/O, PWM, analog on ADC1, so they also work while WiFi is on) and GPIO15 (I/O, PWM, analog on ADC2). Solder pin headers to them and write the GPIO number in code. For this build, GPIO32 or GPIO33 is a good place for a second PIR sensor or another servo. Two warnings: GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC spot) are boot strapping pins, and a wrong connection can stop the board from booting or uploading, so use GPIO32/33 first. Never use the six holes under the digital header (SD0 to SD3, CMD, CLK = GPIO6 to GPIO11). They connect to the flash chip, and using them crashes the board.
Can I get a phone alert when the sensor sees someone?
Yes. The ESP32 Uno has WiFi and Bluetooth, so you can send the motion state to a web page or a phone app. Start with one of the links in the Go Wireless section.