Skip to content

Commit 06d110f

Browse files
ekozlenkocmaglie
authored andcommitted
Update stepper library: High-speed stepping mod and timer rollover fix
When using the stepper library with a 1.8 degrees per step motor, and at high angular speeds, the current Stepper library leads to really loud and jittery rotation. This is due to the fact that the timing is calculated in milliseconds, and the delay length between steps is only 2.5 milliseconds when trying to spin at 120 rpm. Since only integer math is performed, you end up actually bouncing between different step delays, and thus speeds, from step to step instead of giving the motor a constant input. Which causes the motor to freak out. Changing the library to calculate the step delays in micros() solves that problem for any speed you can reasonably demand from your stepper motor. The down side is that the micros() counter rolls over every hour or so, and any move you perform after that point will hang your code. Easy fix for that is to add an || micros() - this->last_step_time < 0 to the while loop if statement in Stepper.cpp.
1 parent b4c5fa7 commit 06d110f

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

libraries/Stepper/src/Stepper.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
Two-wire modifications (0.2) by Sebastian Gassner
66
Combination version (0.3) by Tom Igoe and David Mellis
77
Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley
8+
High-speed stepping mod and timer rollover fix (0.5) by Eugene Kozlenko
89
910
Drives a unipolar or bipolar stepper motor using 2 wires or 4 wires
1011
@@ -18,7 +19,8 @@
1819
A slightly modified circuit around a Darlington transistor array or an L293 H-bridge
1920
connects to only 2 microcontroler pins, inverts the signals received,
2021
and delivers the 4 (2 plus 2 inverted ones) output signals required
21-
for driving a stepper motor.
22+
for driving a stepper motor. Similarly the Arduino motor shields 2 direction pins
23+
may be used.
2224
2325
The sequence of control signals for 4 control wires is as follows:
2426
@@ -70,7 +72,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2)
7072
this->step_number = 0; // which step the motor is on
7173
this->speed = 0; // the motor speed, in revolutions per minute
7274
this->direction = 0; // motor direction
73-
this->last_step_time = 0; // time stamp in ms of the last step taken
75+
this->last_step_time = 0; // time stamp in us of the last step taken
7476
this->number_of_steps = number_of_steps; // total number of steps for this motor
7577

7678
// Arduino pins for the motor control connection:
@@ -100,7 +102,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int moto
100102
this->step_number = 0; // which step the motor is on
101103
this->speed = 0; // the motor speed, in revolutions per minute
102104
this->direction = 0; // motor direction
103-
this->last_step_time = 0; // time stamp in ms of the last step taken
105+
this->last_step_time = 0; // time stamp in us of the last step taken
104106
this->number_of_steps = number_of_steps; // total number of steps for this motor
105107

106108
// Arduino pins for the motor control connection:
@@ -125,7 +127,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int moto
125127
*/
126128
void Stepper::setSpeed(long whatSpeed)
127129
{
128-
this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;
130+
this->step_delay = 60L * 1000L * 1000L / this->number_of_steps / whatSpeed;
129131
}
130132

131133
/*
@@ -144,9 +146,9 @@ void Stepper::step(int steps_to_move)
144146
// decrement the number of steps, moving one step each time:
145147
while(steps_left > 0) {
146148
// move only if the appropriate delay has passed:
147-
if (millis() - this->last_step_time >= this->step_delay) {
149+
if (micros() - this->last_step_time >= this->step_delay || micros() - this->last_step_time < 0) {
148150
// get the timeStamp of when you stepped:
149-
this->last_step_time = millis();
151+
this->last_step_time = micros();
150152
// increment or decrement the step number,
151153
// depending on direction:
152154
if (this->direction == 1) {
@@ -229,5 +231,5 @@ void Stepper::stepMotor(int thisStep)
229231
*/
230232
int Stepper::version(void)
231233
{
232-
return 4;
234+
return 5;
233235
}

0 commit comments

Comments
 (0)