Sensors/ Servo/ mg996r

MG996R Servo

The MG996R is a high-torque servo motor ideal for robotics and demanding DIY projects. Operating on 4.8V to 7.2V, it delivers up to 11 kg·cm torque at 6V, with a ~120° rotation range controlled via PWM signals. Weighing 55g, its durable metal gears and dimensions (40.7mm x 19.7mm x 42.9mm) make it suitable for heavy-duty applications requiring strength and reliability.

MG996R Servo image
mg996r · PWM
PWM
Interface
3pins
Connections
4.8-7.2V
Supply
0-55°C
Operating temp
$4
Typical price
On this page

mg996r pinout

3 pins · PWM

The MG996R is a high-torque 3-wire servo motor with GND (brown), +5V (red), and DATA (orange) wires.

View:
MG996R Servo pinout
PinTypeDescriptionNotes
GNDPowerGround connection. Connect to ESP32 GND and external power supply ground.Essential for both power and signal reference.
+5VPowerPower supply input (4.8V-7.2V). Requires external power supply capable of 2.5A peak.DO NOT power from ESP32 5V pin - insufficient current capacity.
DATAPWMPWM control signal. Pulse width: 1ms (0°), 1.5ms (midpoint), 2ms (max).Connect to a PWM-capable GPIO pin (e.g., GPIO 18).
  • Operating voltage: 4.8V-7.2V

  • Torque: Up to 11 kg·cm at 6V

  • Angular range: ~120° (60° each direction)

  • High current draw: up to 2.5A during stall

  • Metal gears for heavy-duty applications

Wiring the mg996r to ESP32

3 connections · all required

To control the MG996R servo with an ESP32, connect the brown wire to GND, red wire to an external 5-7.2V power supply (NOT ESP32), and orange wire to a PWM GPIO pin.

MG996R Servo wiring with ESP32
mg996r pinESP32 pinPurpose
GND (brown)GND + External Supply GNDCommon ground for ESP32 and external power supply.
+5V (red)External 5-7.2V SupplyDedicated power supply (2.5A+ capacity). DO NOT use ESP32 5V pin.
DATA (orange)GPIO 18PWM control signal (50Hz, 1-2ms pulse width).
  • CRITICAL: Use external power supply - ESP32 cannot provide sufficient current

  • Recommended: 6V 3A regulated power supply

  • PWM frequency: 50Hz (standard servo)

  • Peak current: up to 2.5A during stall conditions

  • Add 470µF-1000µF capacitor across power supply to reduce voltage spikes

  • Connect all grounds together (ESP32 + power supply + servo)

mg996r code examples

5 platforms
Platform:

mg996r Arduino example

Copy
// Requires library: "ESP32Servo"
#include <ESP32Servo.h> // The classic Arduino Servo library does not support the ESP32

Servo myServo; // Create a Servo object

void setup() {
  myServo.attach(18); // Servo signal on GPIO18, matches the wiring above
}

void loop() {
  myServo.write(0); // Move the servo to 0 degrees
  delay(1000);
  myServo.write(90); // Move the servo to 90 degrees
  delay(1000);
  myServo.write(180); // Move the servo to 180 degrees
  delay(1000);
}

On the ESP32 the classic Arduino Servo library does not work - install ESP32Servo instead, which provides the same familiar attach()/write() API on top of the ESP32's LEDC PWM hardware. The servo's signal wire connects to GPIO18 as shown above, and the sketch sweeps between 0, 90 and 180 degrees. Power the servo from 5V (or an external supply for stronger servos) - not from the 3.3V pin. The MG996R is a high-torque servo: power it from an external 5-7.2V supply that can source several amps at stall - never from the ESP32 board's regulator - and tie the grounds together.

mg996r ESP-IDF example

Copy
#include "driver/ledc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_err.h"

#define SERVO_PIN GPIO_NUM_18 // GPIO pin for the servo signal
#define SERVO_MIN_PULSEWIDTH 500 // Minimum pulse width in microseconds (0°)
#define SERVO_MAX_PULSEWIDTH 2500 // Maximum pulse width in microseconds (180°)
#define SERVO_MAX_DEGREE 180 // Maximum angle in degrees

// Convert an angle to an LEDC duty value: pulse width in us -> timer ticks
// (16-bit resolution at 50 Hz means the 20000 us period spans 65535 ticks)
uint32_t calculate_duty(uint32_t angle) {
    uint32_t pulse_us = SERVO_MIN_PULSEWIDTH + ((SERVO_MAX_PULSEWIDTH - SERVO_MIN_PULSEWIDTH) * angle) / SERVO_MAX_DEGREE;
    return (uint32_t)((uint64_t)pulse_us * 65535 / 20000);
}

