0
0
Iot-protocolsHow-ToBeginner · 4 min read

How to Control Servo Motor with Raspberry Pi: Simple Guide

To control a servo motor with a Raspberry Pi, use the RPi.GPIO library to send PWM signals to the servo's control pin. Set the PWM frequency to 50Hz and adjust the duty cycle to move the servo to the desired angle.
📐

Syntax

Use the RPi.GPIO library to set up PWM on a GPIO pin connected to the servo. The key steps are:

  • GPIO.setmode(GPIO.BCM): Use Broadcom pin numbering.
  • GPIO.setup(pin, GPIO.OUT): Set the pin as output.
  • pwm = GPIO.PWM(pin, frequency): Create PWM instance with 50Hz frequency.
  • pwm.start(duty_cycle): Start PWM with initial duty cycle.
  • pwm.ChangeDutyCycle(duty_cycle): Change servo angle by adjusting duty cycle.
  • pwm.stop() and GPIO.cleanup(): Stop PWM and clean GPIO settings.
python
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)  # Use BCM pin numbering
servo_pin = 18
GPIO.setup(servo_pin, GPIO.OUT)

pwm = GPIO.PWM(servo_pin, 50)  # 50Hz frequency for servo
pwm.start(7.5)  # Neutral position (90 degrees)

time.sleep(1)

pwm.ChangeDutyCycle(12.5)  # Move to 180 degrees

time.sleep(1)

pwm.stop()
GPIO.cleanup()
💻

Example

This example shows how to sweep a servo motor from 0 to 180 degrees and back using Raspberry Pi GPIO pin 18. It uses PWM signals with duty cycles mapped to servo angles.

python
import RPi.GPIO as GPIO
import time

def angle_to_duty_cycle(angle):
    # Map angle (0-180) to duty cycle (2.5-12.5)
    return 2.5 + (angle / 180.0) * 10

GPIO.setmode(GPIO.BCM)
servo_pin = 18
GPIO.setup(servo_pin, GPIO.OUT)
pwm = GPIO.PWM(servo_pin, 50)  # 50Hz
pwm.start(angle_to_duty_cycle(0))  # Start at 0 degrees

try:
    while True:
        for angle in range(0, 181, 10):
            duty = angle_to_duty_cycle(angle)
            pwm.ChangeDutyCycle(duty)
            time.sleep(0.3)
        for angle in range(180, -1, -10):
            duty = angle_to_duty_cycle(angle)
            pwm.ChangeDutyCycle(duty)
            time.sleep(0.3)
except KeyboardInterrupt:
    pass

pwm.stop()
GPIO.cleanup()
Output
No printed output; servo motor smoothly moves from 0° to 180° and back repeatedly until stopped.
⚠️

Common Pitfalls

Common mistakes when controlling servos with Raspberry Pi include:

  • Using incorrect GPIO pin numbering mode (BCM vs BOARD).
  • Setting PWM frequency other than 50Hz, which can cause erratic servo movement.
  • Not mapping servo angles correctly to duty cycle values (usually between 2.5% and 12.5%).
  • Failing to provide enough power to the servo, causing jitter or no movement.
  • Not cleaning up GPIO pins after use, which can cause warnings or errors on next run.
python
import RPi.GPIO as GPIO
import time

# Wrong: Using BOARD mode but specifying BCM pin number
GPIO.setmode(GPIO.BOARD)
servo_pin = 12  # BOARD pin 12 corresponds to BCM 18
GPIO.setup(servo_pin, GPIO.OUT)

# Correct way:
GPIO.setmode(GPIO.BCM)
servo_pin = 18
GPIO.setup(servo_pin, GPIO.OUT)
📊

Quick Reference

StepDescriptionExample Code
1Set GPIO mode to BCMGPIO.setmode(GPIO.BCM)
2Set servo pin as outputGPIO.setup(18, GPIO.OUT)
3Create PWM at 50Hzpwm = GPIO.PWM(18, 50)
4Start PWM with neutral duty cyclepwm.start(7.5)
5Change duty cycle to move servopwm.ChangeDutyCycle(12.5)
6Stop PWM and cleanuppwm.stop(); GPIO.cleanup()

Key Takeaways

Use 50Hz PWM frequency to control servo motors with Raspberry Pi.
Map servo angles (0-180°) to duty cycles between 2.5% and 12.5%.
Always set GPIO mode to BCM when using BCM pin numbers.
Provide stable power to the servo to avoid jitter.
Clean up GPIO pins after your program ends to prevent warnings.