Arduino Servo with Potentiometer: A Beginner's Guide to Controlling a Servo Motor Using an Arduino Uno with control from a Potentiometer

Introduction

Arduino Servo with Potentiometer: Welcome to this beginners tutorial on using an Arduino Uno to control a servo motor with a potentiometer. Servos and potentiometers are very common components for introductory robotics and electronics projects. 

arduino servo with poentiometer - servo on bench in holderBeing able to accurately position a servo to match the rotation of a knob or dial is useful for building simple robotic arms, volume controls, and other interactive prototypes.

This tutorial will guide you step-by-step through wiring up an Arduino, connecting a standard servo and potentiometer, uploading some simple Arduino code, and testing it out. By the end, you will have a working demo that allows real-time control over a servo's angular position just by twisting the potentiometer knob.


How to solve switch bounce problems

The components and code used are very beginner friendly. No complex programming or electronics skills are required. With just the basic parts listed and following the instructions, anyone can have success with this project. I hope you find this tutorial helpful as a starting point for your robotics and programming adventures.

Overview: In this tutorial, we will learn how to control the movement of a small servo motor by attaching it to an Arduino Uno board and reading the position of a potentiometer or variable resistor. This project allows you to control the angle of a servo by rotating the potentiometer knob.

There is one very important point you should know and that is:

    No Two Servos are the same!

They are not designed as precision devices. It is likely that when you command the servo to go to the zero or 180 Degree positions, it will be inaccurate.

Warning: Each servo motor is unique and may need calibration.

This tutorial will also show you how to correct that and calibrate your servo motor.

Required Components

  • Arduino Uno board
  • Servo motor (type SG90)
  • Potentiometer (10k ohm recommended)
  • 100uF Electrolytic capacitor
  • Jumper wires
  • Breadboard

Arduino servo with potentiometer: Circuit Diagram

The wiring is very simple. Connect one leg of the Arduino servo pot to the 5V pin on the Arduino. Connect the middle leg to analog pin A1. Connect the other leg to ground. Connect the power/positive leg of the servo to the 5V pin. Connect the ground leg to ground. Connect the signal leg to digital pin 11.

Warning: Servos can have different wire colours: Red = 5V, Black or brown = 0V, White/Orange/Other = PWM control.

The electrolytic capacitor will smooth out the power supplied to the servo motor. When the servo moves high current is drawn which the Arduino may not be able to fully supply and this results in jerky motion of the servo.

Adding the capacitor solves this - you probably need 100uF per servo. In addition for lots more servos you will need a separate higher current output 5V supply - just for the servos.

arduino servo with potentiometer layout diagram
Diagram using fritzing

arduino servo with potentiometer schematic

Diagram using fritzing

Arduino IDE and Libraries

The code for the Arduino servo library is already integrated into the Arduino IDE environment, so you don't need to install the servo library.

All you do is include the library using the include operation at the top of your program

#include <Servo.h>

...and then use the Servo functions as needed (see code below).

Arduino servo with potentiometer: Example Sketch Ex1

The following Arduino servo potentiometer code gives you simple code to implement control of a servo motor using a potentiometer.

You can copy and paste the code below into the Arduino IDE (in a new sketch) replacing everything that is in the new sketch window (See "Uploading the code" below).

#include <Servo.h>

Servo myservo;
const int potPin = A1;
const int servoPin = 11;

void setup() {
  myservo.attach(servoPin);
}

void loop() {
  int val = analogRead(potPin);
  val = map(val, 0, 1023, 0, 180);
  myservo.write(val);
  delay(15);
}

sketch: arduino_servo_with_potentiometer_ex1.ino

This Arduino Servo with Potentiometer code reads the value of the potentiometer on analog pin A1, maps it to a value between 0-180 degrees for the servo, and writes that value to control the servo position.

Test It Out

Upload the Arduino Servo with Potentiometer code to your Arduino. Rotate the potentiometer knob and watch the servo move to match the position. You now have a functioning motor position controller using just a potentiometer for input!

What you may notice, is that the servo positions do not do a true 180 Degrees and that is why you need the following program to figure out the calibration values for the servo.

Arduino servo with potentiometer: Example Sketch Ex2

This program uses the serial port to allow you to enter pulse width time period (PWM signal) to command the servo to move. This time however, the angle is set by the length of output pulse signal sent to the servo in microseconds instead of an angle in degrees.

This is done because the servo library allows you to enter the minimum and maximum values of the control signal and they are not as you would expect, between 1000us and 2000us.

	myServo.attach(11, MIN_PULSE, MAX_PULSE); 	

These MIN_PULSE and MAX_PULSE values define the servo positions corresponding to 0 Degrees and 180 Degrees respectively i.e. these allow you to calibrate the servo to get the 0 and 180 Degree positions accurate.

The library actually allows you to specify the output between the following
values:

    544us and 2400us.

The following program will allow you to observe the servo and figure out these values i.e. you will calibrate the servo. Once you have done this use these values for that specific servo (each servo may be different and require different calibration values).

