Understanding Pulse Width Modulation for Servo Control on Raspberry Pi

Micro Servo Motor with Raspberry Pi / Visits:27

Micro servo motors have revolutionized the world of hobbyist electronics, robotics, and prototyping. These compact, powerful, and precise devices are the muscle behind robotic arms, camera gimbals, automated plant waterers, and countless DIY projects. At the heart of commanding these tiny workhorses lies a critical concept: Pulse Width Modulation (PWM). When paired with a versatile single-board computer like the Raspberry Pi, PWM transforms from a textbook theory into a practical tool for dynamic control. This guide will unravel the intricacies of PWM specifically for micro servo control, providing you with the knowledge to bring precise motion to your Raspberry Pi projects.

The Micro Servo: A Marvel in Miniature

Before we decode the signal, let's understand the actuator. A standard micro servo, such as the ubiquitous SG90, is a self-contained module with a DC motor, a gear train, a control circuit, and a potentiometer for position feedback. Unlike a standard DC motor that spins continuously, a servo motor is designed to move to and hold a specific angular position.

Key Characteristics of a Micro Servo: * Voltage Range: Typically operates between 4.8V and 6.8V. A 5V supply is standard. * Torque: Modest but sufficient for small tasks (e.g., SG90 provides ~1.8 kg-cm at 5V). * Movement Range: Usually 180 degrees, though some offer 270 or 360 degrees of rotation. * Three-Wire Interface: * Power (VCC - Red/Orange): Connects to a 5V source. * Ground (GND - Brown/Black): Common ground with the Raspberry Pi. * Signal (PWM - Yellow/White): The crucial control pin where we apply our PWM signal.

The magic is in that signal wire. The servo's internal control circuit continuously compares the incoming PWM signal's characteristic with the feedback from its internal potentiometer (which tells it the current shaft position). It then drives the motor in the direction needed to match them.

Demystifying Pulse Width Modulation (PWM)

PWM is not about varying the voltage level, like turning a dial on a power supply. Instead, it's a method of simulating an analog signal using a digital output by rapidly switching it on and off.

The Core Components of a PWM Signal

Imagine blinking a flashlight very fast. The brightness you perceive isn't just "on" or "off"; it's an average based on how long it's on versus off during each cycle. PWM works the same way.

  1. Frequency (or Period): How often the signal repeats. It's measured in Hertz (Hz). For servos, this is standardized at 50 Hz, meaning the signal repeats 50 times per second (a period of 20 milliseconds).
  2. Duty Cycle: The percentage of one period where the signal is "ON" (high). A 50% duty cycle means the signal is high for half the period and low for the other half.
  3. Pulse Width: The absolute duration of the "ON" time within a single period. This is the parameter we directly control to command a servo. It's measured in milliseconds (ms).

For servo control, it's the pulse width that matters, not the duty cycle percentage. The standard range for a 180-degree servo is a pulse width between 1.0 ms (full counter-clockwise) and 2.0 ms (full clockwise), with 1.5 ms typically representing the neutral (center) position.

A Single 20ms Period (50Hz) for Servo Control: |---------------------- Period (20ms) ----------------------| |--- Pulse Width (1.0-2.0ms) ---| |ON | | | |___| |____________________________| ^ ^ Start of Period End of Period (Determines Servo Position)

Why PWM for Servos?

PWM is ideal for servos because it's a robust, noise-resistant digital signal that carries precise analog-like information (position) in the time domain. The servo expects this specific "language" of timed pulses to understand its target position.

Hardware Setup: Connecting Servo to Raspberry Pi

Warning: A micro servo can draw significant current, especially when under load or starting up. Never power a servo directly from the Raspberry Pi's 5V pin. Use an external 5V power supply (like a UBEC or a dedicated bench supply) for the servo.

Safe Wiring Configuration

  1. Servo VCC -> External 5V Supply Positive
  2. Servo GND -> External 5V Supply Negative AND Raspberry Pi GND (This creates a common ground, which is essential).
  3. Servo Signal -> Raspberry Pi GPIO Pin (e.g., GPIO18, which is hardware PWM-capable on many models).

A capacitor (e.g., 100µF electrolytic) across the servo power pins (observing polarity) is highly recommended to smooth out voltage spikes and protect your circuit.

Software Implementation: Generating PWM on Raspberry Pi

The Raspberry Pi can generate PWM signals in two primary ways: via hardware PWM and software-timed PWM. The choice depends on your precision needs and available GPIO pins.

Method 1: Using Hardware PWM Pins

The Raspberry Pi has a limited number of dedicated hardware PWM channels (on the 40-pin models, GPIO12, GPIO13, GPIO18, and GPIO19). Hardware PWM is generated by the chip itself, offering very stable and precise timing with minimal CPU overhead.

Example using the pigpio library (highly recommended for servo control):

python import pigpio import time

Connect to the local Pi

pi = pigpio.pi()

if not pi.connected: exit()

SERVO_PIN = 18 # Hardware PWM pin

Set the PWM frequency to 50Hz for servos

pi.setPWMfrequency(SERVO_PIN, 50)

Define pulse width range (1000µs to 2000µs)

MINPULSE = 1000 MAXPULSE = 2000

