Big servo on an Arduino Uno
An MG996R metal-gear servo on pin 9 follows a slide potentiometer on A0, powered from its own 6 V battery pack with only the ground shared. The whole build, an Arduino Uno and 3 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Beginner About 20 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $42. On Mokxi they're free.
What you'll learn
- Reading a potentiometer as a position
- Mapping a range of readings to an angle
- Servo control by pulse width
- Powering a big servo from its own battery
- Sharing a ground between supplies
- Difficulty: Beginner
- Time: About 20 minutes
- Board: Arduino Uno R3
- Parts: 5
How it works
A slide potentiometer is wired between 5 V and ground, and its wiper goes to A0. The Uno reads it, turns 0 to 1023 into an angle from 0 to 180 degrees, and tells the servo where to point.
The MG996R is a big metal-gear servo, so it gets its own power from a battery. Only the signal wire on pin 9 and the ground connect to the Uno. The grounds are joined so the signal has a shared reference.
The sketch averages four readings before converting, so the horn does not twitch on the last count of the reading.
Parts list
5 parts, plus the jumper wires. They retail for about $42; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Full-size breadboard
- 1 × Slide potentiometerIn Spaceship Panel Kit.
- 1 × Servo, MG996R metal gear
- 1 × Battery: AA, coin cell, LiPoIn Handheld Console Kit, Laser Sword Kit, Power Bank Kit.
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| Servo, MG996R metal gear pin PWM | Arduino Uno R3 pin 9 |
| Slide potentiometer pin 3 | Arduino Uno R3 pin 5V |
| Slide potentiometer pin 1 | Arduino Uno R3 pin GND |
| Servo, MG996R metal gear pin GND | Arduino Uno R3 pin GND |
| Battery: AA, coin cell, LiPo pin V- | Arduino Uno R3 pin GND |
| Slide potentiometer pin 2 | Arduino Uno R3 pin A0 |
| Battery: AA, coin cell, LiPo pin V+ | Servo, MG996R metal gear pin VCC |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Servo fader: push the slider, the horn follows.
//
// A0 the slide potentiometer's wiper (its ends on 5 V and GND)
// pin 9 the servo's signal wire (its red wire on 5 V, brown on GND)
//
// A servo does not take PWM the way an LED does. It takes a pulse width: a
// pulse of 544 us once every 20 ms puts the horn at one end of its travel,
// 2400 us puts it at the other (the Arduino Servo library's numbers), and
// anything between is an angle between. The servo holds whatever it was last
// told, and it walks there at its own speed, about a tenth of a second for
// sixty degrees.
//
// So the sketch reads the fader, turns 0..1023 into 0..180 degrees and sends
// the matching pulse, fifty times a second. mokxi_servo.h makes the pulse with
// delayMicroseconds, since the Uno's analogWrite runs far too fast for a servo
// to read.
//
// The reading is averaged over a few samples so the horn does not twitch on
// the last count of the ADC, and the angle is printed only when it changes.
#include "mokxi_servo.h"
const int FADER = A0;
const int SIGNAL = 9;
Servo horn(SIGNAL);
int shown = -1;
void setup() {
Serial.begin(115200);
Serial.println("Mokxi Uno: a fader on A0 drives a servo on pin 9");
horn.begin();
horn.write(90);
}
void loop() {
long sum = 0;
for (int i = 0; i < 4; i++) {
sum += analogRead(FADER);
}
int reading = (int)(sum / 4);
int angle = (int)map(reading, 0, 1023, 0, 180);
horn.write(angle);
if (angle != shown) {
shown = angle;
Serial.print("fader ");
Serial.print(reading);
Serial.print(" -> ");
Serial.print(angle);
Serial.println(" degrees");
}
delay(20);
}
Code walkthrough
The key functions of the sketch, and what each one does.
setup sketch.ino
Starts the serial port at 115200 baud, prints a message, calls horn.begin() and sends the horn to 90 degrees so it starts in the middle.
void setup() {
Serial.begin(115200);
Serial.println("Mokxi Uno: a fader on A0 drives a servo on pin 9");
horn.begin();
horn.write(90);
}loop sketch.ino
Adds up four analogRead samples from FADER and divides by four. map turns 0 to 1023 into 0 to 180, and horn.write sends that angle. It prints only when the angle changes, then waits 20 ms, so the pulse goes out about fifty times a second.
void loop() {
long sum = 0;
for (int i = 0; i < 4; i++) {
sum += analogRead(FADER);
}
int reading = (int)(sum / 4);
int angle = (int)map(reading, 0, 1023, 0, 180);
horn.write(angle);
if (angle != shown) {
shown = angle;
Serial.print("fader ");
Serial.print(reading);
Serial.print(" -> ");
Serial.print(angle);
Serial.println(" degrees");
}
delay(20);
}Troubleshooting
The usual mistakes with this circuit, and the fix for each.
- The servo twitches or the Uno resets This project
Power the servo from the battery, not from the Uno's 5 V pin. A big servo draws far more current than the Uno can supply. - The servo does not move at all This project
Check the battery ground is joined to the Uno's GND. Without a shared ground the signal on pin 9 means nothing to the servo. - Readings jump around, or the pin reads random values. Slide potentiometer
The wiper must go to an analog input and both end pins to 5 V and GND. If an end is loose, the wiper floats. Check all three connections. - Pushing the slider up lowers the number. Slide potentiometer
Swap the two end pins, or flip it in code with map(value, 0, 1023, 1023, 0). The wiper reads high when it is nearer the end tied to 5 V. - The servo jitters, resets the board, or the Arduino reboots when it moves. Servo
It can draw over 1 A moving and up to about 2.5 A stalled. Power it from its own 4.8 to 6 V supply, not the Arduino 5 V pin. Join the grounds and add a 470 uF or larger capacitor. - The servo hums or gets hot at the end of travel. Servo
The code asks for an angle past its range, so it pushes against the stop. Stay inside the real range, such as 10 to 170 degrees, and detach when it is not needed. Gears can strip when stalled. - The battery is wired backwards, or the voltage is too low or too high for the circuit. A fresh AA is about 1.5 V, a LiPo is 3.7 V nominal and 4.2 V full. Battery: AA
Match the plus and minus marks. Check the voltage your parts need. Two AAs make 3 V, four make 6 V. Never feed a LiPo to a 3.3 V chip directly at 4.2 V. - The circuit resets or browns out when a motor or servo starts. A battery has internal resistance, so the voltage sags under load. Battery: AA
Use a fresh pack with enough current rating. Add a 100 uF or larger capacitor near the load. Power motors from their own pack and join the grounds.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.