The Servo vs. Stepper vs. DC Decision Matrix
Before you write a single line of code, you must verify that a servo is actually the right motor for your load profile. Hobbyists often treat steppers and servos as interchangeable, but their torque curves and control architectures are fundamentally different.
| Motor Type | Torque Curve & Holding | Control Needs | Typical Cost (2026) | Best Load Profile |
|---|---|---|---|---|
| RC Servo | High holding torque at zero speed; drops at high speed. | 50Hz PWM signal (1-2ms pulse). Internal H-bridge. | $3 - $15 | Robotic arms, pan/tilt cameras, RC steering. |
| Stepper | High torque at low/zero speed; severe drop-off at high RPM. | Step/Dir pulses via external driver (e.g., A4988, TMC2209). | $10 - $30 | 3D printers, CNC routers, precision linear actuators. |
| DC Brushed | Low holding torque; high torque at stall; peaks at mid-speed. | H-Bridge motor driver for speed/direction control. | $2 - $8 | Drive wheels, conveyor belts, high-speed fans. |
The Verdict: Choose a servo when you need absolute angular positioning over a limited range (usually 180° or 270°) with high holding torque, and you want to avoid the complexity of microstepping drivers and limit switches required by steppers.
Sizing Your Servo: Torque, Load, and the 50% Rule
The most common mistake in motor selection is sizing a servo exactly to its rated stall torque. If a servo is rated for 10 kg-cm, and your load demands 10 kg-cm, the motor will draw maximum stall current, overheat, and strip its gears.
Worked Load Example: Robotic Arm
Imagine you are building a robotic arm that needs to lift a 200g payload. The distance from the servo shaft (the fulcrum) to the payload is 10 cm.
- Payload Torque: 0.2 kg × 10 cm = 2.0 kg-cm.
- Arm Weight Torque: Assume the arm itself weighs 100g, with its center of mass at 5 cm from the shaft. 0.1 kg × 5 cm = 0.5 kg-cm.
- Total Static Torque: 2.0 + 0.5 = 2.5 kg-cm.
Applying the 50% rule, you need a servo with a minimum stall torque of 5.0 kg-cm. A standard micro servo like the SG90 (rated at 1.8 kg-cm) will instantly stall and burn out. You need to step up to a standard-size metal-gear servo like the MG996R (rated at ~13 kg-cm), which will handle this load effortlessly while running cool.
Wiring Terminals and Power Delivery
Standard hobby servos use a 3-pin JST or Dupont connector. The color coding is generally standardized, but always verify against the manufacturer's datasheet.
| Wire Color | Function | Connection Details |
|---|---|---|
| Brown or Black | Ground (GND) | Must share a common ground with the Arduino and external power supply. |
| Red | Power (VCC) | 4.8V to 6.0V DC. Do not exceed 6V or you will fry the internal potentiometer. |
| Orange, Yellow, or White | Signal (PWM) | Connects to any Arduino digital pin capable of PWM output (e.g., Pin 9). |
Driver and Power Requirements
A servo contains its own internal DC motor, H-bridge driver, and gearbox. You do not need an external motor shield to drive it. However, you must pay strict attention to power delivery.
High-torque servos like the MG996R can draw 2.5A or more during a stall condition. The Arduino’s onboard 5V linear regulator is typically rated for only 500mA to 800mA, and the USB polyfuse often trips at 500mA. If you power a heavy-load servo directly from the Arduino's 5V pin, the voltage will sag below 4.5V, causing the ATmega328P or ESP32 to brownout and reset mid-cycle.
How to Code a Servo with Arduino (PWM & Sweep)
Servos are controlled by Pulse Width Modulation (PWM) at a fixed frequency of 50Hz (a 20ms period). The position is dictated by the width of the high pulse: typically 1ms for 0°, 1.5ms for 90°, and 2ms for 180°. Fortunately, the native Arduino Servo.h library abstracts these microsecond timings into simple degree commands.
For deeper library documentation, refer to the official Arduino Servo Library reference.
Pin Mapping
| Component | Arduino Uno / Nano Pin | ESP32 DevKit Pin |
|---|---|---|
| Servo Signal (Orange) | D9 | GPIO 13 |
| Servo VCC (Red) | External 5V BEC | External 5V BEC |
| Servo GND (Brown) | GND (Shared with BEC) | GND (Shared with BEC) |
Complete Sweep Code
This code smoothly sweeps the servo from 0° to 180° and back. It includes a detach command to prevent servo jitter when idle, a common issue caused by noisy power supplies or floating PWM signals.
#include <Servo.h>
// Define the signal pin
const int SERVO_PIN = 9;
// Create servo object
Servo myServo;
void setup() {
// Attach the servo to the pin
myServo.attach(SERVO_PIN, 500, 2400);
// Note: 500 and 2400 are the min/max pulse widths in microseconds.
// Adjust these if your servo doesn't reach full 0-180 range.
}
void loop() {
// Sweep from 0 to 180 degrees
for (int pos = 0; pos <= 180; pos += 1) {
myServo.write(pos);
delay(15); // 15ms delay for smooth motion
}
// Sweep from 180 back to 0 degrees
for (int pos = 180; pos >= 0; pos -= 1) {
myServo.write(pos);
delay(15);
}
// Optional: Detach to stop PWM jitter and save power if holding torque isn't needed
// myServo.detach();
// delay(2000);
// myServo.attach(SERVO_PIN);
}
Failure Signatures: Hum, Overheat, and Stall
When a servo fails, it rarely just stops working silently. It gives physical and electrical warnings. Here is how to diagnose the three most common failure signatures on the bench.
1. The 'Hum' or Jitter
Symptom: The servo vibrates rapidly back and forth by 1° or 2° when it should be holding still, accompanied by an audible high-pitched hum.
Cause: This is almost always a power or signal integrity issue. Ripple on the 5V supply line, a missing common ground between the Arduino and the servo power supply, or a worn internal potentiometer sending noisy feedback to the internal comparator.
Fix: Add a 470µF electrolytic capacitor across the VCC and GND wires near the servo connector to smooth voltage ripple. Ensure the ground wire is thick enough (minimum 22 AWG) to handle the return current without inducing a ground loop voltage drop.
2. Overheat and Thermal Shutdown
Symptom: The servo casing becomes too hot to touch, and the motor eventually stops responding, sometimes emitting a faint smell of melting plastic.
Cause: Mechanical binding. If the linkage or arm is physically restricted from reaching its target angle, the internal DC motor stalls. A stalled DC motor acts as a dead short, drawing maximum current (often 2A+) and converting it entirely into heat.
Fix: Check your mechanical linkages for binding. In code, implement a timeout: if you command a position and read back a mismatch (on smart servos) or if the current draw spikes (measured via an inline shunt), cut power via a MOSFET to prevent melting the internal nylon gears.
3. Stall and Gear Stripping
Symptom: A loud 'clacking' or grinding noise, followed by the servo output shaft spinning freely with no torque.
Cause: Exceeding the stall torque limit, causing the teeth on the internal gearbox to shear off. This is incredibly common with cheap plastic-gear servos (like the SG90) when used in high-inertia loads.
Fix: Upgrade to a metal-gear servo (e.g., MG996R or DS3218). If the load has high inertia (like a long, heavy arm), add a physical hard-stop at the limits of travel so the mechanical structure absorbs the shock, not the servo gears.
The Final Verdict: What to Buy for Your Next Build
Stop guessing which servo to put in your cart. Use this decision tree to make a concrete selection based on your exact mechanical requirements.
| If your project needs... | And your budget is... | Buy this exact part: |
|---|---|---|
| Micro-movements, camera triggers, or lightweight prototyping (< 1.5 kg-cm). | Under $3 | TowerPro SG90 (Plastic gears, 9g micro servo) |
| Robotic arms, RC car steering, or pan/tilt mounts requiring high stall torque (10-13 kg-cm). | $6 - $10 | TowerPro MG996R (Metal gears, standard size, requires external 5V/3A BEC) |
| Precision robotics, 270° wide-angle movement, or continuous high-torque actuation (20+ kg-cm). | $15 - $25 | Waveshare DS3218 (270° metal gear, digital servo, high precision) |
For 90% of intermediate Arduino projects involving robotic arms or heavy pan/tilt mechanisms, the MG996R is the undisputed workhorse. Pair it with a dedicated 5V 3A buck converter, use the Servo.h library with custom min/max pulse widths, and respect the 50% torque rule. Your mechanism will run cool, quiet, and reliably for thousands of cycles.






