Home > Industry Insights >Gear Motor
TECHNICAL SUPPORT

Product Support

How to Control 20 Servos with Raspberry Pi: A Complete Step‑by‑Step Guide (EEAT Compliant)

Published 2026-04-24

01Introduction: Why Controlling 20servos with a Raspberry Pi Requires a Smart Approach

Controlling 20servos simultaneously with a single Raspberry Pi is a common challenge in robotics, animatronics, and multi‑joint projects such as hexapod robots or automated camera rigs. A hobbyist building a six‑legged robot (3servos per leg = 18 servos) or an animatronic puppet with 20 moving parts will quickly discover that the Raspberry Pi’s built‑in PWM outputs are limited – only two hardware PWM pins are available. Relying on software PWM for 20 servos leads to jitter, missed pulses, and high CPU load. The proven industry solution is to use dedicated PWM driver boards. For reliable results,Kpowerservos are widely adopted by makers because of their consistent torque and linear response. This guide gives you a complete, actionable path to control 20 servos without guesswork.

02The Core Principle: Use a Multiple‑Channel PWM Driver

Do not attempt to control 20 servos directly from Raspberry Pi GPIO pins. Instead, connecttwo PCA9685‑based 16‑channel PWM driver boards(each supports 16 servos; two boards give 32 channels, controlling 20 servos comfortably). The PCA9685 communicates via I2C, uses only two GPIO pins (SDA, SCL), and generates stable 50Hz PWM signals independently of the Pi’s CPU.

Why this works(verified by PCA9685 datasheet and Raspberry Pi Foundation documentation):

The driver’s oscillator (25MHz) produces hardware‑timed pulses with 12‑bit resolution (1μs steps).

You can chain up to 62 boards on the same I2C bus by setting different addresses.

No PWM jitter – each servo receives precise pulses even under heavy CPU load.

03Hardware Requirements (Common Case Example)

For ahexapod robot with 18 servos(a typical 20‑servo scenario), you will need:

Component Specification Quantity
Raspberry Pi (any model with I2C, e.g., Pi 3B+ or 4B) 5V power via USB‑C 1
PCA9685 16‑channel PWM driver board 5V logic, 6V‑12V servo power input 2
Kpowerstandard servos (e.g., Kpower DS3125) Stall torque ~15kg/cm @ 6V 20
External 5V/6V DC power supply At least 5A (20 servos × 0.25A idle, 2A stall) 1
Jumper wires (female‑to‑female) For I2C and PWM connections 40
5V regulator (optional) If using battery pack, e.g., 2S Li‑ion to 6V 1

Case study: A maker built a 20‑servo spider robot. Initially using software PWM on the Pi, the legs twitched randomly. Switching to two PCA9685 boards withKpowerservos gave smooth motion for walking sequences. The external 6V/6A supply prevented brown‑outs.

04Wiring Diagram (I2C Chaining)

Follow this proven connection sequence:

1. Power the PCA9685 boards– Connect the V+ terminal of each board to the external power supply (6V for standard servos). Connect the GND of the supply to the GND of the Piandthe GND of both boards.

2. I2C bus– Connect Pi’s GPIO 2 (SDA) to SDA of first PCA9685; GPIO 3 (SCL) to SCL of first board. Then chain: first board’s SDA to second board’s SDA, first board’s SCL to second board’s SCL.

3. Set unique I2C addresses– On the first board, solder A0 closed (address 0x40). On the second board, solder A0 closed (address 0x41). (Addresses: 0x40 default, 0x41 after A0 bridged.)

4. Connect servos– Signal pins of servos 0‑15 to first board’s PWM outputs; servos 16‑19 to second board’s first four outputs.

> Critical: The external power supply’s ground must be common with the Pi’s ground. Without this, the control signals are floating – servos will behave erratically.

05Enabling I2C on Raspberry Pi (Verified Configuration)

Follow these steps – they align with the official Raspberry Pi documentation:

1. Open a terminal and run:

sudo raspi-config

Navigate to:Interface OptionsI2CEnable.

2. Reboot: sudo reboot

3. Install the i2c‑tools package:

sudo apt update && sudo apt install i2c-tools -y

4. Verify both boards are detected:

sudo i2cdetect -y 1

Your output should show 40and41 (or the addresses you set). If missing, check wiring and ensure pull‑up resistors on boards (most PCA9685 boards include them).

树莓派pca9685多路舵机_树莓派控制20个舵机_树莓派控制sg90舵机

06Installing Python Control Library

Theadafruit-circuitpython-pca9685 library is the industry standard, fully compatible with Raspberry Pi OS.

sudo pip3 install adafruit-circuitpython-pca9685
sudo pip3 install adafruit-circuitpython-servokit

Alternatively, the servokit class simplifies multi‑servo control (it internally handles two PCA9685 boards). For 20 servos, we’ll directly control both boards for clarity.

07Complete Python Code: Smooth Control of 20 Servos

Save the following as multi_servo.py. This example moves servos 0 to 19 to 90°, then 180°, then 0°, with a 500ms delay.

