Three Servo Categories, Not One "Smart Servo" Market

"Servo motor" gets used loosely across three genuinely different technologies, and confusing them is a common source of failed builds. Understanding the actual difference matters more than any spec sheet number.

Editorial diagram of a shared servo bus, regulated supply and common ground.
Original editorial illustration for this article. Diagram is indicative and not to scale.

1. Standard PWM Hobby Servos

The classic RC-style servo (like the widely used MG996R or SG90) takes a single pulse-width-modulated signal — typically a pulse between 1000 and 2000 microseconds repeated every 20ms, where pulse width maps to target angle. Internally it has its own small feedback loop (usually a potentiometer) driving a DC motor toward that target, but the controller never receives any position feedback back. You command an angle and hope it got there. Each servo needs its own dedicated signal wire.

2. Digital Serial "Smart" Bus Servos

Bus servos (Dynamixel from Robotis, the Feetech STS/SCS series, Hiwonder LX/HTS series) replace the PWM wire with a digital serial protocol. Multiple servos share the same two-wire bus, each with a unique ID, and the controller sends structured packets rather than raw pulses. Critically, these servos **report back** — actual position, load, voltage, and often temperature — turning open-loop control into closed-loop control at the system level. This is what actually justifies the "smart" name.

3. Industrial AC/BLDC Servo Drives

What industrial robot arms use isn't a "servo" in the hobbyist sense at all — it's a brushless or AC motor paired with a separate high-bandwidth servo drive running a dedicated PID loop (position/velocity/current cascaded control) at kHz update rates, closed over an absolute encoder via protocols like EtherCAT or CANopen. These systems are a different scale of cost and complexity, and are covered separately in our joint encoder guide and harmonic drive review — this article focuses on the PWM and bus servo categories relevant to desktop and educational 6-DOF arms.

Calculating the Torque You Actually Need

The single most common design mistake in DIY arms is picking a servo based on price or brand reputation rather than a real torque calculation. The formula is straightforward static analysis:

Torque sizing formula
Required Torque = (Payload weight + Sum of link weights beyond this joint)
                   × gravitational acceleration (9.81 m/s²)
                   × horizontal lever arm length (worst case: fully extended)
                   × safety factor (1.5–2.0)

Worked example — shoulder joint of a small desktop arm: Suppose the arm carries a 500g payload, the forearm and wrist assembly beyond the shoulder weighs 400g combined, and the arm's horizontal reach at full extension is 250mm (0.25m).

Example calculation
Total mass  = 0.5 kg (payload) + 0.4 kg (links) = 0.9 kg
Force       = 0.9 kg × 9.81 m/s² = 8.83 N
Torque      = 8.83 N × 0.25 m = 2.21 N·m
With 1.75x safety factor = 2.21 × 1.75 ≈ 3.87 N·m ≈ 39.5 kg·cm

That result — roughly 40 kg·cm — tells you immediately that a small 9g micro servo (rated around 1.5–2 kg·cm) is nowhere close to sufficient for this joint, while a mid-range digital bus servo rated 30–35 kg·cm would be marginal without the safety factor and undersized with it. This calculation should be repeated for every joint using its own downstream weight and lever arm — the base and shoulder almost always need dramatically more torque than the wrist.

Stall torque isn't continuous torque. The kg·cm or N·m figure on a servo's spec sheet is almost always stall torque — the maximum torque at zero speed, right before the motor gives up and its internal current limiting or thermal protection kicks in. Running a servo near its stall rating continuously will overheat it. Size for your worst-case moment but expect to operate well under the rated maximum during normal motion.

Controlling a PWM Servo: The Simple Case

For PWM servos, Arduino's built-in Servo library handles pulse generation directly — no protocol to implement:

Arduino C++ — pwm_servo_control.ino
#include <Servo.h>

Servo shoulderServo;

void setup() {
    shoulderServo.attach(9);      // PWM-capable pin
    shoulderServo.write(90);      // center position, degrees
}

void loop() {
    shoulderServo.write(45);      // move to 45 degrees
    delay(1000);
    shoulderServo.write(135);
    delay(1000);
}
Never power servos from the Arduino's 5V pin. The onboard regulator supplies well under 1A. Six servos moving under load can pull several amps combined — the resulting voltage sag causes brownouts, random resets, or servo jitter that looks like a code bug but is actually a power problem. Use a separate 5-6V supply sized for total stall current, sharing only ground with the microcontroller.

Controlling a Smart Bus Servo: Building the Protocol Packet

Bus servos from Feetech and similar manufacturers use a packet structure over half-duplex serial (single wire, or TX/RX tied together with a level shifter). The general structure looks like this:

Generic bus servo packet structure
[0xFF] [0xFF] [ID] [Length] [Instruction] [Param 1]...[Param N] [Checksum]

Checksum = (~(ID + Length + Instruction + Param1 + ... + ParamN)) & 0xFF

Here's a simplified example implementing a "move to position" command in the style of Feetech's SCS/STS protocol — always confirm your specific servo model's register map in its datasheet, since address offsets vary between series:

Arduino C++ — bus_servo_move.ino
// Simplified move-to-position packet, Feetech-style protocol
// Connect bus servo signal line to a hardware or software serial port

