The MG996R is the strong metal-gear servo (about 10 kg·cm) used in robot arms, steering linkages and pan-tilt heads, for about ₹300. It takes the same signal as a small SG90, but it needs far more current — and that is where most Uno projects with it go wrong.
The Uno only sends the control pulse on D9. The servo’s red and brown wires go to a separate 5–6 V supply that can give 3 A, and that supply’s negative is joined to the Uno’s GND. Without the shared ground the servo can’t read the pulse. Powered from the Uno’s 5V pin instead, it resets the board or jitters.
The sketch sets the start angle before attaching, so the servo doesn’t jump at power-up. It then moves one degree at a time between 0°, 180° and 90°, which also keeps the current spikes small.
Wiring
| Arduino Uno R3 | MG996R metal-gear servo (high torque) | Wire | Notes |
|---|---|---|---|
| D9 | SIG | orange | Orange wire. Only the control pulse comes from the Uno. |
| 5–6 V 3 A supply (adapter or 4× AA NiMH) · + | VCC | red | Red wire. Put a 470–1000 µF capacitor across + and − near the servo. |
| 5–6 V 3 A supply (adapter or 4× AA NiMH) · - | GND | brown | |
| GND | GND | brown | Common ground: without it the servo can’t read the pulse. |
4.8–7.2 V (use 5–6 V; up to about 2.5 A when stalled) part, 5 V board. The signal input accepts 3.3 V logic, so ESP32 and Pico drive it directly. Power must come from a separate 5–6 V supply with its GND joined to the board’s GND — never from the board’s 5V pin.
Board quirks
- The MG996R pulls about 0.5–1 A while moving and up to 2.5 A when stalled. On the Uno’s USB 5 V it resets the board or jitters wildly. A separate supply with a shared GND is not optional.
- The Servo library uses Timer1: PWM on D9 and D10 stops once a servo is attached. Up to 12 servos can run on any pins.
- Calling
write(90)beforeattach()starts the servo at 90° instead of snapping to 0° at power-up. - Many cheap MG996Rs only cover about 160–180° and buzz at the end stops. If it buzzes at 0 or 180, narrow the range (e.g. 5–175) — holding against the stop heats the motor.
- Some MG996Rs sold online are the 360° continuous kind, which spin instead of holding an angle. With those,
write(90)means stop.
Code
// MG996R metal-gear servo on an Arduino Uno R3.
// SIG → D9. VCC and GND from a separate 5–6 V 3 A supply; supply GND joined to the Uno GND.
// Never power an MG996R from the Uno's 5V pin - it can pull 2.5 A when stalled.
#include <Servo.h>
const uint8_t SERVO_PIN = 9;
Servo servo;
int current = 90;
// Move in small steps so the servo doesn't slam and pull a big current spike.
void slowMove(int target) {
int step = target > current ? 1 : -1;
while (current != target) {
current += step;
servo.write(current);
delay(10);
}
Serial.print(F("At "));
Serial.print(current);
Serial.println(F(" degrees"));
}
void setup() {
Serial.begin(9600);
servo.write(90); // set the start angle before attach() - no jump to 0
servo.attach(SERVO_PIN, 500, 2500);
Serial.println(F("MG996R on D9 - moving slowly between 0, 90 and 180"));
delay(1000);
}
void loop() {
slowMove(0);
delay(1000);
slowMove(180);
delay(1000);
slowMove(90);
delay(2000);
}// MG996R metal-gear servo on an Arduino Uno R3.
// SIG → D9. VCC and GND from a separate 5–6 V 3 A supply; supply GND joined to the Uno GND.
// Never power an MG996R from the Uno's 5V pin - it can pull 2.5 A when stalled.
#include <Servo.h>
const uint8_t SERVO_PIN = 9;
Servo servo;
int current = 90;
// Move in small steps so the servo doesn't slam and pull a big current spike.
void slowMove(int target) {
int step = target > current ? 1 : -1;
while (current != target) {
current += step;
servo.write(current);
delay(10);
}
Serial.print(F("At "));
Serial.print(current);
Serial.println(F(" degrees"));
}
void setup() {
Serial.begin(9600);
servo.write(90); // set the start angle before attach() - no jump to 0
servo.attach(SERVO_PIN, 500, 2500);
Serial.println(F("MG996R on D9 - moving slowly between 0, 90 and 180"));
delay(1000);
}
void loop() {
slowMove(0);
delay(1000);
slowMove(180);
delay(1000);
slowMove(90);
delay(2000);
}Library: Servo (Arduino (on ESP32 use ESP32Servo by Kevin Harrington, John K. Bennett)) — compiled with Servo 1.3.0.
Expected serial output
MG996R on D9 - moving slowly between 0, 90 and 180
At 0 degrees
At 180 degrees
At 90 degreesMG996R on D9 - moving slowly between 0, 90 and 180 At 0 degrees At 180 degrees At 90 degrees
Common errors
Uno resets or the USB port disconnects when the servo moves
The servo is on the Uno’s 5V pin. Move it to its own supply and keep only SIG and GND going to the Uno.
Servo jitters at rest
Supply too weak or no capacitor, or GND only connected at one side. See servo jitter.
Servo turns continuously
It’s a 360° version. Check the listing — or open it: continuous servos have no stop tab on the output gear.