This is a quick note on how to control multiple servo motors using only the GPIO pins on a Raspberry Pi—without relying on any PWM or servo controller modules.
Introduction
I’ve been tinkering with my Raspberry Pi.
When looking into how to control multiple servo motors, most examples online use external PWM or servo control modules. However, this time I wanted to try controlling multiple servos just with GPIO, without any external modules.
So here’s a simple log of how I did it.
Note: This article was translated from my original post.
Controlling Multiple Servos on Raspberry Pi
OS Environment
I used a Raspberry Pi 4 Model B (4GB RAM).
The OS is Ubuntu 22.04.1 LTS (64-bit). Other OSs like Raspberry Pi OS should work similarly.
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.1 LTS Release: 22.04 Codename: jammy
Wiring the Circuit
The circuit was assembled like this:
- The servo motors used are SG90
- Power is supplied via a 4x AAA battery pack (6V)
(According to the datasheet, this is just within the operating range) - The ground from the external power source is connected to the Raspberry Pi’s GND
- Each servo's PWM signal wire is connected to a Raspberry Pi GPIO pin through a 1kΩ resistor
(Pins 17, 18, and 27 are used here)
Writing a Script to Move the Servos
Now let’s write a simple script to test the servo motor movements. We'll use Python.
Source code:
github.com
import math import time from gpiozero import AngularServo def main(): servo_17 = AngularServo(17) servo_18 = AngularServo(18) servo_27 = AngularServo(27) t = 0 max_angle = 60 gap_angle = 30 try: while True: servo_17.angle = math.sin(math.radians(t % 360)) * max_angle servo_18.angle = math.sin(math.radians((t % 360) + gap_angle)) * max_angle servo_27.angle = math.sin(math.radians((t % 360) + (gap_angle * 2))) * max_angle t += 2 time.sleep(0.01) except KeyboardInterrupt: servo_17.angle = 0 servo_18.angle = 0 servo_27.angle = 0 if __name__ == '__main__': main()
This script uses AngularServo
from gpiozero to control 3 servos.
To make the movements smoother, the angles are calculated using sine functions.
Running the Servo Script
Now let’s run the script on the Raspberry Pi.
First, clone the repository and install the required packages:
# Clone git clone https://github.com/bioerrorlog/raspberry-pi-examples.git cd raspberry-pi-examples/multi_servo_gpio/ # Install required packages sudo apt update sudo apt upgrade sudo apt install python3-pip python3-dev gcc git sudo pip install -r requirements.txt
Then, run the Python script:
sudo python3 main.py # Use sudo to avoid this error: # RuntimeError: No access to /dev/mem. Try running as root!
If everything works correctly, the servo motors should move like this:
(The servos are held together with cardboard.)
Raspberry Piとサーボモーターで疑似ロボットアームver0.00 動作確認
— BioErrorLog (@bioerrorlog) November 20, 2022
とりあえず何かが動きはじめた.
サーボ制御モジュールもソフト面の工夫もしていないので動作は不安定. pic.twitter.com/LKjnJbSS8s
Conclusion
This was a simple record of how I controlled multiple servos with a Raspberry Pi.
Since I didn’t use a PWM controller or implement any advanced software tricks, there's a fair amount of jitter.
Still, it works “well enough” to see the basic behavior.
That’s it for this note.
[Related Articles]