void app_main() {
    // Configure the LEDC timer
    ledc_timer_config_t ledc_timer = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .timer_num = LEDC_TIMER_0,
        .duty_resolution = LEDC_TIMER_16_BIT,
        .freq_hz = 50, // Frequency for servos
        .clk_cfg = LEDC_AUTO_CLK
    };
    ledc_timer_config(&ledc_timer);

    // Configure the LEDC channel
    ledc_channel_config_t ledc_channel = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .channel = LEDC_CHANNEL_0,
        .timer_sel = LEDC_TIMER_0,
        .intr_type = LEDC_INTR_DISABLE,
        .gpio_num = SERVO_PIN,
        .duty = 0, // Initial duty cycle
        .hpoint = 0
    };
    ledc_channel_config(&ledc_channel);

    while (1) {
        // Move servo to 0°
        uint32_t duty = calculate_duty(0);
        ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty);
        ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
        vTaskDelay(pdMS_TO_TICKS(1000));

        // Move servo to 90°
        duty = calculate_duty(90);
        ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty);
        ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
        vTaskDelay(pdMS_TO_TICKS(1000));

        // Move servo to 180°
        duty = calculate_duty(180);
        ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty);
        ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

This code controls a servo using ESP-IDF's LEDC PWM driver. The calculate_pulse_width function computes the pulse width for a given angle (0° to 180°). The LEDC timer is set to 50 Hz, and the GPIO pin (e.g., GPIO_NUM_18) is configured as the output for the PWM signal. The servo's position is adjusted by updating the PWM duty cycle in the loop. The MG996R is a high-torque servo: power it from an external 5-7.2V supply that can source several amps at stall - never from the ESP32 board's regulator - and tie the grounds together.

mg996r ESPHome example

Copy
output:
  - platform: ledc
    id: pwm_output
    pin: GPIO18  # servo signal, matches the wiring above
    frequency: 50 Hz

servo:
  - id: my_servo
    output: pwm_output

number:
  - platform: template
    name: "MG996R Position"
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
    set_action:
      - servo.write:
          id: my_servo
          level: !lambda 'return x / 100.0;'

On the ESP32 the PWM output platform is ledc (the esp8266_pwm platform seen in older examples is ESP8266-only). The servo consumes the 50 Hz LEDC output on GPIO18, and the template number entity maps -100..100 to the servo range so you can slide it from Home Assistant; servo.write takes -1.0..1.0. The MG996R is a high-torque servo: power it from an external 5-7.2V supply that can source several amps at stall - never from the ESP32 board's regulator - and tie the grounds together.

mg996r PlatformIO example

Copy
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
    madhephaestus/ESP32Servo @ ^3.0.5
src/main.cppCopy
#include <Arduino.h>
#include <ESP32Servo.h> // The classic Arduino Servo library does not support the ESP32

Servo myServo; // Create a Servo object

void setup() {
  myServo.attach(18); // Servo signal on GPIO18, matches the wiring above
}

void loop() {
  myServo.write(0); // Move the servo to 0 degrees
  delay(1000);
  myServo.write(90); // Move the servo to 90 degrees
  delay(1000);
  myServo.write(180); // Move the servo to 180 degrees
  delay(1000);
}

This code demonstrates how to control a servo in PlatformIO using the Arduino framework. The servo is connected to GPIO 18, and its position is controlled using PWM signals generated by the myServo.attach() and myServo.write() methods. No additional libraries are needed as the Arduino Servo library is built into the framework. The setup() function initializes the servo, while the loop() moves it between 0°, 90°, and 180° with delays. The MG996R is a high-torque servo: power it from an external 5-7.2V supply that can source several amps at stall - never from the ESP32 board's regulator - and tie the grounds together.

mg996r MicroPython example

Copy
from machine import Pin, PWM
from time import sleep

# Configure PWM on GPIO18
servo = PWM(Pin(18))
servo.freq(50)  # Set frequency to 50 Hz

# Function to move the servo to a specific angle (0° to 180°)
def set_servo_angle(angle):
    # Convert angle to duty cycle (pulse width in microseconds)
    duty = int(40 + (angle / 180) * 115)  # Duty cycle range: 40-155 (approx. 500-2500 μs)
    servo.duty(duty)

# Main loop
while True:
    set_servo_angle(0)   # Move to 0°
    sleep(1)             # Wait 1 second
    set_servo_angle(90)  # Move to 90°
    sleep(1)             # Wait 1 second
    set_servo_angle(180) # Move to 180°
    sleep(1)             # Wait 1 second

