Arduino library · Motion

ServoEasing: smooth servo movements with easing curves

The Servo library’s write() jumps a servo to an angle as fast as the motor can go. That is fine for a pointer and harsh for a robot arm, a puppet’s eyes or a camera pan, where the sudden start and stop shakes the whole build. ServoEasing by Armin Joachimsmeyer moves the servo in many small steps instead, at a speed you choose in degrees per second, and shapes the motion with an easing curve so it starts and stops gently.

Built in on Mokxi: #include <ServoEasing.hpp> and it builds, with nothing to install. Free, and no account needed.

What ServoEasing does

A ServoEasing object is a drop-in for a Servo object: attach() it to a pin, with a starting angle, and it moves there at once. easeTo() then moves to a new angle and returns when it arrives. startEaseTo() starts the same move and returns at once, and the sketch checks isMoving() until it is done, which lets several servos or other code run alongside. The curves include linear, quadratic, cubic, sine, bounce and more, each with in, out and in-out forms.

The example attaches a servo on pin 9 at 45 degrees, eases it to 135 at 90 degrees a second with a cubic in-out curve, then starts a move back to 90 and polls until it finishes. Upstream moves a started servo from a timer interrupt; in Mokxi it moves each time the sketch calls isMoving() or update(), as the library’s non-blocking examples do anyway. The PCA9685 servo board constructors are not here.

Library Manager nameServoEasing
AuthorArmin Joachimsmeyer
Include#include <ServoEasing.hpp>
#include <ServoEasing.h>
Boardsevery board Mokxi compiles for but ATtiny85
In the simulatorRuns, with a gap the note below names.
Parts it drivesHobby servo

Install it

It builds on every board Mokxi compiles for but ATtiny85.

In Mokxi it is built in: #include <ServoEasing.hpp> and the sketch compiles, with no download, no zip and no Library Manager.

On a real board, install "ServoEasing" by Armin Joachimsmeyer from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add ServoEasing to lib_deps in PlatformIO. Mokxi follows the calls of release 3.6.0, so a sketch written here builds there too.

What to know in the simulator: Upstream advances a started move from a timer interrupt; here it advances when the sketch calls isMoving() or update(), as the library’s non-blocking examples do. The PCA9685 constructors are not here.

The calls you will use

In the order a sketch meets them.

ServoEasing Servo1

One servo. Include ServoEasing.hpp in the main sketch file only; other files include ServoEasing.h.

Servo1.attach(9, 45)

Attaches to pin 9 and moves straight to 45 degrees, so the first eased move has a known start.

Servo1.setEasingType(EASE_CUBIC_IN_OUT)

The curve for the following moves. EASE_LINEAR is a constant speed; the IN_OUT forms speed up and slow down.

Servo1.easeTo(135, 90)

Moves to 135 degrees at 90 degrees a second and returns when it gets there.

Servo1.startEaseTo(90, 45)

Starts the move and returns at once. Use it when the sketch has other work to do while the servo moves.

Servo1.startEaseTo(90, 45);
while (Servo1.isMoving()) {
  // read buttons, update a display
}

Servo1.isMoving()

True until the started move is finished. Here it also advances the move, so call it often.

Servo1.setSpeed(60)

The default speed in degrees a second for moves that do not name one.

synchronizeAllServosStartAndWaitForAllServosToStop()

After setEaseTo() on several servos, starts them together so they all arrive at the same moment.

Example: A servo eased across, then started and polled

On the Arduino Uno R3. It runs in the browser exactly as printed.

sketch.ino · Arduino Uno R3
#include <ServoEasing.hpp>

ServoEasing Servo1;

void setup() {
  Serial.begin(9600);
  Servo1.attach(9, 45);
  Servo1.setEasingType(EASE_CUBIC_IN_OUT);
  Servo1.easeTo(135, 90);  // 90 degrees at 90 a second: one second, and it waits
  Serial.print("at ");
  Serial.println(Servo1.read());
  Servo1.startEaseTo(90, 45);
  unsigned long started = millis();
  while (Servo1.isMoving()) {
  }
  Serial.print("back at ");
  Serial.print(Servo1.read());
  Serial.print(" after ");
  Serial.print((millis() - started + 50) / 100 * 100);
  Serial.println(" ms");
}

void loop() {}

Wiring

  • Arduino Uno R3 9 to Hobby servo PWM
  • Arduino Uno R3 5V to Hobby servo VCC
  • Arduino Uno R3 GND to Hobby servo GND

Open it in the editor, wired and ready to run

Common errors and how to fix them

multiple definition of ServoEasing functions

ServoEasing.hpp was included in more than one .cpp or .ino tab. It holds the code itself, so include it in exactly one file and use ServoEasing.h everywhere else.

The servo jumps at power on before easing

A hobby servo goes to its last commanded angle as soon as it gets a signal. Pass the position it is likely already at as attach()’s second argument, so the first move starts from there.

startEaseTo() starts but the servo never finishes the move

Nothing is calling isMoving() or update() in Mokxi, or on a real board the timer interrupt is disabled. Poll isMoving() in loop() until it returns false.

Questions and answers

Which calls move a started servo in Mokxi?

Any of isMoving(), update(), updateAllServos() or isOneServoMoving(). Call one of them in loop() after startEaseTo() and the move advances each time.

Try ServoEasing without installing anything

Open the example, change the sketch, and keep your version in a free account.