Overview
The MG90S is a 9-gram metal-gear micro servo motor designed for precise position control between 0 and 180 degrees. Its all-metal brass and aluminum gear train resists stripping under heavier loads, making it a popular drop-in upgrade from the plastic-geared SG90. With up to about 2.2 kg-cm of stall torque at 6V and a standard 3-wire interface, it is well suited for RC planes, robotic arms, pan-tilt camera mounts, biped robots, and small motion projects.
Like all hobby servos, the MG90S is controlled with a single PWM signal — typically a 50 Hz pulse where the pulse width (roughly 500 to 2400 microseconds) sets the target angle. That makes it directly compatible with Arduino's Servo library, MicroPython's PWM module on Raspberry Pi Pico and ESP32, and Raspberry Pi GPIO PWM via Python.
The servo accepts 4.8V to 6V on the red wire, ground on the brown wire, and the PWM signal on the orange wire. The 3.3V GPIO on Pico, ESP32, and Raspberry Pi is sufficient to drive the signal pin reliably, but you should always power the servo from a separate 5V supply rather than the board's regulator to avoid brownouts and resets under load.
At a Glance
Specifications
| Parameter | Value |
| Operating Voltage | 4.8V - 6V DC |
| No-Load Current | ~100 - 200 mA |
| Stall Current | ~650 - 800 mA |
| Stall Torque | 1.8 kg-cm @ 4.8V / 2.2 kg-cm @ 6V |
| Rotation Range | 0 - 180 degrees |
| Operating Speed | 0.10 sec / 60 deg @ 4.8V |
| Control Signal | 50 Hz PWM, 500 - 2400 us pulse width |
| Gear Material | Metal (brass and aluminum) |
| Wire Length | ~25 cm (3-pin JR/Futaba connector) |
| Weight | ~13.4 g |
| Dimensions | 22.8 x 12.2 x 28.5 mm |
| Operating Temperature | -30 to +60 degrees C |
Pinout Diagram
Wiring Guide
Arduino Wiring
The MG90S works with any Arduino board that supports the Servo library. Power the servo from the Arduino 5V pin only for short bench tests with a single servo and no load — for anything beyond that, use a separate 5V supply and tie its ground to the Arduino ground.
| MG90S Wire | Arduino Pin | Details |
|---|---|---|
| Red (+5V) | 5V (or external 5V) | Use external supply if servo stalls or causes resets |
| Brown (GND) | GND | Common ground with Arduino if using external supply |
| Orange (PWM) | Digital Pin 9 | Any PWM-capable digital pin works |
ESP32 Wiring
The ESP32's 3.3V GPIO is high enough to drive the MG90S signal pin reliably. Always power the servo from a separate 5V source — the ESP32's onboard regulator cannot supply enough current for a servo and will reset under load.
| MG90S Wire | ESP32 Pin | Details |
|---|---|---|
| Red (+5V) | External 5V supply | Do NOT use ESP32 3.3V or VIN under load |
| Brown (GND) | GND | Tie external supply ground to ESP32 GND |
| Orange (PWM) | GPIO 18 | Any output-capable GPIO works (avoid GPIO 6-11) |
Raspberry Pi Wiring
The Raspberry Pi GPIO operates at 3.3V, which is enough to drive the MG90S signal pin. Software PWM works for one or two servos, but for jitter-free control of multiple servos, use the hardware PWM pins (GPIO 12, 13, 18, 19) or the pigpio daemon.
| MG90S Wire | Raspberry Pi Pin | Details |
|---|---|---|
| Red (+5V) | External 5V supply | Do NOT use the Pi's 5V pin for servos under load |
| Brown (GND) | Pin 6 (GND) | Tie external 5V supply ground to Pi GND |
| Orange (PWM) | Pin 12 (GPIO 18) | Hardware PWM pin — recommended for smooth motion |
pigpio library produces much smoother servo motion than RPi.GPIO software PWM. Install it with sudo apt install pigpio python3-pigpio, start the daemon with sudo pigpiod, and use pigpio.pi().set_servo_pulsewidth().
Raspberry Pi Pico Wiring
Every GPIO on the Pico can output hardware PWM, so any output-capable pin works for the signal wire. As with the other 3.3V boards, the Pico's onboard 3.3V regulator cannot power a servo — use a separate 5V supply.
| MG90S Wire | Pico Pin | Details |
|---|---|---|
| Red (+5V) | VBUS or external 5V | VBUS works only if Pico is USB-powered; external supply preferred |
| Brown (GND) | GND | Common ground with Pico |
| Orange (PWM) | GP15 | Any GPIO — Pico has hardware PWM on every pin |
Code Examples
Arduino
// MG90S Servo Sweep - Arduino Example
// Signal pin: Digital 9
// Power the servo from an external 5V supply with a common ground.
#include <Servo.h>
Servo myServo;
const int servoPin = 9;
void setup() {
Serial.begin(9600);
// attach(pin, minPulseUs, maxPulseUs) — tune these for your servo
myServo.attach(servoPin, 500, 2400);
myServo.write(90); // center
delay(500);
}
void loop() {
// Sweep 0 to 180 degrees
for (int angle = 0; angle <= 180; angle++) {
myServo.write(angle);
delay(15);
}
// Sweep back 180 to 0 degrees
for (int angle = 180; angle >= 0; angle--) {
myServo.write(angle);
delay(15);
}
}
ESP32 (Arduino Core)
// MG90S Servo - ESP32 Arduino Example using LEDC PWM
// Signal pin: GPIO 18
// Power the servo from a separate 5V supply, share ground with ESP32.
const int servoPin = 18;
const int pwmChannel = 0;
const int pwmFreq = 50; // 50 Hz for hobby servos
const int pwmResolution = 16; // 16-bit duty
// Pulse width in microseconds at 50 Hz: 20000 us period
// Duty = (pulseUs / 20000) * 65535
int pulseToDuty(int pulseUs) {
return (int)(((long)pulseUs * 65535L) / 20000L);
}
void writeAngle(int angle) {
if (angle < 0) angle = 0;
if (angle > 180) angle = 180;
int pulseUs = map(angle, 0, 180, 500, 2400);
ledcWrite(pwmChannel, pulseToDuty(pulseUs));
}
void setup() {
Serial.begin(115200);
ledcSetup(pwmChannel, pwmFreq, pwmResolution);
ledcAttachPin(servoPin, pwmChannel);
writeAngle(90);
delay(500);
}
void loop() {
for (int a = 0; a <= 180; a++) {
writeAngle(a);
delay(15);
}
for (int a = 180; a >= 0; a--) {
writeAngle(a);
delay(15);
}
}
Raspberry Pi (Python)
#!/usr/bin/env python3
# MG90S Servo - Raspberry Pi Example using gpiozero
# Signal pin: GPIO 18 (physical pin 12)
# Power the servo from a separate 5V supply, share ground with the Pi.
#
# For smoothest motion, run pigpiod first:
# sudo pigpiod
# Then run this script.
from gpiozero import AngularServo
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep
# Use pigpio backend for jitter-free PWM
factory = PiGPIOFactory()
servo = AngularServo(
18,
min_angle=0,
max_angle=180,
min_pulse_width=0.0005, # 500 us
max_pulse_width=0.0024, # 2400 us
pin_factory=factory,
)
try:
while True:
for angle in range(0, 181, 2):
servo.angle = angle
sleep(0.015)
for angle in range(180, -1, -2):
servo.angle = angle
sleep(0.015)
except KeyboardInterrupt:
print("Stopped by user")
finally:
servo.detach()
Raspberry Pi Pico (MicroPython)
# MG90S Servo - Pico MicroPython Example
# Signal pin: GP15
# Power the servo from a separate 5V supply, share ground with Pico.
from machine import Pin, PWM
from time import sleep
servo = PWM(Pin(15))
servo.freq(50) # 50 Hz for hobby servos
# 16-bit duty mapping for 500 - 2400 us pulse on a 20000 us period
MIN_DUTY = 1638 # ~500 us -> 0 degrees
MAX_DUTY = 7864 # ~2400 us -> 180 degrees
def write_angle(angle):
if angle < 0:
angle = 0
if angle > 180:
angle = 180
duty = MIN_DUTY + int((MAX_DUTY - MIN_DUTY) * angle / 180)
servo.duty_u16(duty)
try:
while True:
for a in range(0, 181, 2):
write_angle(a)
sleep(0.015)
for a in range(180, -1, -2):
write_angle(a)
sleep(0.015)
except KeyboardInterrupt:
print("Stopped by user")
servo.deinit()
Frequently Asked Questions
Servo.h library. ESP32 Arduino: either the ESP32Servo library or the LEDC PWM peripheral directly. Raspberry Pi: gpiozero with the PiGPIOFactory backend (after installing and starting pigpiod) for smooth motion. Pico MicroPython: the built-in machine.PWM module is sufficient.