Servo Control via Potentiometer

This tutorial explains how to directly interface with a servo via a potentiometer, using an Arduino. It ensures that the input and output are calibrated correctly, so that the servo and potentiometer remain in sync, and allows you to view readings through a serial viewer. When writing this code, I used extracts from the calibrate example in the Arduino library, and code from the Michal Rinott tutorial on the arduino.cc site.

In case you didn’t know, a potentiometer is a variable resistor, which can be used to adjust a power output according to how far open / closed it is. With the Arduino you can read this change as an analog input, allowing for high control over inputs. I used a potentiometer from spark fun. It is actually called a Trimpot, but this is basically just a really small potentiometer. You could use a bigger one if you prefer.  On the potentiometer you should have three pins, to wire it up, connect the left hand pin to the 3.3v power supply on the Arduino. Then connect the centre pin to analog pin 1 (A1) on your Arduino, and the right hand pin to the ground pin on the Arduino (place a 330 ohm resistor in-between the right hand pin and the ground pin).

Using this code, you should be able to read the analog output of the potentiometer in a serial viewer.

//Reading the value of a potentiometer and displaying it on a serial output
//Created by Jacob Unwin, using code from Michal Rinott tutorial

int sensorValue = 0;         // the sensor valueint sensorMin = 1023;        // minimum sensor value
int sensorMax = 0;           // maximum sensor value
int sensor = 1;  // analog pin used to connect the potentiometer

void setup()
{

  Serial.begin(9600); //start serial output

}

void loop()
{
  sensorValue = analogRead(sensor);            // reads the value of the potentiometer (value between 0 and 1023)
  Serial.print(sensorValue);  //print the servo value in degrees in the serial monitor
  Serial.println();

}

Now its time to wire up the servo. This is more complicated, as it needs an external power supply to ensure you don’t burn out your Arduino. You will need a switch, a 6v power pack (a set of 4 aa batteries in a holder will do), and a smallish servo. Plug the battery back into the switch, so that you can use it to turn the battery pack on and off. Alternatively you could just unplug the battery pack each time you wan’t to turn off the Arduino. You will find 3 coloured wires coming out of the servo. Connect the red one to the power packs positive wire (probably red), and connect the black wire to the ground strip on your breadboard. To the same ground strip connect a ground wire to the Arduino, and another to the power pack. Whilst you are doing this, make sure the power pack is turned off. Finally, connect the white or yellow wire on the servo to pin 9 on the Arduino. This is the control wire, which we will use to control the rotation of the servo.

 

 

I also connected an additional momentary push button to my Arduino, which allows for the device to be re-calibrated whilst in use. You’d don’t need to do this, it is just personal preference. Connect the left hand pin to the 3.3v power supply,and the right hand pin of the button to pin 7 on the Arduino and to the Arduino’s ground pin (via a 330 ohm resistor).

To use this code, you will need to download and install the Servo library.

If it is wired up correctly, plug in the Arduino, turn on the power pack, and then upload the code. The servo should move in sync with the potentiometer.

 
// Controlling a servo position using a potentiometer (variable resistor)
// Added callibration function to ensure accurate control of servo
// Written by Jacob Unwin, code used from Michal Rinott tutorial

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int sensorValue = 0;         // the sensor value
int sensorMin = 1023;        // minimum sensor value
int sensorMax = 0;           // maximum sensor value

int sensor = 1;  // analog pin used to connect the potentiometer
int button = 7;

int buttonVal = 0; // sets the value
int state = 0; //sets the state
int old_val = 0; //stores the previous value

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(button, INPUT); //sets the button as an input

  myservo.write(180);

  // calibrate during the first five seconds
  while (millis() < 5000) { //for the first five seconds
    sensorValue = analogRead(sensor);

    // record the maximum sensor value
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }

    // record the minimum sensor value
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }
  }

  // signal the end of the calibration period
  myservo.write(0);

  Serial.begin(9600); //start serial output
}