def setangle(angle): # Convert angle (0-180) to pulse width (1000-2000) pulse = MINPULSE + (angle / 180.0) * (MAXPULSE - MINPULSE) pi.setservopulsewidth(SERVO_PIN, pulse) print(f"Angle: {angle}°, Pulse: {pulse}µs") time.sleep(0.5) # Allow servo to move

Sweep from 0 to 180 degrees

for angle in range(0, 181, 45): set_angle(angle)

Return to center

set_angle(90)

Clean up

pi.setservopulsewidth(SERVO_PIN, 0) # Turns servo signal off pi.stop()

Method 2: Using Software-Timed PWM (Any GPIO)

For pins without hardware PWM support, you can use software libraries that generate the signal by timing GPIO highs and lows in the operating system. This is more flexible but can be slightly less precise and consumes more CPU.

Example using RPi.GPIO library:

python import RPi.GPIO as GPIO import time

GPIO.setmode(GPIO.BCM) SERVO_PIN = 17 # Can be any GPIO

GPIO.setup(SERVO_PIN, GPIO.OUT)

Create a PWM instance with 50Hz frequency

pwm = GPIO.PWM(SERVO_PIN, 50)

Start the PWM with a duty cycle for the neutral position (1.5ms pulse)

Duty Cycle for 1.5ms at 50Hz = (1.5 / 20) * 100 = 7.5%

pwm.start(7.5)

try: while True: # Move to 0 degrees (1ms pulse ~ 5% duty cycle) pwm.ChangeDutyCycle(5) time.sleep(1) # Move to 180 degrees (2ms pulse ~ 10% duty cycle) pwm.ChangeDutyCycle(10) time.sleep(1) # Move to 90 degrees (1.5ms pulse ~ 7.5% duty cycle) pwm.ChangeDutyCycle(7.5) time.sleep(1) except KeyboardInterrupt: pwm.stop() GPIO.cleanup()

Advanced Techniques and Calibration

The Necessity of Servo Calibration

Not all servos are created equal. Manufacturing tolerances mean the pulse width needed for exactly 0 or 180 degrees can vary. You may find your servo's effective range is from 1.1 ms to 1.9 ms.

Simple Calibration Routine: Write a script that slowly increments the pulse width and observe the servo's movement. Note the pulse values where it just starts to move and where it reaches its mechanical limit. Use these as your new MIN_PULSE and MAX_PULSE constants.

Managing Multiple Servos

Controlling multiple servos requires careful planning. * Hardware PWM: The Pi has only two independent hardware PWM channels (which can be mapped to a few pins each). You can run two servos with perfect timing this way. * Software PWM: Libraries like pigpio can handle multiple software servos on any pin quite reliably by using hardware timing peripherals (like the DMA controller), making it the best choice for multi-servo projects like robot arms or hexapods.

Reducing Jitter and Improving Stability

Servo jitter (small, nervous movements) is a common issue. * Power Supply Noise: Ensure your external 5V supply is clean and capable of supplying ample current (2A per servo is a safe budget for small projects). * Software Timing: Use a hardware-based library like pigpio over pure software timing (RPi.GPIO). * Physical Damping: Sometimes, adding a small capacitor (0.1µF ceramic) between the signal pin and ground on the servo can help filter noise. * Avoid time.sleep() in Complex Code: In event-driven programs, long sleep() calls can block other processes. Consider using threading or callbacks for smooth operation.

Practical Project: A Programmable Camera Pan-Tilt

Let's apply this knowledge to a classic project: a Raspberry Pi-controlled pan-tilt mechanism using two micro servos.

Components: * Raspberry Pi (any model with 40-pin GPIO) * 2x Micro Servos (e.g., SG90s) * Pan-Tilt Bracket Kit * External 5V/3A Power Supply * Jumper Wires & Capacitors

Wiring: * Servo 1 (Tilt): Signal -> GPIO18 * Servo 2 (Pan): Signal -> GPIO19 * Both Servo VCC -> External 5V+ * Both Servo GND -> External 5V- & Pi GND

Code Snippet (using pigpio):

python import pigpio import time

pi = pigpio.pi()

PANPIN = 19 TILTPIN = 18

pi.setPWMfrequency(PANPIN, 50) pi.setPWMfrequency(TILTPIN, 50)

def setservo(pin, angle): pulse = 1000 + (angle / 180.0) * 1000 pi.setservo_pulsewidth(pin, pulse)

Simple scan pattern

try: while True: for panangle in range(30, 151, 30): setservo(PANPIN, panangle) time.sleep(0.7) for tiltangle in [45, 90, 135]: setservo(TILTPIN, tiltangle) time.sleep(0.5) except KeyboardInterrupt: pi.setservopulsewidth(PANPIN, 0) pi.setservopulsewidth(TILTPIN, 0) pi.stop()

This project encapsulates the core principles: independent PWM control on two channels, coordinated movement, and proper cleanup. From here, you could integrate a camera module and create an automated surveillance system or a time-lapse rig with dynamic motion.

Copyright Statement:

Author: Micro Servo Motor

Link: https://microservomotor.com/micro-servo-motor-with-raspberry-pi/pwm-servo-control-raspberry-pi.htm

Source: Micro Servo Motor

The copyright of this article belongs to the author. Reproduction is not allowed without permission.

About Us

Lucas Bennett avatar
Lucas Bennett
Welcome to my blog!

Tags