Servo motors are compact actuators that let you set an exact angular position, not just turn on or off. This makes them ideal for robotic arms, pan-tilt camera mounts, and automated mechanisms. In this tutorial, you will learn how to control an SG90 micro servo with an Arduino Uno using a potentiometer as an analog input. The guide covers wiring, a complete and improved Arduino sketch, how the code works, and what to do if the servo does not behave as expected.
Understanding Servo Motors and the SG90 Specifications
A standard hobby servo like the SG90 accepts pulse-width modulation (PWM) signals. The duration of the pulse, typically between 1 ms and 2 ms within a 20 ms cycle, determines the target angle. Most SG90 servos rotate from 0 to 180 degrees. According to typical SG90 datasheet values, it is a micro servo with a torque rating around 1.2 kg·cm at 4.8 V and slightly higher at 6 V. That means it can lift about 1.2 kg at a distance of 1 cm from the output shaft, not that it can lift 1.2 kg in any orientation. Always treat these values as approximate and check your specific model's datasheet.
Because the SG90 is small, it works well for learning and light-load projects. If your mechanism requires more force, choose a larger servo or use an external power supply.
Arduino Servo Wiring and PWM Pin Selection
The SG90 uses a 3-wire connector: brown is ground, red is power, and orange or yellow is the signal. Connect brown to GND, red to 5V, and signal to a digital I/O pin. The Arduino Servo library can use any digital pin on most boards, but PWM-capable pins such as 3, 5, 6, 9, 10, and 11 are often used because they are also available for analogWrite in other projects. In this example, we use pin 11.
Do not power multiple or high-torque servos directly from the Arduino 5V regulator. A single SG90 under light load is usually fine, but if the board resets, the servo buzzes, or movement is weak, connect an external 5V supply and join all grounds together.
Potentiometer Wiring
Use a 10 kΩ linear potentiometer. Connect the outer legs to 5V and GND, and the center wiper to A0. As you turn the knob, the voltage on A0 changes from 0 to 5V, producing ADC values from 0 to 1023.
Complete Arduino Code for Potentiometer Servo Control
The following sketch reads the potentiometer, maps the analog value to an angle between 0 and 180 degrees, and sends the corresponding command to the servo.
#include
// Pin definitions
const int servoPin = 11; // Servo signal pin
const int potPin = A0; // Potentiometer analog input
Servo myServo; // Create servo object
void setup() {
myServo.attach(servoPin);
}
void loop() {
int potValue = analogRead(potPin); // Read potentiometer (0-1023)
int angle = map(potValue, 0, 1023, 0, 180); // Convert to servo angle
myServo.write(angle); // Move servo to target angle
delay(15); // Short delay for stability
}
Code Explanation
The Servo.h library is included so the Arduino can generate the required pulses without blocking the whole program. In setup(), myServo.attach(servoPin) tells the library which pin the servo signal wire uses. In loop(), analogRead returns an integer from 0 to 1023. The map function scales that range to 0–180, which matches the SG90's normal angular range. The servo then moves to the mapped angle.
Using constants for pin definitions makes the code easier to maintain. If you change the wiring, update servoPin or potPin in one place instead of searching through the code.
Why the Delay Matters
The delay(15) gives the servo time to respond and reduces jitter caused by small voltage fluctuations in the potentiometer. Servo control pulses repeat about every 20 ms, so a 15 ms loop delay keeps the updates smooth without overwhelming the servo or the Arduino.
Testing, Calibration, and Troubleshooting
After uploading the sketch, turn the potentiometer slowly. The servo arm should follow the knob. If the movement is reversed, swap the 5V and GND connections on the potentiometer's outer legs. If the servo only moves over part of the range, measure the actual ADC values at your potentiometer's endpoints and replace the 0 and 1023 in the map function with those values.
Common issues include insufficient power, missing common ground when using an external supply, and signal wires connected to non-digital pins. If the servo hums but does not move, remove the load and test again. If the Arduino resets, use a separate 5V source with common ground.
You now have a working Arduino servo control setup using an SG90 and a potentiometer. The improved code uses clear pin definitions, proper mapping, and a stable delay. From here, you can replace the potentiometer with other analog sensors or add a second servo for more complex projects.
Upload the sketch, test your servo, and leave a comment with your results or questions.