void AccelStepperDriver::computeNewSpeed() {
long distanceTo = distanceToGo(); // +ve is clockwise from curent location
long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
if (distanceTo == 0 && stepsToStop <= 1) {
// We are at the target and its time to stop
_stepInterval = 0;
_speed = 0.0;
_n = 0;
return;
}
if (distanceTo > 0) {
// We are anticlockwise from the target
// Need to go clockwise from here, maybe decelerate now
if (_n > 0) {
// Currently accelerating, need to decel now? Or maybe going the wrong way?
if ((stepsToStop >= distanceTo) || _direction == DIRECTION_CCW) {
_n = -stepsToStop; // Start deceleration
}
}
else if (_n < 0) {
// Currently decelerating, need to accel again?
if(stepsToStop < distanceTo && _direction == DIRECTION_CW) {
long targetStepsToStop = (long)((_maxSpeed * _maxSpeed) / (2.0 * _acceleration)); // Equation 16
if(_isAccelerating || _n > -targetStepsToStop) { // braking to reach target speed complete
_n = -_n; // Start accceleration
_isAccelerating = true;
}
}
}
}
else if (distanceTo < 0) {
// We are clockwise from the target
// Need to go anticlockwise from here, maybe decelerate
if (_n > 0) {
// Currently accelerating, need to decel now? Or maybe going the wrong way?
if ((stepsToStop >= -distanceTo) || _direction == DIRECTION_CW) {
_n = -stepsToStop; // Start deceleration
}
}
else if (_n < 0) {
// Currently decelerating, need to accel again?
if ((stepsToStop < -distanceTo) && _direction == DIRECTION_CCW) {
long targetStepsToStop = (long)((_maxSpeed * _maxSpeed) / (2.0 * _acceleration)); // Equation 16
if(_isAccelerating || _n > -targetStepsToStop) { // braking to reach target speed complete
_n = -_n; // Start accceleration
_isAccelerating = true;
}
}
}
}
// Need to accelerate or decelerate
if (_n == 0) {
// First step from stopped
_cn = _c0;
_direction = (distanceTo > 0) ? DIRECTION_CW : DIRECTION_CCW;
}
else {
// Subsequent step. Works for accel (n is +_ve) and decel (n is -ve).
_cn = _cn - ((2.0 * _cn) / ((4.0 * _n) + 1)); // Equation 13
if(_isAccelerating) { // allows deceleration to lower speeds
_cn = max(_cn, _cmin);
}
}
_n++;
_stepInterval = _cn;
_speed = 1000000.0 / _cn;
if (_direction == DIRECTION_CCW) {
_speed = -_speed;
}
}