Servo motors need special signals to move to the right position. PWM helps send these signals easily.
0
0
Servo motor control with PWM in Raspberry Pi
Introduction
You want to control the angle of a small robot arm.
You need to open or close a small door automatically.
You want to make a remote-controlled car steer.
You want to move a camera smoothly to look around.
Syntax
Raspberry Pi
import RPi.GPIO as GPIO import time pin_number = 12 # Define your pin number here GPIO.setmode(GPIO.BOARD) GPIO.setup(pin_number, GPIO.OUT) pwm = GPIO.PWM(pin_number, 50) # 50 Hz frequency pwm.start(7.5) # Start at middle position # To change angle: pwm.ChangeDutyCycle(new_duty_cycle) # When done: pwm.stop() GPIO.cleanup()
Use 50 Hz frequency because servo motors expect a 20 ms period signal.
Duty cycle controls the angle: usually between 2.5% (0°) and 12.5% (180°).
Examples
This example moves the servo to middle, then 0°, then 180° positions.
Raspberry Pi
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) GPIO.setup(12, GPIO.OUT) pwm = GPIO.PWM(12, 50) # 50 Hz pwm.start(7.5) # Middle position # Move to 0 degrees pwm.ChangeDutyCycle(2.5) time.sleep(1) # Move to 180 degrees pwm.ChangeDutyCycle(12.5) time.sleep(1) pwm.stop() GPIO.cleanup()
This example sweeps the servo through several angles smoothly.
Raspberry Pi
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) GPIO.setup(18, GPIO.OUT) pwm = GPIO.PWM(18, 50) pwm.start(0) for duty in [2.5, 5, 7.5, 10, 12.5]: pwm.ChangeDutyCycle(duty) time.sleep(0.5) pwm.stop() GPIO.cleanup()
Sample Program
This program moves the servo motor to 0°, 90°, and 180° positions with pauses and prints the current angle. It cleans up GPIO pins at the end.
Raspberry Pi
import RPi.GPIO as GPIO import time # Set up GPIO pin 11 for PWM GPIO.setmode(GPIO.BOARD) GPIO.setup(11, GPIO.OUT) # Create PWM instance at 50 Hz servo = GPIO.PWM(11, 50) # Start PWM with 0 duty cycle (servo off) servo.start(0) try: # Move servo to 0 degrees servo.ChangeDutyCycle(2.5) print("Servo at 0 degrees") time.sleep(1) # Move servo to 90 degrees servo.ChangeDutyCycle(7.5) print("Servo at 90 degrees") time.sleep(1) # Move servo to 180 degrees servo.ChangeDutyCycle(12.5) print("Servo at 180 degrees") time.sleep(1) finally: # Stop PWM and clean up servo.stop() GPIO.cleanup() print("Cleaned up GPIO")
OutputSuccess
Important Notes
Always clean up GPIO pins after use to avoid warnings or errors next time.
Servo angles depend on the duty cycle; check your servo's datasheet for exact values.
Use delays after changing duty cycle to give the servo time to move.
Summary
Servo motors use PWM signals to set their angle.
Use 50 Hz frequency and adjust duty cycle between about 2.5% and 12.5% for 0° to 180°.
Always clean up GPIO pins after controlling the servo.