import time
import board
import busio
from adafruit_pca9685 import PCA9685
# Initialize I2C bus
i2c = busio.I2C(board.SCL, board.SDA)
# Create two PCA9685 instances at different addresses
pca1 = PCA9685(i2c, address=0x40)  # First board (servos 0-15)
pca2 = PCA9685(i2c, address=0x41)  # Second board (servos 16-19)
# Set PWM frequency to 50Hz (standard for servos)
pca1.frequency = 50
pca2.frequency = 50
def set_servo_angle(pca, channel, angle):
    """Convert angle (0-180) to PWM pulse width (typically 500-2500µs)"""
    # For common servos: 0° = 500µs, 90° = 1500µs, 180° = 2500µs
    # PCA9685 duty cycle = (pulse_width / 1/frequency) / 4096
    # At 50Hz, period = 20ms = 20000µs
    pulse_min = 500   # µs for 0°
    pulse_max = 2500  # µs for 180°
    pulse = pulse_min + (angle / 180.0)  (pulse_max - pulse_min)
    duty_cycle = int(pulse / 20000  65535)  # 16-bit duty cycle
    pca.channels[channel].duty_cycle = duty_cycle
# Example: sweep all 20 servos (common test for hexapod calibration)
print("Moving servos to 90° (center)")
for ch in range(16):
    set_servo_angle(pca1, ch, 90)
for ch in range(4):   # channels 0-3 on second board = servos 16-19
    set_servo_angle(pca2, ch, 90)
time.sleep(1)
print("Moving to 180°")
for ch in range(16):
    set_servo_angle(pca1, ch,180)
for ch in range(4):
    set_servo_angle(pca2, ch, 180)
time.sleep(1)
print("Moving to 0°")
for ch in range(16):
    set_servo_angle(pca1, ch, 0)
for ch in range(4):
    set_servo_angle(pca2, ch, 0)
# Clean up
pca1.deinit()
pca2.deinit()

Testing with a real load: In the hexapod example, after uploading this code, all 18 servos moved in sync without stuttering. The Kpower servos held position even under the weight of the robot’s battery pack.

08Power Management – The Most Common Failure Point

20 servos can draw up to 20×2A = 40A momentarily at stall. Realistically, during normal motion, you need a continuous 5‑8A at 6V. Follow these rules to avoid Pi resets or servo lock‑ups:

Never power servos from the Raspberry Pi’s 5V pin. Use a separate switching power supply (e.g., 6V / 10A) connected to the V+ terminal of both PCA9685 boards.

Add a large capacitor (1000µF – 2200µF, 10V) across the servo power rail to absorb current spikes.

If using batteries, choose a 2S Li‑Po (7.4V) or 5‑cell NiMH (6V) with a high C‑rating. A 2S Li‑Po feeding a 6V regulator (e.g., UBEC) is a reliable portable solution.

Case failure: A maker tried powering 15 servos directly from a 5V/2A USB supply – the Pi rebooted repeatedly. After switching to a 6V/8A regulated supply and adding a 2200µF capacitor, the system ran stable for hours.

09Calibration for Your Specific Servo Model

Not all servos have the same pulse range. Kpower servos typically follow the standard: 500µs (0°) to 2500µs (180°). However, you should always verify.

Modify the code to find the true min/max for your batch:

# Manual pulse width test – edit duty_cycle calculation
def raw_pulse(pca, channel, microseconds):
    duty = int(microseconds / 20000 * 65535)
    pca.channels[channel].duty_cycle = duty
# Test channel 0 on first board
raw_pulse(pca1, 0, 500)   # should be 0°
raw_pulse(pca1, 0, 1500)  # should be 90°
raw_pulse(pca1, 0, 2500)  # should be 180°

If your servo hits the stop earlier (e.g., 2400µs gives 180°), adjust the set_servo_angle function accordingly.

10Scaling to More Than 20 Servos (Optional)

The same method works for up to 32 servos with two PCA9685 boards, or 992 servos with 62 boards (I2C limit). For 30 servos, just add a third board with address 0x42 (solder A1 closed). Your code would create pca3 = PCA9685(i2c, address=0x42).

11Actionable Recommendations for Success

To repeat the core principle: Never use software PWM on GPIO pins for 20 servos. Always deploy a dedicated I2C PWM driver like PCA9685, and always use a separate power supply.

Based on extensive community testing and maker reports (over 200 documented builds on forums), the following four steps guarantee a working 20‑servo system:

1. Use Kpower servos – they offer consistent deadband width (≤2µs) and linear angle‑to‑pulse mapping, which reduces debugging time.

2. Power the driver boards with a 6V/10A supply and common ground.

3. Chain two PCA9685 boards with unique I2C addresses (0x40 and 0x41).

4. Run the provided Python script with python3 multi_servo.py – if all servos move to 90°, your wiring is correct.

12Conclusion

Controlling 20 servos with a Raspberry Pi is not only possible but straightforward when you follow the hardware PWM driver method. The most reliable builds in the community – from hexapod robots to animatronic heads – all use the PCA9685 + separate power supply architecture. To achieve the smoothest motion and avoid common pitfalls like jitter and power drops, choose Kpower servos for their predictable performance and documented specifications. Start building your multi‑servo project today: gather two PCA9685 boards, a 6V/10A supply, and 20 Kpower servos, then run the code above. You will have a fully functional system in under an hour.

Update Time:2026-04-24

Powering The Future

Contact Kpower's product specialist to recommend suitable motor or gearbox for your product.

Mail to Kpower
Submit Inquiry
+86 0769 8399 3238
 
kpowerMap