Servos and Bus Servos
Introduction
A servo is a closed-loop actuator that integrates a motor, gear reducer, control circuitry, and position sensor into one unit. From simple PWM servos to high-performance bus servos, they cover a wide range of robotic applications from beginner to professional level.
PWM Servos
Operating Principle
PWM servos are controlled by pulse width modulation signals:
- Signal frequency: 50 Hz (20 ms period)
- Pulse width: 0.5 ms–2.5 ms corresponds to the angular range
- Typical mapping: 1 ms → 0°, 1.5 ms → 90°, 2 ms → 180°
1ms 1.5ms 2ms
┌─┐ ┌──┐ ┌───┐
│ │ │ │ │ │
────┘ └───────┘ └───────┘ └────
0° 90° 180°
←──────── 20ms period ────────→
Internal Structure
PWM signal → Control IC → H-bridge driver → DC motor → Gear train → Output shaft
↑ ↓
Compare/PID ←── Potentiometer (angle feedback) ←─┘
Common Models
SG90 Micro Servo
| Parameter | Value |
|---|---|
| Torque | 1.8 kg·cm (4.8V) |
| Speed | 0.1 s/60° |
| Weight | 9 g |
| Angular range | 180° |
| Gears | Plastic |
| Price | ~5 RMB |
| Suitable for | Beginner experiments, light-load scenarios |
MG996R Standard Servo
| Parameter | Value |
|---|---|
| Torque | 11 kg·cm (6V) |
| Speed | 0.14 s/60° |
| Weight | 55 g |
| Angular range | 180° |
| Gears | Metal |
| Price | ~20 RMB |
| Suitable for | Robotic arms, gimbals |
MG90S Micro Metal Gear
| Parameter | Value |
|---|---|
| Torque | 2.2 kg·cm (4.8V) |
| Weight | 13.4 g |
| Gears | Metal |
| Suitable for | Small-scale applications requiring durability |
PWM Servo Control Code
// Arduino PWM servo control
#include <Servo.h>
Servo myServo;
void setup() {
myServo.attach(9); // PWM pin
}
void loop() {
// Method 1: Set angle directly
myServo.write(90); // Move to 90°
delay(1000);
// Method 2: Set pulse width (microseconds)
myServo.writeMicroseconds(1500); // Center position
delay(1000);
// Smooth motion
for (int angle = 0; angle <= 180; angle++) {
myServo.write(angle);
delay(15);
}
}
Limitations of PWM Servos
- No feedback: Can only send target position; cannot confirm if reached
- Single-wire control: Each servo occupies one PWM pin
- Limited precision: Low potentiometer feedback accuracy
- No torque/speed control: Only position control
- Cannot be daisy-chained: Large numbers of servos require PCA9685 or similar PWM expansion boards
Serial Bus Servos
Bus servos use a serial communication protocol, addressing many limitations of PWM servos.
Core Advantages
| Feature | PWM Servo | Bus Servo |
|---|---|---|
| Connection | Each occupies a PWM pin | Daisy-chained |
| Feedback | None | Position + speed + torque + temperature |
| Control modes | Position only | Position / speed / torque |
| ID addressing | None | Each servo has a unique ID |
| Parameter configuration | None | Configurable PID, limits, baud rate, etc. |
| Wiring | Complex (many wires) | Simple (one bus) |
Waveshare ST3215 / ST3235
Feetech STS series, distributed by Waveshare, offering excellent cost-effectiveness:
| Parameter | ST3215 | ST3235 |
|---|---|---|
| Torque | 15 kg·cm | 20 kg·cm |
| Speed | 0.054 s/60° | 0.068 s/60° |
| Resolution | 4096 (0.088°) | 4096 |
| Communication | Half-duplex UART (TTL) | Half-duplex UART |
| Baud rate | 1 Mbps (max) | 1 Mbps |
| Feedback | Position + speed + load + temperature + voltage | Same |
| Control modes | Position / speed / PWM open-loop | Same |
| Price | ~60 RMB | ~80 RMB |
Daisy-Chain Connection
MCU(TX/RX) → Servo1(ID=1) → Servo2(ID=2) → Servo3(ID=3) → ...
│ │ │
GND GND GND
VCC VCC VCC
Half-Duplex Note
The STS series uses single-wire half-duplex communication where TX and RX share one data line. Direction control is needed (tri-state buffer or GPIO-based transmit/receive switching).
Control Example
# Waveshare ST3215 Python control example
# Using SCServo SDK
from scservo_sdk import *
# Initialize port
portHandler = PortHandler('/dev/ttyUSB0')
packetHandler = SMS_STS(portHandler)
portHandler.openPort()
portHandler.setBaudRate(1000000) # 1Mbps
SERVO_ID = 1
# Write target position (0-4095 corresponds to 0-360°)
# Parameters: ID, target position, speed, acceleration
packetHandler.WritePosEx(SERVO_ID, 2048, 1000, 50) # Center, speed 1000, accel 50
# Read current state
position = packetHandler.ReadPos(SERVO_ID)
speed = packetHandler.ReadSpeed(SERVO_ID)
load = packetHandler.ReadLoad(SERVO_ID)
temperature = packetHandler.ReadTemperature(SERVO_ID)
print(f"Position: {position}, Speed: {speed}, Load: {load}, Temperature: {temperature}°C")
# Sync write to multiple servos (simultaneous motion)
groupSyncWrite = GroupSyncWrite(portHandler, packetHandler,
SMS_STS_GOAL_POSITION, 4)
groupSyncWrite.addParam(1, [0x00, 0x08, 0xE8, 0x03]) # ID1: pos=2048, speed=1000
groupSyncWrite.addParam(2, [0x00, 0x04, 0xE8, 0x03]) # ID2: pos=1024, speed=1000
groupSyncWrite.txPacket()
Dynamixel Series
Robotis' Dynamixel is the most well-known bus servo brand, widely used in research and competitions.
Common Models
| Model | Torque | Communication | Resolution | Features |
|---|---|---|---|---|
| AX-12A | 15.3 kg·cm | TTL half-duplex | 1024 | Classic entry-level, discontinued |
| XL330-M288 | 0.43 N·m | TTL half-duplex | 4096 | Ultra-compact, suitable for dexterous hands |
| XL430-W250 | 1.4 N·m | TTL half-duplex | 4096 | Cost-effective entry-level |
| XM430-W350 | 4.1 N·m | RS-485 | 4096 | Research workhorse |
| XM540-W270 | 10.6 N·m | RS-485 | 4096 | High torque |
Dynamixel Protocol 2.0
Communication protocol structure:
[Header] [Reserved] [ID] [Length] [Instruction] [Parameters...] [CRC]
FF FF FD 00 0x01 0x07 0x03 ... CRC
Main instructions:
| Instruction | Value | Function |
|---|---|---|
| Ping | 0x01 | Check if servo is online |
| Read | 0x02 | Read control table data |
| Write | 0x03 | Write control table data |
| Sync Read | 0x82 | Synchronously read multiple servos |
| Sync Write | 0x83 | Synchronously write to multiple servos |
| Bulk Read | 0x92 | Bulk read (different addresses) |
Dynamixel Python SDK
from dynamixel_sdk import *
ADDR_TORQUE_ENABLE = 64
ADDR_GOAL_POSITION = 116
ADDR_PRESENT_POSITION = 132
BAUDRATE = 57600
PROTOCOL_VERSION = 2.0
portHandler = PortHandler('/dev/ttyUSB0')
packetHandler = PacketHandler(PROTOCOL_VERSION)
portHandler.openPort()
portHandler.setBaudRate(BAUDRATE)
DXL_ID = 1
# Enable torque
packetHandler.write1ByteTxRx(portHandler, DXL_ID, ADDR_TORQUE_ENABLE, 1)
# Write goal position (0-4095)
packetHandler.write4ByteTxRx(portHandler, DXL_ID, ADDR_GOAL_POSITION, 2048)
# Read current position
position, result, error = packetHandler.read4ByteTxRx(
portHandler, DXL_ID, ADDR_PRESENT_POSITION)
print(f"Current position: {position}")
# Disable torque
packetHandler.write1ByteTxRx(portHandler, DXL_ID, ADDR_TORQUE_ENABLE, 0)
portHandler.closePort()
RS-485 vs. TTL Comparison
| Feature | TTL Half-Duplex | RS-485 |
|---|---|---|
| Signal level | 0/3.3V or 0/5V | Differential signal |
| Transmission distance | <1 m | <1200 m |
| Noise immunity | Weak | Strong |
| Number of nodes | Fewer | Up to 32/256 |
| Typical application | Small robots | Industrial / large robots |
See UART and I2C/SPI for details.
Bus Servo Comparison Summary
| Feature | Feetech STS | Dynamixel X |
|---|---|---|
| Price | Low (60–100 RMB) | High (300–2000 RMB) |
| Ecosystem | Simpler SDK | Complete SDK, rich documentation |
| Community | Mainly domestic (China) | Global research community |
| Communication protocol | Proprietary | Protocol 2.0 (open) |
| Software tools | FD debug tool | Dynamixel Wizard 2.0 |
| Suitable for | Cost-effective projects, education | Research, competitions, commercial |
Servo Power Supply Considerations
Power Isolation
- Servos (especially multiple units) should use a separate power supply, not shared with the MCU
- Large transient currents may cause MCU resets
- Power wires must be thick enough to minimize voltage drop
- Bus servos can draw 3–5 times their rated current at startup
Typical Power Supply Configuration
Battery/PSU ─┬─→ Buck converter (5V/3.3V) ──→ MCU
│
└─→ Servo power (6-12V) ──→ Servo bus
│
Common GND ←─┘
Summary
- PWM servos are simple and inexpensive, suitable for beginner and light-load applications
- Bus servos support daisy-chaining, status feedback, and multi-mode control, suitable for complex robots
- The Feetech STS series offers excellent value; Dynamixel has a well-established ecosystem
- For projects with many servos, power supply design is critical
- Selection should consider torque, precision, communication method, and budget holistically