Ramp up and Ramp down using AccelStepper library

Hi, I am trying to control the stepper motor to rotate by 90 degrees over 10 seconds with 2 seconds ramp up/accelerate and 2 seconds ramp down/decelerate. Acceleration is working fine but deceleration is not going through and the motor stops. Could you help diagnose what I am missing in the code below?

I am not a programmer and learning to control stepper motors for a DIY project.

/*
Controlling Stepper with the AccelStepper library; 3200 steps per rotation
Rotate the motor by 90 degrees or 800 steps over 10 seconds, 2 seconds to ramp up/acceleration, 6 seconds at constant speed and 2 seconds ramp down/deceleration

*/

#include <AccelStepper.h>

// Define the stepper motor and the pins that is connected to
AccelStepper stepper1(1, 2, 5); // (Typeof driver: with 2 pins, STEP, DIR)

void setup() {

  stepper1.setMaxSpeed(100); // Set maximum speed value for the stepper; 3200 steps per rotation
  stepper1.setAcceleration(25); // Set acceleration value for the stepper
  stepper1.setCurrentPosition(0); // Set the current position to 0 steps

}

void loop() {

  stepper1.moveTo(700); // Set desired move: 100 steps with ramp up and 600 steps at constant speed
  stepper1.runToPosition(); // Moves the motor to target position w/ acceleration

}


void setup() {

  stepper1.setMaxSpeed(100); // Set maximum speed value for the stepper; 3200 steps per rotation
  stepper1.setAcceleration(-25); // Set deceleration value for the stepper
  stepper1.setCurrentPosition(700); // Set the current position to 0 steps

}

void loop() {

  stepper1.moveTo(800); // Set desired move: 100 steps with ramp down
  stepper1.runToPosition(); // Moves the motor to target position w/ deceleration and it blocks until is in position

}


A standard Arduino sketch would have only one "setup()" function and only one "loop()" function. Something like this (not tested).

/*
  Controlling Stepper with the AccelStepper library; 3200 steps per rotation
  Rotate the motor by 90 degrees or 800 steps over 10 seconds, 2 seconds to ramp up/acceleration, 6 seconds at constant speed and 2 seconds ramp down/deceleration
*/

#include <AccelStepper.h>

// Define the stepper motor and the pins that is connected to
AccelStepper stepper1(1, 2, 5); // (Typeof driver: with 2 pins, STEP, DIR)

void setup() {
  stepper1.setMaxSpeed(100); // Set maximum speed value for the stepper; 3200 steps per rotation
  stepper1.setAcceleration(25); // Set acceleration value for the stepper
  stepper1.setCurrentPosition(0); // Set the current position to 0 steps

  rampup();

  stepper1.setMaxSpeed(100); // Set maximum speed value for the stepper; 3200 steps per rotation
  stepper1.setAcceleration(-25); // Set deceleration value for the stepper
  stepper1.setCurrentPosition(700); // Set the current position to 0 steps

  rampdown();
}

void rampup() {
  stepper1.moveTo(700); // Set desired move: 100 steps with ramp up and 600 steps at constant speed
  stepper1.runToPosition(); // Moves the motor to target position w/ acceleration
}

void rampdown() {
  stepper1.moveTo(800); // Set desired move: 100 steps with ramp down
  stepper1.runToPosition(); // Moves the motor to target position w/ deceleration and it blocks until is in position
}
  1. It doesn't compile with the two setups/loops.

  2. You can't set negative acceleration:

vs

https://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html#adfb19e3cd2a028a1fe78131787604fd1

and:

It sounds like you are making it too complicated.
AccelStepper will ramp up and ramp down automatically. The trick you need is to calculate the right steps/sec/sec acceleration to fit your desired profile, and that will take some math. 25steps/sec/sec seems like it would take 4 sec to get to the 100steps/sec cruising speed. I'm not going to do the math for you, but the standard physics equations of motion of s=1/2at^2, v=at and s=vt would apply and should add up to your s=800 steps. You could set a=v_cruise/2sec and then work out what v_cruise needs to be and then the rampup/rampdown is handled by just:

stepper1.moveTo(800);
1 Like

This works here, although I can't imagine what the resulting action would be for.

/*
Controlling Stepper with the AccelStepper library; 3200 steps per rotation
Rotate the motor by 90 degrees or 800 steps over 10 seconds, 2 seconds to ramp up/acceleration, 6 seconds at constant speed and 2 seconds ramp down/deceleration

*/

#include <AccelStepper.h>

// Define the stepper motor and the pins that is connected to
AccelStepper stepper1(1, 2, 5); // (Typeof driver: with 2 pins, STEP, DIR)

void setup() {

  stepper1.setMaxSpeed(100); // Set maximum speed value for the stepper; 3200 steps per rotation
  stepper1.setAcceleration(25); // Set acceleration value for the stepper
  stepper1.setCurrentPosition(0); // Set the current position to 0 steps

}

void loop() {

  stepper1.moveTo(700); // Set desired move: 100 steps with ramp up and 600 steps at constant speed
  stepper1.runToPosition();
  stepper1.moveTo(800);
  stepper1.runToPosition(); // Moves the motor to target position w/ acceleration
}


Doing the math gives a = 50steps/sec/sec and v_cruise = 100steps/sec so that stepper1.moveTo(800) takes 10 seconds with a 2 second rampup and 2 second rampdown.

Try editing the AccelStepper Bounce example to use an acceleration of 50steps/sec/sec and a +/-400 travel.

void setup()
{  
  // Change these to suit your stepper if you want
  stepper.setMaxSpeed(100);
  stepper.setAcceleration(50);
  stepper.moveTo(400);
}

After the initial 6-second half-motion, you get a 10 second bounce with 2sec ramps.

Yes, I dont need to add deceleration separately. AccelStepper Acceleration function takes care of that automatically. Now the code is very clean and straight forward. Thanks for catching this and sharing simulation!

1 Like

Thank you! There is a compilation problem with negative acceleration values. The acceleration function in the library takes care of deceleration by itself as pointed out by @DaveX

1 Like