#include <Servo.h>

int MIN_PULSE = 1000;
int MAX_PULSE = 2000;

Servo myservo;
const int potPin = A1;
const int servoPin = 11;

int servoPos = 0;

void setup() {
  Serial.begin(9600);
  myservo.attach(servoPin, MIN_PULSE, MAX_PULSE);
}

void loop() {
int val;

  if(Serial.available() > 0){
  char input = Serial.read();

    if (input == 'l') {
      val = Serial.parseInt();  
      if (val>=544) {
        MIN_PULSE =  val;      
      } else {
        Serial.println("Too small <544");
        MIN_PULSE = 544;
      }

      show_values();
      myservo.detach();
      myservo.attach(servoPin, MIN_PULSE, MAX_PULSE);

    } else if(input == 'h') {  
      val = Serial.parseInt();  
      if (val<=2400) {
        MAX_PULSE = val;
      } else {
        Serial.println("Too big >2400");
        MAX_PULSE = 2400;
      }

      if (val<1200) MAX_PULSE= 1200;

      show_values();
      myservo.detach();  
      myservo.attach(servoPin, MIN_PULSE, MAX_PULSE);

    } else if(input == 'v') {
      show_values();
    } else if(input == 't') {      
      Serial.println("toggle between 0 and 180");
      toggleServo();

    } else if(input == '0') {      
      Serial.println("Set pos 0");
      servoPos = 0;
      myservo.write(servoPos);

    } else if(input == '1') {      
      Serial.println("Set pos 180");
      servoPos = 180;
      myservo.write(servoPos);

    } else if(input == 'r') {      
      Serial.println("Reset high and low");
      MIN_PULSE = 1000;
      MAX_PULSE = 2000;
      myservo.write(servoPos);

    } else if(input == '?') {      
       Serial.println("0 - Set pos 0");
       Serial.println("1 - Set pos 180");
       Serial.println("t - toggle between 0 and 180");
       Serial.println("h<n> - set high us value (180 degree position)");
       Serial.println("l<n> - set low  us value (0 degree position)");
       Serial.println("r - set high and low to 2000,1000us");
       Serial.println("v - print h & l us");
       servoPos = 0;
       myservo.write(servoPos);
    }
     
  } // Serial input  
}

void toggleServo() {

  if(servoPos == 0)
    servoPos = 180;  
  else
    servoPos = 0;
  Serial.print("Position ");
  Serial.println(servoPos);
 
  myservo.write(servoPos);
}

void show_values(void) {
  Serial.print("MIN_PULSE = ");
  Serial.print(MIN_PULSE);
  Serial.println(";") ;
  Serial.print("MAX_PULSE = ");
  Serial.print(MAX_PULSE);
  Serial.println(";") ;
}

sketch: arduino_servo_with_potentiometer_ex2.ino

Using the calibration code

The code is driven using the serial port as a serial commander. The commands are as follows:

0 - Set pos 0
1 - Set pos 180
t - toggle between 0 and 180
h<n> - set high us value (180 degree position)
l<n> - set low  us value (0 degree position)
r - set high and low to 2000,1000us
v - print h & l us

Intially the max. and min. pulse outputs are set to 1000 and 2000. Press the toggle key to move between 0 and 180 Degrees. You will probably find that it does not move far enough. So enter l<num> and h<num> for the new pulse settings. For example:

l800
h2200

Now enter 't' to toggle the new servo positions. Continue until you are happy with the results. Type in 'v' the see the values you entered. You can use these to calibrate the servo - place these numbers into you servo code for initialisation.

Uploading the Code

There are a few steps to uploading the code using the Arduino IDE:

  • Connect the Arduino Uno to the PC with a USB cable.
  • Select the Arduino Uno hardware.
  • Open a new sketch.
  • Paste the code above into the new page (overwrite everything).
  • Press the upload button (right arrow at top).

You can find a more detailed tutorial on the Arduino IDE page.

Conclusions

In this tutorial, you learned the basics of controlling a servo motor with an Arduino. By connecting a servo, potentiometer and the Arduino board, you created a simple circuit to link the rotation of a knob to movement of the motor. Uploading some sample code allowed you to test how adjusting the potentiometer changed the angular position of the servo in real-time.

You also explored calibrating servos for precise rotation. By sending pulse-width signals directly, you learned how to set minimum and maximum pulse widths to ensure the servo could accurately reach 0 and 180 degree positions.

Understanding servo calibration is important for applications that require position control. The skills you gained in controlling a servo with an analog input provide a foundation for more complex robotics and automation projects using an Arduino board.


I hope this basic tutorial on using "An Arduino, a potentiometer and a servo motor" helps you get started controlling servos with an Arduino. Let me know if you have any other questions!



Written by John Main who has a degree in Electronic Engineering.

Note: Parts of this page were written using claude-instant as a research assistant.





Comments

Have your say about what you just read! Leave me a comment in the box below.

Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.



Privacy Policy | Contact | About Me

Site Map | Terms of Use