How to Control Servo Motors Using Raspberry Pi and the WiringPi Library
Micro servo motors are the unsung heroes of the modern maker movement. From animating robot arms and DIY camera gimbals to controlling small valves in automated gardens, these compact, precise devices translate digital commands into physical movement. While the Arduino often gets the spotlight for servo control, the Raspberry Pi offers a powerful, Linux-based alternative, capable of integrating complex logic, computer vision, and internet connectivity into your projects. This guide dives deep into the art and science of controlling micro servos using a Raspberry Pi and the robust, if now legacy, WiringPi library.
Why the Raspberry Pi and Micro Servos Are a Perfect Match
The Raspberry Pi is more than just a small computer; it's a gateway to sophisticated physical computing. Unlike microcontrollers, the Pi runs a full operating system, allowing you to write programs in high-level languages like Python, C, or C++ while managing multiple processes. Micro servos, particularly the ubiquitous SG90, are ideal partners for the Pi. They are lightweight, require relatively low current (often under 500mA when moving, which a good 5V external supply can handle for a few servos), and provide a useful range of motion—typically 180 degrees.
The challenge, and the core of this tutorial, lies in the Raspberry Pi's lack of a true analog output. Servos are controlled not by voltage level, but by a Pulse Width Modulation (PWM) signal. This is where the WiringPi library shines. It provides a straightforward, C-based API to generate precise, timed pulses on the Pi's GPIO pins, abstracting away much of the complex low-level hardware interaction.
Understanding the Pulse: How Micro Servos Work
Before writing a single line of code, it's crucial to grasp the signal you need to generate. A standard micro servo like the SG90 expects a pulse every 20 milliseconds (a 50Hz frequency). The width of this pulse determines the servo's angular position.
- A 1.0 ms pulse typically drives the servo to its 0-degree position (full left or counter-clockwise, depending on model).
- A 1.5 ms pulse centers the servo at 90 degrees.
- A 2.0 ms pulse moves it to its 180-degree position (full right or clockwise).
It's a linear relationship: pulse width between 1.0ms and 2.0ms yields a proportional angle between 0 and 180 degrees. This pulse train must be consistent; the servo's internal circuitry constantly adjusts to match the received pulse width.
Setting Up Your Hardware and Software
Essential Components and Wiring
You will need: 1. A Raspberry Pi (any model with GPIO pins, tested here on a Pi 3B+). 2. A micro servo motor (SG90 or equivalent). 3. A 5V power supply (a dedicated UBEC or a stable 5V from a bench supply is best for more than one servo. Do not power a servo directly from the Pi's 5V pin for anything beyond light testing). 4. Jumper wires (female-to-male for connecting to the servo).
Critical Wiring Diagram: * Servo Yellow/Orange Wire (Signal): Connect to a GPIO pin on the Pi, e.g., GPIO 18 (Physical pin 12). This is the PWM control line. * Servo Red Wire (Power - 5V): Connect to your external 5V power supply's positive terminal. The Pi's ground and the external supply's ground must be connected. * Servo Brown/Black Wire (Ground): Connect to the common ground between the Pi and the external power supply.
Power Advisory: A moving servo can cause significant current spikes. These spikes can cause your Pi to brown-out and reset if powered from the same source. Always use a separate, regulated 5V supply for the servo(s), with the grounds tied together.
Installing and Configuring WiringPi
While WiringPi is deprecated for new projects, it remains a stable and excellent tool for learning precise timing control. It may already be installed on your Raspberry Pi OS (Legacy) image. To check and install:
bash
Check if WiringPi is installed and its version
gpio -v
If not installed, you can clone and build it from its archive
git clone https://github.com/WiringPi/WiringPi cd WiringPi ./build
The library includes both a command-line tool (gpio) and a C library (wiringPi). We will focus on using the C library for programmatic control.
Programming Servo Control in C with WiringPi
Let's write a C program that gives you complete control over your micro servo. We'll start with a basic example and build up to more complex movements.
Basic Code Structure: Initialization and Sweep
Create a file named servo_basic.c:
c
include <wiringPi.h> include <stdio.h> include <stdlib.h>
include <stdlib.h>
// Define our servo pin. We use WiringPi pin numbering. // WiringPi Pin 1 corresponds to BCM_GPIO 18.
define SERVO_PIN 1
// Constants for pulse timing (based on 100µs increments, common in WiringPi servo code) // These values are typical for a 180-degree servo. YOU MAY NEED TO CALIBRATE.
define PWM_FREQ 50 // Hz define PWM_RANGE 200 // This number times 100µs = 20ms period define MINPULSEWIDTH 10 // 10 * 100µs = 1.0ms (0 degrees) define MAXPULSEWIDTH 30 // 30 * 100µs = 2.0ms (180 degrees)
define MINPULSEWIDTH 10 // 10 * 100µs = 1.0ms (0 degrees) define MAXPULSEWIDTH 30 // 30 * 100µs = 2.0ms (180 degrees)
void setup() { if (wiringPiSetup() == -1) { printf("WiringPi setup failed!\n"); exit(1); }
pinMode(SERVO_PIN, PWM_OUTPUT); // Set the pin to PWM mode pwmSetMode(PWM_MODE_MS); // Use Mark-Space mode, which is correct for servos pwmSetRange(PWM_RANGE); pwmSetClock(192); // This clock divisor gives a 50Hz signal on Pi. (19.2MHz / (192 * 2000)) ~= 50Hz }
void setServoAngle(int angle) { // Constrain angle to 0-180 if (angle < 0) angle = 0; if (angle > 180) angle = 180;
// Map the angle (0-180) to the pulse width (MIN_PULSE_WIDTH - MAX_PULSE_WIDTH) int pulseWidth = MIN_PULSE_WIDTH + ((angle * (MAX_PULSE_WIDTH - MIN_PULSE_WIDTH)) / 180); pwmWrite(SERVO_PIN, pulseWidth); delay(100); // Give the servo time to move }
int main(void) { setup(); printf("Raspberry Pi Micro Servo Control Started.\n");
// Perform a smooth sweep from 0 to 180 degrees and back while (1) { for (int angle = 0; angle <= 180; angle += 5) { setServoAngle(angle); printf("Angle set to: %d degrees\n", angle); } for (int angle = 180; angle >= 0; angle -= 5) { setServoAngle(angle); printf("Angle set to: %d degrees\n", angle); } } return 0; }
To compile and run this program: bash gcc -o servo_basic servo_basic.c -lwiringPi sudo ./servo_basic Note: sudo is often required for accessing the GPIO hardware.
Calibration and Fine-Tuning Your Servo
Not all servos are created equal. The MIN_PULSE_WIDTH and MAX_PULSE_WIDTH values in the code are theoretical. Your specific servo might have a slightly different range.
How to Calibrate: 1. Set the pulse width to the theoretical center (e.g., 20, which is 1.5ms). Does the servo shaft point to 90 degrees? 2. If not, adjust the values. Use the gpio command for quick testing: bash # Switch pin to PWM mode gpio mode 1 pwm gpio pwm-ms gpio pwmc 192 gpio pwmr 2000 # Test a value (e.g., 150 for ~1.5ms) gpio pwm 1 150 Experiment with different values to find the true minimum and maximum pulse widths your servo responds to without straining. Update the constants in your C code accordingly.
Advanced Techniques and Project Integration
Creating Smooth, Non-Blocking Movements
The delay() function in the sweep example is blocking. For a responsive system (e.g., a robot that needs to listen for commands while moving), you must manage timing without blocking.
Example: Non-Blocking Sweep using millis()-like logic c
include <wiringPi.h> include <stdio.h> define SERVO_PIN 1
define SERVO_PIN 1
unsigned long previousMillis = 0; int currentAngle = 0; int targetAngle = 180; int sweepDirection = 1; // 1 for increasing, -1 for decreasing
void updateServoSmoothly() { unsigned long currentMillis = millis();
// Update angle every 20ms for smooth motion if (currentMillis - previousMillis >= 20) { previousMillis = currentMillis; if (currentAngle != targetAngle) { currentAngle += sweepDirection; // Use your setServoAngle function here (without its delay) int pulseWidth = 10 + ((currentAngle * 20) / 180); pwmWrite(SERVO_PIN, pulseWidth); } else { // Change direction when target is reached sweepDirection *= -1; targetAngle = (targetAngle == 180) ? 0 : 180; } } }
int main(void) { // ... setup code ... while (1) { updateServoSmoothly(); // You can do other tasks here, like reading sensors or network calls // delay(1); // Small delay to prevent CPU overuse } }
Building a Web-Controlled Servo Pan-Tilt
Combine your servo knowledge with a simple web server to create a remote-controlled camera platform.
Conceptual Steps: 1. Use Two Servos: One for pan (horizontal), one for tilt (vertical). Connect each to its own GPIO pin (e.g., GPIO 18 and GPIO 13). 2. Write a CGI Program: In C, using WiringPi for servo control, create a program that reads query parameters (e.g., ?pan=90&tilt=45) and sets the servo angles accordingly. 3. Lightweight Web Server: Use a simple server like lighttpd and configure it to execute your CGI program. 4. HTML Interface: Create a webpage with sliders or buttons that send GET requests to your CGI endpoint.
This project demonstrates the Raspberry Pi's unique strength: bridging the physical world of motors with the networked world of the internet.
Troubleshooting Common Issues
- Servo Jitters or Vibrates: This is often caused by electrical noise or an unstable power supply. Ensure your power supply is adequate and your grounds are solidly connected. Adding a large capacitor (e.g., 470µF to 1000µF) across the servo's power and ground leads, close to the servo, can smooth out spikes.
- Servo Doesn't Move / Pi Crashes: You are likely drawing too much current through the Pi. Immediately switch to an external 5V power supply for the servo.
- Incomplete Range of Motion: Your pulse width constants need calibration. Adjust
MIN_PULSE_WIDTHandMAX_PULSE_WIDTHas described in the calibration section. - "wiringPi.h: No such file or directory": The WiringPi development package is not installed. Ensure you built the library correctly.
While newer libraries like pigpio offer more features and active development, WiringPi provides a direct, no-frills path to understanding the fundamental timing required for servo control. Its simplicity is its didactic strength. By mastering these principles—PWM signal generation, power management, and non-blocking code—you equip yourself to integrate the dynamic motion of micro servos into virtually any Raspberry Pi project, from simple automations to complex robotic systems.
Copyright Statement:
Author: Micro Servo Motor
Source: Micro Servo Motor
The copyright of this article belongs to the author. Reproduction is not allowed without permission.
Recommended Blog
- Implementing Servo Motors in Raspberry Pi-Based Robotics Projects
- Using Raspberry Pi to Control Servo Motors in Automated Quality Control and Testing Systems
- Building a Servo-Powered Automated Sorting Machine with Raspberry Pi
- Creating a Servo-Controlled Automated Sorting Machine with Raspberry Pi and Robotics
- How to Control Servo Motors Using Raspberry Pi and the gpiozero Library
- Creating a Servo-Controlled Pan-Tilt Camera with Raspberry Pi
- Understanding Pulse Width Modulation for Servo Control on Raspberry Pi
- Building a Servo-Powered Automated Package Delivery System with Raspberry Pi
- How to Control Servo Motors Using Raspberry Pi and the pigpio Library
- Using Raspberry Pi to Control Servo Motors in Automated Inspection and Testing Systems
About Us
- Lucas Bennett
- Welcome to my blog!
Hot Blog
- How to Build a Remote-Controlled Car with 4G LTE Control
- Micro Servo Motors in Underwater Robotics: Challenges and Opportunities
- Using Micro Servos for Automated Door Locks in Smart Homes
- The Importance of Gear Materials in Servo Motor Performance Under Varying Signal Robustness
- How to Repair and Maintain Your RC Car's Motor End Bell
- Dimensions and Mounting: What You Should Know Before Buying
- Micro Servo Motors in Space Exploration: Innovations and Challenges
- The Role of PCB Design in Battery Management Systems
- Micro Servos with Programmable Motion Profiles
- How to Control Servo Motors Using Raspberry Pi and the gpiozero Library
Latest Blog
- Future Trends: How AI & Materials Will Improve Micro Servos in Robotics
- Creating a Servo-Controlled Automated Conveyor Belt System with Raspberry Pi
- The Importance of Design Rule Checks (DRC) in PCB Design
- Micro Servo Motors in Automated Painting Systems
- How Do Micro Servo Motors Work Step by Step?
- How to Control Servo Motors Using Raspberry Pi and the WiringPi Library
- The Impact of PCB Layout on EMC (Electromagnetic Compatibility)
- How to Create Effective Schematics for Control Circuits
- Exploring the Use of Micro Servo Robotic Arms in Industry
- Micro Servo Motors in Space Exploration: Applications and Challenges
- Micro Servos for High Temperature Environments
- Micro Servo vs Standard Servo for UAVs / Drones
- Reliability under Stress: Micro vs Standard Servo
- Child Safety: Automating Child-Proof Cabinets with Servos
- Choosing the Right Motor for Your RC Car Build
- Using Micro Servos in Smart Frames (digital art, picture slides)
- Baumüller's Micro Servo Motors: Precision Engineering at Its Best
- How Specification of Startup Surge Current Impacts Power Supply Design
- Diagnosing and Fixing RC Car Motor Mount Issues
- Using Arduino to Control the Position, Speed, and Direction of a Micro Servo Motor