Python Reference
Servo 9G
9G Micro Servo Motor
Wiring:
| Servo Wire Colour | Connect To |
|---|---|
| Red | 5V |
| Brown or Black | GND |
| Orange or Yellow (signal) | GPIO 13 |
{: .note } Servos can draw significant current when moving under load. If your ESP32 resets when the servo moves, power the servo from a separate 5V supply (keep GND connected to the ESP32's GND).
How PWM works for servos: Send a 50Hz signal. The pulse width (time the signal is HIGH) sets the angle: - 0.5ms pulse ≈ 0° - 1.5ms pulse ≈ 90° (centre) - 2.5ms pulse ≈ 180°
Code:
from machine import Pin, PWM
import time
servo = PWM(Pin(13), freq=50)
def set_angle(angle):
"""Move servo to angle (0–180 degrees)."""
# Map 0–180° to duty cycle 40–115 (0–1023 range, 50Hz)
# Adjust these values to calibrate your specific servo
min_duty = 40
max_duty = 115
duty = int(min_duty + (angle / 180) * (max_duty - min_duty))
servo.duty(duty)
# Move through positions
for angle in [0, 45, 90, 135, 180]:
set_angle(angle)
print(f"Angle: {angle}°")
time.sleep(1)
servo.deinit() # Release PWM when done
Calibrating your servo:
If 0° and 180° aren't quite right, adjust min_duty and max_duty. Try values between 30–50 for min and 110–130 for max.
Simpler example
import time
from machine import Pin,PWM
servo1 = PWM(Pin((13)), freq=50)
# Move to 90 degrees
servo1.duty(int(30 + (90 / 180) * (125 - 30)))
time.sleep(1)
# Move to 0 degrees
servo1.duty(int(30 + (0 / 180) * (125 - 30)))
time.sleep(1)
# Move to 180 degrees
servo1.duty(int(30 + (180 / 180) * (125 - 30)))
time.sleep(1)