0
0
Iot-protocolsProgramBeginner · 2 min read

Raspberry Pi Program to Control Servo Motor with Python

Use the RPi.GPIO library to control a servo motor on Raspberry Pi by setting up PWM on a GPIO pin and changing the duty cycle with code like pwm.ChangeDutyCycle(duty) to move the servo.
📋

Examples

InputSet servo angle to 0 degrees
OutputServo moves to 0 degrees position
InputSet servo angle to 90 degrees
OutputServo moves to 90 degrees position
InputSet servo angle to 180 degrees
OutputServo moves to 180 degrees position
🧠

How to Think About It

To control a servo motor with Raspberry Pi, you first connect the servo's control wire to a GPIO pin. Then you use PWM (Pulse Width Modulation) signals to tell the servo what angle to move to. The PWM duty cycle corresponds to the servo angle. You write a program that sets up the GPIO pin for PWM, starts the PWM signal, and changes the duty cycle to move the servo to desired angles.
📐

Algorithm

1
Import the GPIO library and time module
2
Set GPIO mode and configure the servo pin as output
3
Start PWM on the servo pin with 50Hz frequency
4
Define a function to convert angle to duty cycle
5
Use the function to set servo angle by changing PWM duty cycle
6
Clean up GPIO after use
💻

Code

raspberry_pi
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
servo_pin = 18
GPIO.setup(servo_pin, GPIO.OUT)

pwm = GPIO.PWM(servo_pin, 50)  # 50Hz frequency
pwm.start(0)

def set_angle(angle):
    duty = 2 + (angle / 18)
    pwm.ChangeDutyCycle(duty)
    time.sleep(0.5)
    pwm.ChangeDutyCycle(0)

try:
    for angle in [0, 90, 180]:
        print(f"Moving servo to {angle} degrees")
        set_angle(angle)
        time.sleep(1)
finally:
    pwm.stop()
    GPIO.cleanup()
    print("Servo control finished")
Output
Moving servo to 0 degrees Moving servo to 90 degrees Moving servo to 180 degrees Servo control finished
🔍

Dry Run

Let's trace moving the servo to 90 degrees through the code

1

Calculate duty cycle

angle = 90; duty = 2 + (90 / 18) = 7.0

2

Change PWM duty cycle

pwm.ChangeDutyCycle(7.0)

3

Wait for servo to move

time.sleep(0.5)

4

Stop PWM signal

pwm.ChangeDutyCycle(0)

StepAngleDuty CyclePWM Duty Cycle
1907.0N/A
2907.07.0
3907.07.0
4907.00
💡

Why This Works

Step 1: Setup GPIO and PWM

We use GPIO.setmode(GPIO.BCM) to select pin numbering and set the servo pin as output. Then we start PWM at 50Hz because servos expect 50 pulses per second.

Step 2: Convert angle to duty cycle

The servo angle is converted to a PWM duty cycle between 2 and 12 percent using duty = 2 + (angle / 18). This matches the servo's expected pulse width range.

Step 3: Send PWM signal to servo

We change the PWM duty cycle to move the servo, wait 0.5 seconds for the servo to reach the position, then stop the signal to avoid jitter.

Step 4: Cleanup

After moving the servo, we stop PWM and clean up GPIO to free resources and avoid warnings on next run.

🔄

Alternative Approaches

Using pigpio library
raspberry_pi
import pigpio
import time

pi = pigpio.pi()
servo_pin = 18

try:
    for angle in [0, 90, 180]:
        pulse_width = 500 + (angle * 2000 // 180)  # 500-2500 microseconds
        print(f"Moving servo to {angle} degrees")
        pi.set_servo_pulsewidth(servo_pin, pulse_width)
        time.sleep(1)
finally:
    pi.set_servo_pulsewidth(servo_pin, 0)
    pi.stop()
    print("Servo control finished")
pigpio offers more precise PWM control and runs as a daemon, but requires installing and running pigpio service.
Using gpiozero library
raspberry_pi
from gpiozero import Servo
from time import sleep

servo = Servo(18)

for position in [-1, 0, 1]:  # -1 is 0°, 0 is 90°, 1 is 180°
    print(f"Moving servo to position {position}")
    servo.value = position
    sleep(1)

print("Servo control finished")
gpiozero simplifies servo control with abstracted positions but uses a different scale (-1 to 1) instead of degrees.

Complexity: O(n) time, O(1) space

Time Complexity

The program runs a loop over n angles to move the servo, so time complexity is O(n). Each movement waits a fixed time for the servo to reach position.

Space Complexity

The program uses a fixed amount of memory for variables and GPIO setup, so space complexity is O(1).

Which Approach is Fastest?

All approaches have similar time complexity; pigpio may offer smoother control but requires extra setup. gpiozero is easiest but less flexible.

ApproachTimeSpaceBest For
RPi.GPIO PWMO(n)O(1)Basic servo control with standard library
pigpio libraryO(n)O(1)Precise PWM control, better for complex projects
gpiozero libraryO(n)O(1)Simple and quick servo control with abstraction
💡
Always use a separate power supply for the servo to avoid damaging your Raspberry Pi.
⚠️
Beginners often forget to stop PWM or clean up GPIO pins, causing warnings or unexpected behavior on next runs.