Lesson 86: Control position of a servo motor using potentiometer
Imagine turning a simple knob and watching a mechanical arm precisely follow your every move. That is the magic of combining a potentiometer with a servo motor. This project, part of the Arduino Step by Step Course by Robojax, demonstrates a fundamental and incredibly useful concept in electronics: translating an analog input into precise physical motion. You will learn how to read a variable voltage from a potentiometer, map that value to a range of angles, and command a servo motor to rotate to that exact position. This is your gateway to building intuitive and interactive projects where manual control meets automation.

The applications for this skill are vast and practical. Here are just a few ideas to get you inspired:
- Robotic Arm Control: Use a potentiometer to manually position each joint of a robotic arm for precise pick-and-place operations.
- Camera Pan and Tilt System: Build a remote-controlled camera mount for time-lapses or surveillance, smoothly panning and tilting with a twist of a dial.
- Analog Gauge Replica: Create a physical dashboard gauge (like a speedometer or temperature dial) that moves based on sensor data, with the potentiometer acting as a manual override or calibration tool.
- Interactive Art Installations: Create kinetic sculptures that respond to viewer input, where turning a dial changes the position of moving parts.
- Model Vehicle Steering: Control the steering angle of a model car or boat remotely, providing a more intuitive and analog feel than digital buttons.
This guide is based on the video tutorial Lesson 86: Control position of a servo motor using potentiometer by Robojax (in video at 00:00). It walks you through the entire process, from understanding the wiring to explaining the code that makes it all work. Let's get started.
Hardware and Components
To follow along with this project, you will need the following components:
- An Arduino board (e.g., Uno, Nano)
- A standard servo motor (e.g., SG90 or MG996R)
- A potentiometer (variable resistor, typically 10kΩ)
- Jumper wires
- A breadboard (optional, for easier connections)
Understanding the Wiring
The wiring for this project is straightforward. The key is to provide the correct power and signal connections for both the servo and the potentiometer. The servo is a power-hungry device, so it gets its power directly from the Arduino's 5V pin. The potentiometer acts as a voltage divider, and we read the voltage at its wiper (the middle pin) to determine its position. (in video at 01:05)
One clever trick this project uses is creating an additional 5V source on a digital pin to power the potentiometer, as some Arduino boards only have one dedicated 5V pin. This is done in the code by setting a digital pin (pin 8) to HIGH, which outputs 5V. (in video at 00:39)
Here is the wiring diagram mentioned in the video:
Let's break down the connections:
- Servo Motor:
- Power (Red wire) → Arduino 5V pin
- Ground (Brown/Black wire) → Arduino GND pin
- Signal (Orange/Yellow wire) → Arduino pin 3 (a PWM-capable pin)
- Potentiometer:
- Left Pin → Arduino GND pin
- Middle Pin (Wiper) → Arduino analog pin A0
- Right Pin → Arduino pin 8 (defined as VCC2 in the code)
Code Explanation
The code for this project is elegantly simple. It leverages a few key Arduino functions to read the potentiometer and control the servo. Let's focus on the user-configurable parts that you can adjust for your own projects. (in video at 03:00)
At the top of the sketch, you will define the pins and create the servo object. These are the primary variables you will change based on your wiring:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int potpin = A0; // analog pin used to connect the potentiometer
int servoPin = 3; // define a digital pin (with PWM) for servo. Can use only pin 3, 5, 6,9, 10, 11
int VCC2 = 8;// define extra VCC for potentiometer
int val; // variable to read the value from the analog pin
Here is what each part does:
- Servo myservo;: This line creates an object named
myservothat we will use to control our specific servo motor. You can rename it, but you must use the same name later in the code. - int potpin = A0;: This defines which analog pin the potentiometer's wiper is connected to. If you move the wire to a different analog pin, you must update this number.
- int servoPin = 3;: This sets the digital pin for the servo's signal wire. It is crucial to use a PWM-capable pin (usually those marked with a '~' on the board). The comment lists the valid pins for most Arduinos.
- int VCC2 = 8;: This is the pin we are using as a secondary 5V source for the potentiometer. If you have a board with multiple 5V pins, you can connect it directly and remove this part of the code.
In the setup() function, the code initializes the servo and sets up the extra power pin. The myservo.attach(servoPin) function is essential as it tells the Arduino which pin is connected to the servo's signal wire.
void setup() {
Serial.begin(9600); // setup serial
myservo.attach(servoPin); // attaches the servo on pin 3 to the servo object
pinMode(VCC2, OUTPUT);// set pin 8 as output
digitalWrite(VCC2, HIGH);// set pin 8 HIGH so it acts as 5V pin
}
The core logic is in the loop() function. It reads the potentiometer's value, scales it to an angle, and commands the servo to move. The two critical functions here are analogRead() and map(). (in video at 04:27)
void loop() {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
Serial.print(val);
Serial.println();
delay(50); // waits for the servo to get there
}
Here is how it works:
- analogRead(potpin): This function reads the voltage from the potentiometer's wiper and returns a value between 0 (0V) and 1023 (5V).
- map(val, 0, 1023, 0, 180): This is the key to the whole project. It takes the raw value from the potentiometer (0 to 1023) and proportionally converts it to a servo angle (0 to 180 degrees). For example, if the potentiometer reads 511 (about half), the
map()function will return 90, moving the servo to its center position. - myservo.write(val): This function takes the calculated angle (now stored in
val) and tells the servo to rotate to that position. - delay(50): This adds a small pause at the end of each loop. It controls the update rate. A larger delay (like 200ms) makes the servo move in steps, while a smaller delay (like 50ms) makes the movement very smooth. You can adjust this to change the responsiveness. (in video at 07:26)
Live Project Demonstration
In the video, you can see the project in action. As the potentiometer knob is turned, the servo motor's arm follows its position proportionally. The serial monitor prints the current angle, confirming that the mapping is working correctly. When the potentiometer is at its minimum position, the servo is at 0 degrees. As you turn the knob to its maximum, the servo smoothly rotates to 180 degrees. (in video at 06:33)
This real-time feedback loop demonstrates the seamless integration of an analog sensor with a digital actuator, creating a responsive and intuitive control system.
Chapters
- [00:00] Introduction and Project Overview
- [01:05] Schematic and Wiring Diagram
- [02:07] Physical Wiring Demonstration
- [03:00] Code Explanation
- [06:33] Live Demonstration and Testing
- [07:26] Adjusting Servo Response Speed
/*
* Lesson 88: Controlling Servo motor a with Potentiometer
* 📚⬇️ Download and resource page https://robojax.com/RJT763
watch full video tutroial: https://www.youtube.com/watch?v=ntRW77mNFFk
Controlling a servo position using a potentiometer (variable resistor)
by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
modified on 8 Nov 2013
by Scott Fitzgerald
http://www.arduino.cc/en/Tutorial/Knob
Update by Ahmad Shamshiri on Jan 01, 2019 in Ajax, Ontario, Canada
*/
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int potpin = A0; // analog pin used to connect the potentiometer
int servoPin = 3; // define a digital pin (with PWM) for servo. Can use only pin 3, 5, 6,9, 10, 11
int VCC2 = 8;// define extra VCC for potentiometer
int val; // variable to read the value from the analog pin
void setup() {
//
Serial.begin(9600); // setup serial
myservo.attach(servoPin); // attaches the servo on pin 3 to the servo object
pinMode(VCC2, OUTPUT);// set pin 8 as output
digitalWrite(VCC2, HIGH);// set pin 8 HIGH so it acts as 5V pin
}
void loop() {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
Serial.print(val);
Serial.println();
delay(50); // waits for the servo to get there
}
Things you might need
-
Amazon
-
Amazon
-
eBay
-
AliExpressPurchase SG90 servo motor 180 or 360 from AliExpresss.click.aliexpress.com
Resources & references
Files📁
Other files
-
SG90 Servo motor datasheet
robojax-servo-SG90_datasheet.pdf0.12 MB