# AccelStepper Library: Problems when switching between accelerated and constant

I use the phantastic AccelStepper Library by Mike McCauley to control two stepper motors. Sometimes I need the movement to be accelerated, other times to be constant.

My program behaves very strange: When I use a non-accelerated movement followed by an accelerated movement, both steppers move very slow (3 steps per second or so) for about 5 seconds before doing the accelerated movement they should be doing.

The library supports both accelerated and non-accelerated movements.
Generally, accelerated movements work by doing something like this:

``````stepperL.setMaxSpeed(144);
stepperR.setMaxSpeed(144);
stepperL.setAcceleration(200);
stepperR.setAcceleration(200);
stepperL.move(500);
stepperR.move(500);
void loop() {
if (stepperL.distanceToGo() != 0 || stepperR.distanceToGo() != 0) {
stepperL.run();
stepperR.run();
}
}
``````

Non-accelerated movements (constant speed) work by doing something like this:

``````stepperL.setSpeed(144);
stepperR.setSpeed(144);
stepperL.move(500);
stepperR.move(500);
void loop() {
if (stepperL.distanceToGo() != 0 || stepperR.distanceToGo() != 0) {
stepperL.runSpeedToPosition();
stepperR.runSpeedToPosition();
}
}
``````

The following is my code which tries to combine the two. If a ist set to 1, I want the movement to be accelerated. Otherwise it should be constant.

``````#include <AccelStepper.h>

// Define two steppers and the pins they will use
AccelStepper stepperR(1, 9, 8);
AccelStepper stepperL(1, 7, 6);

float acceleration = 200;
boolean accelerationMode = true;
float speedL;
float speedR;

void setup() {
// Enable/disable pin for steppers
pinMode(11, OUTPUT);
digitalWrite(11, LOW); // low = enabled

// Right motor
stepperR.setEnablePin(11);
stepperR.setPinsInverted(false, false, true); // invert direction & enable pin
stepperR.enableOutputs(); // activate motor - normally happens on construction but since the enable pin is inverted, do it again
stepperR.setAcceleration(acceleration);
// Left motor
stepperL.setEnablePin(11);
stepperL.setPinsInverted(true, false, true); // invert enable pin
stepperL.enableOutputs();
stepperL.setAcceleration(acceleration);
}

void loop() {

// Simplifying the code here for clarity. Every now and then (by far not at every execution of the loop), a command is executed like this:
doCommand(stepsLeft, stepsRight, useAcceleration);

// Are we busy? Set timer so that we can switch off motors after a while.
millisSinceMotorUse = millis();
}
// When no commands arrive for some time, deactivate the motors.
if (readyForNextCommand == true && (unsigned long)(millis() - millisSinceMotorUse) > disableMotorIntervall) {
// Only act if the motors are enabled
// Deactivate motors
stepperL.disableOutputs();
// Tell the server about it
Serial.write("s");
}
}

if (stepperL.distanceToGo() != 0 || stepperR.distanceToGo() != 0) {
// Drive on.
// With acceleration
if (accelerationMode == true) {
stepperL.setMaxSpeed(speedL);
stepperR.setMaxSpeed(speedR);
stepperL.run();
stepperR.run();
}
// Without acceleration
else if (accelerationMode == false){
stepperL.setSpeed(speedL);
stepperR.setSpeed(speedR);
stepperL.runSpeedToPosition();
stepperR.runSpeedToPosition();
}
}
}

void doCommand(long l, long r, long a) {
speedL = 144;
speedR = 144;
// Enable motors
stepperL.enableOutputs();
// Use acceleration?
if (a == 1) {
accelerationMode = true;
}
else if (a == 0) {
accelerationMode = false;
}
stepperL.move(l);
stepperR.move(r);
}
``````

As stated above, when I use a non-accelerated movement followed by an accelerated movement, both steppers move very slow (3 steps per second or so) for about 5 seconds before doing the accelerated movement they should be doing.

So, if I call doCommand(200,200,0) and then doCommand(200,200,1), the strange slow-mo-movement happens.

Any idea how this is happening?

I wonder are you changing the mode before the previous movement has completed?

I can't figure that out from your code.

Why not write a very short program to explore this problem?

...R

Good idea, Robin2.

I wrote a very simple program that alternates between accelerated and non-accelerated mode. Now the accelerated movements work as expected while the non-accelerated movements are in slow-motion. Any ideas?

``````#include <AccelStepper.h>

// Define two steppers and the pins they will use
AccelStepper stepperR(1, 9, 8);
AccelStepper stepperL(1, 7, 6);

// Set some variables
float maxSpeed = 400;
float acceleration = 400;
boolean accelerationMode = false;
int accelerationCounter = 0;

