Servo: Arduino Basics

Servo: Arduino Basics

Able to point in a specific direction or turn by degrees, this motor is a staple in home automation and robotics.

  • 15,527 views
  • 2 comments
  • 53 respects

Components and supplies

About this project

Make a wall-mounted dial to indicate today's weather conditions, your current location (à la Harry Potter), or power usage in your home. Or build brainwave-controlled wings. Or a robot arm to serve you Bellinis. The power is yours, with SERVOS!

We're using the Arduino to send these motors a position value in degrees, over PWM. We'll start with a simple back-and-forth movement, then make a little physical button-press-counter. Set up your circuit like so:

Fire up the Arduino IDE, bring up File > Examples, and scroll alllll the way down to the Servo library. Click on the Sweep example.

CODE

Go ahead and upload this, and you'll soon see your servo's arm sweeping back and forth in an arc. There's one important thing to note: At either end of its arc, the servo may pause and make little angry noises. That means that it's being driven outside its scope. We'll handle that in a minute – first, let's go through the code...

Inside the loop code, there are a couple of sub-loops: for loops. These will "trap" the Arduino in a series of re-executed steps, until a test condition is satisfied.

for (pos = 0; pos <= 180; pos += 1) {
myservo.write(pos);
delay(15);
}

The meat of the loop is in the middle {between the brackets}: the actions we take on each run. The servo, which we called myservo in the setup (or george in the video), is set to the value of the pos variable, which is usually between 0 and 180 degrees: myservo.write(pos);

Then, we wait 15 milliseconds, and loop around again.

This loop takes three arguments: info in parentheses that tells the code how to run. In this case:

  • The for loop will only be triggered if the variable pos is at 0 – which it is, when we create it at setup.
  • The second argument (our condition) checks to see whether pos is still less than 180; once the loop is triggered, we will keep looping through until that's false.
  • And finally, the third argument increments the pos variable by one. (This is an alternative to the "pos++" incrementation we learned in Code Magic.)

As long as the condition is true – that is, until pos hits 180 – the Arduino repeats the loop.

And then, it goes directly into another one! This one starts at 180, then increments the pos variable down by one, until it hits 0. At that point, the entire loop section of this sketch is complete, and the Arduino takes a deep breath and starts again. Since pos is at 0 again, we go back into the roundabout.

Calibrating your servo

So, those little unhappy groany noises at either end of the servo's arc: Although the code expects a servo that can rotate between 0º and 180º, that's not always the case. So, we'll adjust the code as needed so that it pauses only slightly at each extreme, and doesn't make the little gear-grinding sound.

All you really need to do is modify the 0 and 180 numbers, moving both toward 90, until the switchback is instantaneous and the angry noises cease.

You can also use the example code I've uploaded below, which maps each extreme to a variable (mini & maxi ) so that you only have to change it in one place each time. This code also adds a blinking LED to show you when the full code loop restarts: on for a loop, off for a loop, etc.

Now try: Dial counter

Use your new dial to track how many times a button has been pressed. Add a button, with one side connected to d2 and one to GND, and upload the code example below. This one divides the servo's range by 30, so you can track 30 button presses before the machine gets fed up and puts on its little light. Have fun!

Further reading

To learn a bit more about this, check out the Arduino docs on "for" loops.

See the whole series of Hackster 101 tutorials on Hackster and YouTube

Code

Arduino example sketch: "Sweep"C/C++
File > Examples > Servo > Sweep
/* Sweep
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}
SweepCalibratedC/C++
This sketch modifies Sweep to add calibration variables – so you don't drive your motor outside its range – and also adds a little LED feedback each time the loop finishes. My servo is called George.
/* Sweep
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo george;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position
int ledPin = 13;
int mini = 15; // servo's minimum position
int maxi = 160; // servo's maximum position

void setup() {
  george.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = mini; pos <= maxi; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    george.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = maxi; pos >= mini; pos -= 1) { // goes from 180 degrees to 0 degrees
    george.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  digitalWrite(ledPin, !digitalRead(ledPin));
}
Dial counter sketchC/C++
Count the number of button presses, and track them on a dial.
/*
Sweep
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
                // twelve servo objects can be created on most boards

int pos = 10;    // variable to store the servo position
int pushButton = 2;
int ledPin = 13;
int clicks = 0;

void setup()
{
  Serial.begin(9600);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(pushButton, INPUT_PULLUP);
  digitalWrite(ledPin, LOW);
}

void loop() {
  int buttonState = digitalRead(pushButton);
  if (buttonState == 0 && pos <= 160) {
    clicks = clicks + 1;
    Serial.print("Clicks: ");
    Serial.println(clicks);
    pos = map(clicks, 0, 29, 15, 160);
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(100);
  }
  else if (buttonState == 0) {
    digitalWrite(ledPin, HIGH); // LED goes on when the button has been pressed too many times
  }
}

Schematics

1. Arduino with servo on pin 9
Arduino servo
2. Arduino with servo & button
For the third code sample, Dial Counter :)
Arduino servo counter

Comments

Similar projects you might like

Button: Arduino Basics

by Alex Glow

  • 10,970 views
  • 0 comments
  • 11 respects

LED Blinkies: Arduino Basics

by Alex Glow

  • 5,622 views
  • 1 comment
  • 11 respects

NeoPixel LEDs: Arduino Basics

by Alex Glow

  • 43,344 views
  • 1 comment
  • 46 respects

Servo Tuning Buttons

Project in progress by Andrew Hillier

  • 1,279 views
  • 0 comments
  • 8 respects

Basic Arduino + JavaScript (Workshop)

by Alex Glow

  • 11,873 views
  • 1 comment
  • 27 respects
Add projectSign up / Login