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.
if (readyForNextCommand == false) {
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
if (digitalRead(11) == LOW) {
// 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?