This MicroPython code controls a servo motor using PWM on GPIO 18. The PWM object sets a 50 Hz frequency for the servo. The function set_servo_angle(angle) converts an angle (0° to 180°) into a duty cycle to position the servo. In the loop, the servo moves between 0°, 90°, and 180° with a 1-second delay between movements. The MG996R is a high-torque servo: power it from an external 5-7.2V supply that can source several amps at stall - never from the ESP32 board's regulator - and tie the grounds together.

mg996r specifications

From the datasheet
Interface
PWM
Stall Torque
9.4 kg·cm (4.8V), 11 kg·cm (6V)
Operating Speed
0.17 s/60° (4.8V), 0.14 s/60° (6V)
Operating Voltage
4.8V to 7.2V
Running Current
500 mA (4.8V), 900 mA (6V)
Stall Current
2.5 A (6V)
Dead Band Width
5 µs
Temperature Range
0°C to 55°C
Weight
55 grams
Dimensions
40.7mm x 19.7mm x 42.9mm
Gear Type
Metal
Rotation Range
Approximately 120° (60° in each direction)

About the mg996r

The MG996R is a standard-size metal-gear servo, a step up in every dimension from the micro servos on this site: about 55g, 41 x 20 x 43mm, and enough torque for robotic arms, pan-tilt rigs, and steering linkages that would strip an SG90 or MG90S in minutes. TowerPro’s own figures put stall torque at 9.4 kg-cm at 4.8V and 11 kg-cm at 6V - worth stating plainly because online listings for this exact part are all over the place, with some sellers advertising 13 kg-cm or more. Treat any number above the manufacturer’s own 9.4/11 kg-cm as marketing rather than measurement.

Current draw scales with that torque. The datasheet-quoted stall current reaches 2.5A at 6V, and while a moving load rarely sits at full stall for long, informal side-by-side testing against similar standard servos has recorded peak draws close to 1A even under moderate load - enough on its own to overwhelm the regulator on an ESP32 dev board. This is not a servo to power from the board’s 5V pin: it needs its own external 5-7.2V supply rated for at least a couple of amps, with its ground tied back to the ESP32’s ground and only the PWM signal wire going to a GPIO.

Control is the same 50Hz pulse-width signal as every other servo here, so the general PWM servo wiring and ESP32Servo code apply unchanged - only the power budget is different. For driving several MG996R-class servos at once, a PCA9685 PWM controller with its own dedicated servo power rail is a cleaner setup than trying to fan out several GPIOs and hoping one 5V rail keeps up.

mg996r troubleshooting

4 common issues

Servo Not Responding or Moving Erratically

›

Issue: The MG996R servo does not move as expected or exhibits erratic behavior.

Possible causes include insufficient power supply, incorrect wiring, or incompatible control signals.

Solution: Ensure the servo is powered by an adequate external power source, as it can draw up to 2.5A at stall. Verify that the control signal is connected to a PWM-capable pin on the microcontroller, and that the signal parameters match the servo's specifications.

Servo Overheating

›

Issue: The MG996R servo becomes excessively hot during operation.

Possible causes include overloading the servo, continuous operation under high torque, or inadequate power supply.

Solution: Avoid stalling the servo for extended periods, as this can lead to overheating. Ensure that the load applied to the servo is within its torque specifications. Use a stable and adequately rated power supply to prevent voltage drops that could cause the servo to overheat.

Servo Jittering or Twitching

›

Issue: The MG996R servo exhibits jittery or twitchy movements during operation.

Possible causes include electrical noise, insufficient power supply, or signal interference.

Solution: Ensure a stable and adequate power supply to the servo, as voltage fluctuations can cause erratic behavior. Implement proper grounding and consider adding decoupling capacitors to filter out electrical noise. Check for any sources of signal interference and ensure that control signals are clean and within the appropriate voltage levels.

Servo Not Centering Correctly

›

Issue: The MG996R servo does not return to its neutral position accurately.

Possible causes include calibration issues, mechanical wear, or internal potentiometer faults.

Solution: Perform a calibration by sending a neutral position command (typically 1500µs pulse width) and adjust as necessary. Inspect the servo for signs of mechanical wear or damage. If the problem persists, the internal potentiometer may be faulty, and replacing the servo could be necessary.

Where to buy the mg996r

MG996R Servo
MG996R Servo
$4per unit, typical
Amazon and AliExpress links are affiliate links - buying through them supports the site at no extra cost to you.

Resources

Similar sensors