Interaction Design WikiElectrical Engineering

Servo Motors

Servo motors are actuators that allow the precise control of the angle of the axel. Typical servo motors are constructed from a regular DC motor, combined with a gear ratio, potentiometer to measure the final position of the axel some digital components to control the motor. Most servo motors are limited to a certain range of angles, often between 0 and 180 degrees. 

Common types of hobby servos read PWM signals and convert this into angles. The easiest way to generate the correct PWM signal for a given angle is to use the Servo library in Arduino. 

Basic Servo
#include <Servo.h>

Servo myservo;  // create servo object 
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
  }
}


We can also add some easing, to smooth out the movements of the servo and achieve a more organic movement. The algorithm used here is the same seen in Signal Filtering.

Easing servo
#include <Servo.h>

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

int angle = 160;  // goal angle of servo
float easedAngle;  // for storing an eased position between current and goal angle
int lastChange;    // Used for timing changes of angle

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

void loop() {
  // change the goal angle every 5000 miliseconds
  if (millis()>= lastChange+5000) {
    lastChange = millis();
    if (angle == 160) {
      angle = 20;
    } else {
      angle = 160;
    }
  }
  easedAngle = angle*0.02 + easedAngle*0.98;
  Serial.print(angle);
  Serial.print(",");
  Serial.println(int(easedAngle)); 
  myservo.write(easedAngle);   
  delay(10);
}