void loop()
{
  buttonVal = digitalRead(button);
  sensorValue = analogRead(sensor);            // reads the value of the potentiometer (value between 0 and 1023)
  sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(sensorValue);                  // sets the servo position according to the scaled value
  sensorValue = constrain(sensorValue, 0, 179); //in case the sensor value is outside the range seen in callibration
  delay(15);                           // waits for the servo to get there

  Serial.print("servo = " );
  Serial.print(sensorValue);  //print the servo value in degrees in the serial monitor
  Serial.println();

  if((buttonVal==HIGH) && (old_val==LOW)){ //checks if there was a transition between old and new val
  state = 1 - state; //sets the state
  delay(10); //sets a delay of 10
}

old_val = buttonVal; //stores the new value as the old value

if (state==1) {

  calibrate();
}

}

void calibrate(){

  myservo.write(180);

  // calibrate during the first five seconds

    sensorValue = analogRead(sensor);

    // record the maximum sensor value
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }

    // record the minimum sensor value
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }

  // signal the end of the calibration period
  myservo.write(0);

  delay (2000);

}

35 comments

  1. I wanted to create you that very little note so as to give many thanks once again just for the wonderful ideas you have provided on this page. This has been so seriously generous with people like you to give unreservedly just what a lot of folks could possibly have offered for sale for an e book to generate some money for their own end, specifically considering the fact that you might have done it if you ever considered necessary. Those good tips additionally worked like a great way to recognize that other individuals have a similar fervor really like mine to realize a lot more on the subject of this matter. I believe there are a lot more pleasant sessions ahead for individuals who look over your site.

  2. Good submit. I’ve been studying your blog for some time now. I wanted to ask, are you currently currently looking for support with doing posts here? Possibly even a visitor writer? Be sure to let me know. Thank you.

  3. I’ll immediately grasp your rss as I can not in finding your e-mail subscription hyperlink or e-newsletter service. Do you’ve any? Please permit me understand in order that I could subscribe. Thanks.

  4. hey hey!! this is a very nice website here and I just wanted to comment & say that you’ve done a great job here! Very nice choice of colors & layout, very easy on the eyes.. Nicely done!…

  5. you are actually a good webmaster. The web site loading velocity is amazing. It seems that you are doing any distinctive trick. Also, The contents are masterpiece. you have performed a wonderful task on this matter!

  6. I’m more than happy to uncover this web site. I wanted to thank you for ones time just for this fantastic read!! I definitely loved every bit of it and i also have you bookmarked to see new things on your blog.

  7. I have adopted your blog for some time and must say that this time you hit the actual nail together with precision because never, I’ve almost the same thought and also ideals as you’ve, keep coming along with gold posts like this you’ll also find a follower for life!

  8. Hi you all, good blog. I am very happy to have founded it. I am getting a lot of useful information here. I will bookmark it surely. Thanks to the webmaster. See you all.

  9. Magnificent web site. A lot of useful info here. I¡¦m sending it to some pals ans also sharing in delicious. And naturally, thank you for your sweat!

  10. It was a really nice concept! Just wanna say thank you for the information you’ve gotten diffused. Just proceed composing this sort of post. I shall be a loyal reader, thanks a lot.

  11. Hi all, interesting blog. I am very happy to have founded it. I am getting some interesting info here. I ‘ll bookmark it for sure. Thank you to the webmaster. Have a nice day.

  12. I would like to thank you for the efforts you have put in penning this website. I’m hoping to check out the same high-grade blog posts by you later on as well. In fact, your creative writing abilities has motivated me to get my very own website now ;)

  13. I simply want to tell you that I am all new to blogging and honestly loved your web site. Likely I’m planning to bookmark your site . You surely have really good articles. Regards for sharing your blog.

    • It’s a possibility that could definitely be implemented, but writing to the EEPROM comes with a delay of 3ms, and although the supposed limit of 100000 read/writes doesn’t seem like a problem, it can add up quiet quickly.

      If you wanted to find the position of the servo, you could use a timer to measure how long it takes to get to the end of its rotation, and compare that to the time it takes for its complete motion to find its position.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>