STEP 2 : Smooth Servo Motion

You may have noticed that the servos move very quickly. This can lead to very harsh movements and endanger both the servos and the project you are building. The next step is therefore to make the movement of the servos slower and more controllable. For this it is necessary to know the current position of the servo. Unfortunately, there is no way to query the current position of a servo, so we have to remember it ourselves.

The following program defines a class "SmoothServo" which represents a smooth moving and better controlable servo. A SmoothServo remembers the current position and rotates slowly and safely to the new target position when needed.

  

/* Arduino Servo Tutorial
 * Gently moving a servo
 * Stefan Hager 2022
 * 
 * 
 * Note: it is important that the servo is already in 
 * the position provided to the constructor
 */

#ifndef _SMOOTH_SERVO_H_
#define _SMOOTH_SERVO_H_
 
#include <Servo.h>
#include "Arduino.h"


 
 class SmoothServo
 {
   private:
    int pin, currentPos, speed; 
    Servo servo;
   public:
    SmoothServo(int _pin, int _currentPos, int _speed); // constructor
    void start();
    void moveToTargetPosition(int _angle);
 };

  #endif
    
/* Arduino Servo Tutorial
 * Gently moving a servo
 * Stefan Hager 2022
 */

#include "smooth_servo.h"

// initialize the smooth moving servo

SmoothServo::SmoothServo(int _pin, int _currentPos, int _speed)
{ pin = _pin;
  speed = _speed;
  currentPos =  _currentPos;  
}

void SmoothServo::start()
{ 
  servo.attach(pin);
  servo.write(currentPos);
}

void SmoothServo::moveToTargetPosition(int target_angle)
{
  if(target_angle < 0)
    target_angle = 0;
  if(target_angle > 180)
    target_angle = 180;

  if(currentPos <= target_angle)
  {
    while(currentPos <= target_angle)
    {
      currentPos = currentPos + speed;
      servo.write(currentPos);
      delay(20);
    }
  }

  if(currentPos >= target_angle)
  {
    while(currentPos >= target_angle)
    {
      currentPos = currentPos - speed;
      servo.write(currentPos);
      delay(20);
    }
  }
}

  

/* Arduino Servo Tutorial
 * Gently moving a servo
 * 
 * Servo is on pin 9, starts at 90 degrees ans sets speed to 2
 * Stefan Hager 2022
 */

#include "smooth_servo.h"
SmoothServo servo(9,90,2);

void setup() 
{
  // opens serial port, sets data rate to 9600 bps
  Serial.begin(9600); 
  servo.start();
}

void loop() 
{ 
  Serial.println("Insert target value (0 to 180 degrees): "); 
  int value = readnextValue();
  servo.moveToTargetPosition(value);
  Serial.println(value);
  delay(1000);
}


// reads one number from serial and deletes 
// all misleading characters

 
int readnextValue()
{

  while (Serial.available() == 0) 
  {
    // empty loop - we are still waiting for a real value
  } 
  // read the incoming value
  int value = Serial.parseInt();
  // clears the serial buffer
  while(Serial.available() > 0) {
    char t = Serial.read();
  }
  return value;
}

Running the program

Once the program has been uploaded, you can enter the desired position via the serial monitor. You will notice that the servo changes its position very smooth and slowly. If it is too slow for your application you can increase the speed when you create the "SmoothServo" object.