void moveServo(uint8_t id, uint16_t position, uint16_t timeMs) {
    uint8_t params[] = {
        42,                              // register address: goal position (check datasheet)
        (uint8_t)(position & 0xFF),      // position low byte
        (uint8_t)(position >> 8),        // position high byte
        (uint8_t)(timeMs & 0xFF),        // move time low byte
        (uint8_t)(timeMs >> 8)           // move time high byte
    };
    uint8_t instruction = 0x03;         // WRITE instruction
    uint8_t length = sizeof(params) + 2;

    uint16_t sum = id + length + instruction;
    for (uint8_t p : params) sum += p;
    uint8_t checksum = ~(sum & 0xFF);

    Serial1.write(0xFF); Serial1.write(0xFF);
    Serial1.write(id);
    Serial1.write(length);
    Serial1.write(instruction);
    for (uint8_t p : params) Serial1.write(p);
    Serial1.write(checksum);
}

void setup() {
    Serial1.begin(1000000);   // typical bus servo baud rate — confirm per model
}

void loop() {
    moveServo(1, 512, 800);   // servo ID 1, mid-position, 800ms move time
    delay(1000);
    moveServo(1, 800, 800);
    delay(1000);
}

Reading position feedback follows the same packet structure with a READ instruction (typically 0x02) instead of WRITE, and parsing the servo's response packet. In practice, most projects use the manufacturer's SDK (Feetech's SCServo library, or the Dynamixel SDK for Robotis servos) rather than hand-building packets — the manual protocol above is shown so you understand what those libraries are doing underneath, which matters when debugging communication errors.

Published Specifications: What's Actually on the Datasheet

These figures come from publicly available manufacturer datasheets for commonly used models in each category — always confirm against the current datasheet for your exact model and voltage, since torque scales with supply voltage.

Editorial summary table — check values against the current datasheet for your configuration.
Model / TypeStall TorqueFeedbackControl InterfaceTypical Use
Generic 9g micro (SG90-class)~1.6 kg·cm @ 4.8VNone (open-loop)PWMGrippers, light wrist axes
MG996R-class PWM servo~9.4–11 kg·cm @ 4.8–6VNone (open-loop)PWMSmall desktop arm joints
Dynamixel AX-12A~1.5 N·m (~15 kg·cm) @ 12VPosition, load, temp, voltageTTL serial bus, daisy-chainEducational/research arms
Feetech STS3215~30 kg·cm @ 12V (variants vary)Position, load, temp, voltageSerial bus, daisy-chainDIY 6-DOF arm base/shoulder joints
Hiwonder LX-16A~17 kg·cm @ 7.4VPosition (ADC), voltageSerial bus, daisy-chainMid-range DIY arms, hexapods

Note the resolution difference too: PWM servos typically resolve to roughly 0.5–1° depending on the receiving library's pulse timing precision, while bus servos commonly use 10-12 bit position sensing (1024–4096 steps across their range), giving resolution around 0.088–0.3° per step — a meaningful difference for tasks requiring fine positioning.

Choosing the Right Type Per Joint

Common Mistakes That Show Up After the Build Is "Finished"

"A servo's spec sheet tells you what it can do for an instant at stall. Your arm's design has to account for what it can sustain — that gap is where most DIY builds run into trouble."
— Robotics Engineering, Motion Control Editorial Notes

Sources and Further Reading

Torque and resolution figures above are drawn from publicly published manufacturer specifications at the time of writing and vary by supply voltage and specific model revision. Always verify against the current datasheet for the exact part you're purchasing.

Written by the Robotics Engineering Editorial Team
Technical content focused on 6-DOF robot arm design, motion control hardware, and embedded systems. Code examples are simplified for clarity — verify exact register addresses and baud rates against your specific servo model's datasheet before deployment.

What's the actual difference between a hobby PWM servo and a smart bus servo?

A PWM servo takes a single analog pulse-width signal per unit, has no position feedback to the controller, and needs one dedicated signal wire per servo. A smart bus servo communicates over a shared serial line using a digital packet protocol, reports back its actual position, load, temperature, and voltage, and multiple units can be daisy-chained on the same two wires using unique IDs.

How do I calculate how much torque a servo needs for a robot arm joint?

Multiply the total weight the joint must lift (payload plus the weight of every link beyond that joint) by gravitational acceleration and by the horizontal lever arm distance at full extension, then multiply by a safety factor of roughly 1.5-2x to account for dynamic loads during acceleration.

Can I power six servos directly from an Arduino's 5V pin?

No. The onboard regulator supplies well under 1A, while six servos moving under load can draw several amps combined. Use a separate power supply sized for combined stall current, sharing only ground with the microcontroller.

Why do smart bus servos use a checksum in their communication protocol?

The checksum lets the receiving servo verify the command packet wasn't corrupted during transmission over the shared bus. Since one line carries commands to many servos with different IDs, catching a corrupted packet's ID before acting on it prevents the wrong servo from executing an unintended movement.

Related Reading

Related: 6-DOF Robot Arm Master Guide

The long-form reference this article draws on for kinematics and cell design.

Read Full Guide →