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
}
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:
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!
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