void setup() {

// Enable/disable pin for steppers
pinMode(11, OUTPUT);
digitalWrite(11, LOW); // low = enabled

// Right motor
stepperR.setEnablePin(11);
stepperR.setPinsInverted(false, false, true); // invert direction & enable pin
stepperR.enableOutputs(); // activate motor - normally happens on construction but since the enable pin is inverted, do it again
stepperR.setAcceleration(acceleration);
stepperR.setMaxSpeed(maxSpeed);
// Left motor
stepperL.setEnablePin(11);
stepperL.setPinsInverted(true, false, true); // invert enable pin
stepperL.enableOutputs();
stepperL.setAcceleration(acceleration);
stepperL.setMaxSpeed(maxSpeed);
}

void loop() {

// When motors stand still, call the function that lets them run.
if (stepperL.distanceToGo() == 0 && stepperR.distanceToGo() == 0) {
doCommand(100,100);
}

// Otherwise, drive on.
if (stepperL.distanceToGo() != 0 || stepperR.distanceToGo() != 0) {
// With acceleration
if (accelerationMode == true) {
stepperL.run();
stepperR.run();
}
// Without acceleration
else if (accelerationMode == false){
stepperL.runSpeed();
stepperR.runSpeed();
}
}
}

void doCommand(long l, long r) {
// Alternate between accelerated and non-accelerated mode.
if (accelerationCounter % 2 == 0) {
accelerationMode = true;
}
else {
accelerationMode = false;
}
accelerationCounter++;
// Use acceleration?
if (accelerationMode == true) {
stepperL.setMaxSpeed(maxSpeed);
stepperR.setMaxSpeed(maxSpeed);
}
else if (accelerationMode == false) {
stepperL.setSpeed(maxSpeed);
stepperR.setSpeed(maxSpeed);
}
// Register step command for motors
stepperL.move(l);
stepperR.move(r);
}
``````

By the way, the AccelStepper website says, “DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS”. I am not sure what lists he is referring to, though, and could not find any.

I'm not sure that this line is needed - I think it will stop automatically when it reaches the target

``````if (stepperL.distanceToGo() != 0 || stepperR.distanceToGo() != 0) {
``````

I wonder if you should use runSpeedToPosition() rather than runSpeed()

I don't know if that would have any effect on the speed.

Have you tried accelerated and non-accelerated motion in two separate programs?

...R

I solved the problem by

• calling setSpeed() and setMaxSpeed() in the Loop and thus constantly instead of only when a movement is ordered.
• using runSpeedToPosition() instead of runSpeed() (good guess, Robin2)
• calling stop() before ordering a new movement.

I’m glad it works but I think there is room for improvement in the AccelStepper documentation. Better description of the functions would help preventing this trial-and-error approach :). That said, I’m still glad AccelStepper exists.

Below is the working code of my previous simplified program which alternates between accelerated and non-accelerated movement.

``````#include <AccelStepper.h>

// Define two steppers and the pins they will use
AccelStepper stepperL(1, 7, 6);
AccelStepper stepperR(1, 9, 8);

// Set some variables
float maxSpeed = 400;
float acceleration = 100;
boolean accelerationMode = false;
int accelerationCounter = 0;

void setup() {

// Enable/disable pin for steppers
pinMode(11, OUTPUT);
digitalWrite(11, LOW); // low = enabled

// Right motor
stepperR.setEnablePin(11);
stepperR.setPinsInverted(false, false, true); // invert direction & enable pin
stepperR.enableOutputs(); // activate motor - normally happens on construction but since the enable pin is inverted, do it again
stepperR.setAcceleration(acceleration);
stepperR.setMaxSpeed(maxSpeed);
// Left motor
stepperL.setEnablePin(11);
stepperL.setPinsInverted(true, false, true); // invert enable pin
stepperL.enableOutputs();
stepperL.setAcceleration(acceleration);
stepperL.setMaxSpeed(maxSpeed);
}

void loop() {

// When motors stand still, call the function that lets them run.
if (stepperL.distanceToGo() == 0 && stepperR.distanceToGo() == 0) {
doCommand(100,100);
}

// Otherwise, drive on.
if (stepperL.distanceToGo() != 0 || stepperR.distanceToGo() != 0) {
// With acceleration
if (accelerationMode == true) {
stepperL.setMaxSpeed(maxSpeed);
stepperR.setMaxSpeed(maxSpeed);
stepperL.run();
stepperR.run();
}
// Without acceleration
else if (accelerationMode == false){
stepperL.setSpeed(maxSpeed);
stepperR.setSpeed(maxSpeed);
stepperL.runSpeedToPosition();
stepperR.runSpeedToPosition();
}
}
}

void doCommand(long l, long r) {
stepperL.stop();
stepperR.stop();
// Alternate between accelerated and non-accelerated mode.
if (accelerationCounter % 2 == 0) {
accelerationMode = true;
}
else {
accelerationMode = false;
}
accelerationCounter++;
// Register step command for motors
stepperL.move(l);
stepperR.move(r);
}
``````

I know this thread is a few months old, but on the main AccelStepper library page there is a link to the Google Groups page for AccelStepper.

The forum there has a number of people experienced with the library, helping with issue like this.

I will say the library is fantastic for what it does, but it does have a somewhat steep learning curve for some of the features.