We’ve already explored how to build a robot arm and control it using an ultrasonic sensor. If you want a bit more control (and to learn how dials and knobs work), you can add a potentiometer to your project. These inputs allow you to control your project using variable dials. In this guide, we’ll show you how to operate multiple servos on a robot independently with a dial for each one.
Underneath most dials and knobs is a device known as a potentiometer. This type of resistor adjusts the voltage passed through it, which can then be interpreted as a variable value. This is useful for tasks like adjusting volume, controlling brightness levels, or, as is the case in the guide we’ll be going through today, the position of a servo.
Potentiometers can come in the form of dials, knobs, and sliders, depending on the needs of your application. For this guide, we’ll be using a dial to control multiple servos on a robotic arm. This style of potentiometer usually has three pins: two pins on the outside, connected to power and ground.
The middle pin is a signal that can be attached to an analog pin on the Arduino board to measure how close to the full 5V the signal pin on the potentiometer is outputting. At one extreme, 0V passthrough and the board reads a value of 0. At the other end, the full 5V makes it through, and the board reads a value of 1,023. This provides 1,024 levels of resistance that can be measured and, accordingly, 1,024 values that can be passed to your scripts.
The materials for this project will be largely similar to our previous guide on controlling a robot arm using an ultrasonic sensor. Instead of an ultrasonic sensor, however, we’ll use a simple dial. Basic electronics kits often come with these dials, or you can buy them separately.
Arduino Uno | ![]() |
|||
Potentiometer & Dial
|
|
|||
Arduino IDE | ![]() |
|||
A Robot Kit
We used the meArm kit for our previous robot guide and we’ll be using the same kit for this one. Some forms of this kit don’t come with servos so look up the version you need. |
![]() |
You’ll also need a simple speaker module – I’m using this simple mono speaker – and a USB cable
This guide was written using the TG9z servos on the meArm kit. Depending on the specific servos you use, there may be some variation so be sure to read the documentation for your materials.
Our previous guide here goes into more detail on how the servos work, so we’ll focus on the potentiometer here, but we’ll still cover the basics where they’re relevant here. The entire code is here if you want to upload it to your Arduino and skip straight to the wiring.
#include
Servo myservo1; // create servo object to control a servo
Servo myservo2; // create servo object to control a servo
int potpinA0 = 0; // Assign analog pin to potentiometer
int potpinA1 = 1; // Assign analog pin to potentiometer
int val0 = 0; // Variable to read value from potentiometer, starts at 0
int val1 = 0; // Variable to read value from potentiometer, starts at 0
void setup() {
myservo1.attach(9); // attaches the servo on pin 9 to the servo object
myservo2.attach(10); // attaches the servo on pin 10 to the servo object
Serial.begin(9600); // This will allow you to read how far away your sensor is later
}
void loop() {
val0 = analogRead(potpinA0); // Reads potentiometer value (between 0 and 1023)
val0 = map(val0, 0, 1023, 110, 150); // Scale value to volume (value between 0 and 50)
val1 = analogRead(potpinA1); // Reads potentiometer value (between 0 and 1023)
val1 = map(val1, 0, 1023, 50, 170); // Scale value to volume (value between 0 and 50)
Serial.print(“Pin 1: “);
Serial.print(val0); // Print dial/volume position
Serial.print(“, Pin 2: “);
Serial.print(val1); // Print dial/volume position
Serial.println();
myservo1.write(val0); // Sets servo 1 according to the scaled value
delay(15); // Waits for the servo to get there
myservo2.write(val1); // Sets servo 2 according to the scaled value
delay(15); // Waits for the servo to get there
}
First, let’s take a look at the variables.
int potpinA0 = 0; // Assign analog pin to potentiometer
int val0 = 0; // Variable to read value from potentiometer, starts at 0
These are defined before the setup() function (make sure you’ve created your servo objects and included the Servo.h library here as well). The first variable, potpinA0 assigns the signal pin from the potentiometer to pin A0 on your Arduino. The second variable, val0, will be used to store the value received from this pin.
val0 = analogRead(potpinA0); // Reads potentiometer value (between 0 and 1023)
val0 = map(val0, 0, 1023, 110, 150); // Scale value to volume (value between 0 and 50)
The first line here reads the analog pin that the potentiometer is connected to and assigns the value to val0. By default, this value will be somewhere between 0 and 1023. However, this is far too high of a range for our servos, which can only rotate up to 180 degrees (and, practically speaking, even less than that as we’ll see in a bit). So, the second line is used to scale the value received from the potentiometer down to something more manageable.
The map() function is useful for this task, but figuring out which values to enter may take some trial and error. While your servos can rotate up to 180 degrees, the pieces they’re attached to may be more limited in their movement. Experiment with their range of movement to find the minimum and maximum values that these servos can reach. In my case, I found that my first servo operated between 110 degrees and 150 degrees.
With that information in mind, the map() function can remap the 0 to 1023 range down to 110 to 150. Now, if I turn the dial to its lowest point, it will return a value of 110. If I rotate it all the way to its highest point, it will return a value of 150. The degrees in between will be mapped proportionately between those two values.
Serial.print(“Pin 1: “);
Serial.print(val0); // Print dial/volume position
Serial.print(“, Pin 2: “);
Serial.print(val1); // Print dial/volume position
Serial.println();
This section will return the values for your potentiometer (after remapping) in the serial monitor. This is useful for testing values before hooking up your servos.
myservo1.write(val0); // Sets servo 1 according to the scaled value
delay(15); // Waits for the servo to get there
Finally, this command will tell the servo to rotate to the position specified after remapping the potentiometer signal. The delay command will give the program a little bit of time to complete the rotation action.
The full code includes two sets of the various commands above, with variables assigned for multiple servos, each of which can be operated independently. You can add as many servos as your board is capable of handling. Keep in mind that each servo will need its own specific range of motion in the map() function.
As with all servo projects, it’s a good idea to do as much coding work and testing as possible before hooking up your servos. When you’re ready, upload the code to your Arduino, then hook up your wiring as follows (you’ll probably need to use a breadboard for this project):
● Connect the first pin on each potentiometer to GND.
● Connect the third pin on each potentiometer to 5V
● Connect the final pin on the first potentiometer to pin A0 on the Arduino. If you’re using a second potentiometer and servo combo (as the full code does), connect it to pin A1. And so on for each potentiometer you want to add.
● Connect the power wire on your servo(s) to 5V and the ground wire to GND.
● Connect the yellow signal wire on your servo to pin 9. If you’re using a second servo, connect its signal wire to pin 10
Once everything is connected and the code is uploaded, you should be able to rotate the dials and see the corresponding movement from the servos. Each servo will operate independently with its own potentiometer; however, it is possible to control multiple servos from a single dial, or even write a sketch that automates movement along a preset path. Try adding more servos to the project and experiment with other ways to control the servos.