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.
#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.
#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); }