Skip to content

Improvements to Stepper library #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
182 changes: 120 additions & 62 deletions libraries/Stepper/Stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,56 @@
3 1 0
4 0 0

The circuits can be found at

http://www.arduino.cc/en/Tutorial/Stepper


*/
For 4 wire configurations only, the motor can be driven with full-stepping (the default),
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to have this comment in both the .h and .cpp file? It might be easier to maintain if i was exclusively in the .h (unless this is part of convention for the project).

half-stepping, or a wave drive.

Half-stepping will halve the size of the motor's step, giving it double the resolution.
Remember that the amount of steps you pass to step() will be interpreted based on the current
value of the drive type. The sequence of control signals is as follows:

Step C0 C1 C2 C3
1 1 0 1 0
2 0 0 1 0
3 0 1 1 0
4 0 1 0 0
5 0 1 0 1
6 0 0 0 1
7 1 0 0 1
8 1 0 0 0

Wave drive mode only keeps one phase on a time. This means that the motor will use less power, but
will also only have half of the torque of full-stepping. The sequence of control signals is as
follows:

Step C0 C1 C2 C3
1 0 0 1 0
2 0 1 0 0
3 0 0 0 1
4 1 0 0 0

The circuits can be found at http://www.arduino.cc/en/Tutorial/Stepper
More info on the different types of drives can be found at
http://www.wikipedia.org/wiki/Stepper_motor#Phase_current_waveforms
*/


#include "Arduino.h"
#include "Stepper.h"

// Only even rows are used for full-stepping.
// Only odd rows are used for wave-stepping.
// All rows are used for half-stepping.
const int Stepper::STEP_VALUES[8][4] = {
{HIGH, LOW, HIGH, LOW}, // not used for wave-stepping
{LOW, LOW, HIGH, LOW}, // not used for full-stepping
{LOW, HIGH, HIGH, LOW}, // not used for wave-stepping
{LOW, HIGH, LOW, LOW}, // not used for full-stepping
{LOW, HIGH, LOW, HIGH}, // not used for wave-stepping
{LOW, LOW, LOW, HIGH}, // not used for full-stepping
{HIGH, LOW, LOW, HIGH}, // not used for wave-stepping
{HIGH, LOW, LOW, LOW} // not used for full-stepping
};

/*
* two-wire constructor.
* Sets which wires should control the motor.
Expand All @@ -59,6 +98,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2)
this->direction = 0; // motor direction
this->last_step_time = 0; // time stamp in ms of the last step taken
this->number_of_steps = number_of_steps; // total number of steps for this motor
this->drive_type = FullStep;

// Arduino pins for the motor control connection:
this->motor_pin_1 = motor_pin_1;
Expand Down Expand Up @@ -89,6 +129,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int moto
this->direction = 0; // motor direction
this->last_step_time = 0; // time stamp in ms of the last step taken
this->number_of_steps = number_of_steps; // total number of steps for this motor
this->drive_type = FullStep;

// Arduino pins for the motor control connection:
this->motor_pin_1 = motor_pin_1;
Expand All @@ -108,11 +149,18 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int moto

/*
Sets the speed in revs per minute

*/
void Stepper::setSpeed(long whatSpeed)
{
this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;
this->step_delay = 60L * 1000000L / this->number_of_steps / whatSpeed;
}

/*
Sets the drive type
*/
void Stepper::setDriveType(DriveType drive_type)
{
this->drive_type = drive_type;
}

/*
Expand All @@ -126,88 +174,98 @@ void Stepper::step(int steps_to_move)
// determine direction based on whether steps_to_mode is + or -:
if (steps_to_move > 0) {this->direction = 1;}
if (steps_to_move < 0) {this->direction = 0;}



int number_of_steps = this->number_of_steps;
unsigned long step_delay = this->step_delay;
if (this->drive_type == HalfStep) {
// There are twice as many steps, adjust appropriately.
number_of_steps *= 2;
step_delay /= 2;
}

// decrement the number of steps, moving one step each time:
while(steps_left > 0) {
// move only if the appropriate delay has passed:
if (millis() - this->last_step_time >= this->step_delay) {
unsigned long now = micros();
long elapsed_time = now - this->last_step_time;
// move only if the appropriate delay has passed:
if (elapsed_time >= step_delay) {
// get the timeStamp of when you stepped:
this->last_step_time = millis();
this->last_step_time = now;
// increment or decrement the step number,
// depending on direction:
if (this->direction == 1) {
this->step_number++;
if (this->step_number == this->number_of_steps) {
if (this->step_number >= number_of_steps) {
this->step_number = 0;
}
}
else {
if (this->step_number == 0) {
this->step_number = this->number_of_steps;
if (this->step_number <= 0) {
this->step_number = number_of_steps;
}
this->step_number--;
}
// decrement the steps left:
steps_left--;
// step the motor to step number 0, 1, 2, or 3:
stepMotor(this->step_number % 4);
// step the motor:
stepMotor();
}
}
}

/*
* Moves the motor forward or backwards.
*/
void Stepper::stepMotor(int thisStep)
{
if (this->pin_count == 2) {
switch (thisStep) {
case 0: /* 01 */
digitalWrite(motor_pin_1, LOW);
digitalWrite(motor_pin_2, HIGH);
break;
case 1: /* 11 */
digitalWrite(motor_pin_1, HIGH);
digitalWrite(motor_pin_2, HIGH);
void Stepper::stepMotor() {
switch(this->drive_type) {
case FullStep:
fullStepMotor();
break;
case 2: /* 10 */
digitalWrite(motor_pin_1, HIGH);
digitalWrite(motor_pin_2, LOW);
case HalfStep:
halfStepMotor();
break;
case 3: /* 00 */
digitalWrite(motor_pin_1, LOW);
digitalWrite(motor_pin_2, LOW);
case Wave:
waveStepMotor();
break;
}
}
}

void Stepper::fullStepMotor()
{
const int* step_row = STEP_VALUES[(this->step_number % 4) * 2]; // full-stepping only uses even rows
if (this->pin_count == 2) {
// For 2-wire configurations we take the middle two pins
digitalWrite(motor_pin_2, step_row[1]);
digitalWrite(motor_pin_3, step_row[2]);
} else if (this->pin_count == 4) {
digitalWrite(motor_pin_1, step_row[0]);
digitalWrite(motor_pin_2, step_row[1]);
digitalWrite(motor_pin_3, step_row[2]);
digitalWrite(motor_pin_4, step_row[3]);
}
}

void Stepper::halfStepMotor()
{
// Only 4-wire configurations can be half-stepped.
if (this->pin_count == 4) {
const int* step_row = STEP_VALUES[this->step_number % 8];
digitalWrite(motor_pin_1, step_row[0]);
digitalWrite(motor_pin_2, step_row[1]);
digitalWrite(motor_pin_3, step_row[2]);
digitalWrite(motor_pin_4, step_row[3]);
}
}

void Stepper::waveStepMotor()
{
// Only 4-wire configurations can be wave-driven.
if (this->pin_count == 4) {
switch (thisStep) {
case 0: // 1010
digitalWrite(motor_pin_1, HIGH);
digitalWrite(motor_pin_2, LOW);
digitalWrite(motor_pin_3, HIGH);
digitalWrite(motor_pin_4, LOW);
break;
case 1: // 0110
digitalWrite(motor_pin_1, LOW);
digitalWrite(motor_pin_2, HIGH);
digitalWrite(motor_pin_3, HIGH);
digitalWrite(motor_pin_4, LOW);
break;
case 2: //0101
digitalWrite(motor_pin_1, LOW);
digitalWrite(motor_pin_2, HIGH);
digitalWrite(motor_pin_3, LOW);
digitalWrite(motor_pin_4, HIGH);
break;
case 3: //1001
digitalWrite(motor_pin_1, HIGH);
digitalWrite(motor_pin_2, LOW);
digitalWrite(motor_pin_3, LOW);
digitalWrite(motor_pin_4, HIGH);
break;
}
const int* step_row = STEP_VALUES[(this->step_number % 4) * 2 + 1]; // wave drive only uses odd rows
digitalWrite(motor_pin_1, step_row[0]);
digitalWrite(motor_pin_2, step_row[1]);
digitalWrite(motor_pin_3, step_row[2]);
digitalWrite(motor_pin_4, step_row[3]);
}
}

Expand Down
50 changes: 46 additions & 4 deletions libraries/Stepper/Stepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,36 @@
3 1 0
4 0 0

The circuits can be found at
http://www.arduino.cc/en/Tutorial/Stepper
For 4 wire configurations only, the motor can be driven with full-stepping (the default),
half-stepping, or a wave drive.

Half-stepping will halve the size of the motor's step, giving it double the resolution.
Remember that the amount of steps you pass to step() will be interpreted based on the current
value of the drive type. The sequence of control signals is as follows:

Step C0 C1 C2 C3
1 1 0 1 0
2 0 0 1 0
3 0 1 1 0
4 0 1 0 0
5 0 1 0 1
6 0 0 0 1
7 1 0 0 1
8 1 0 0 0

Wave drive mode only keeps one phase on a time. This means that the motor will use less power, but
will also only have half of the torque of full-stepping. The sequence of control signals is as
follows:

Step C0 C1 C2 C3
1 0 0 1 0
2 0 1 0 0
3 0 0 0 1
4 1 0 0 0

The circuits can be found at http://www.arduino.cc/en/Tutorial/Stepper
More info on the different types of drives can be found at
http://www.wikipedia.org/wiki/Stepper_motor#Phase_current_waveforms
*/

// ensure this library description is only included once
Expand All @@ -48,20 +76,35 @@
// library interface description
class Stepper {
public:
enum DriveType { FullStep, HalfStep, Wave };

// constructors:
Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2);
Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4);

// speed setter method:
void setSpeed(long whatSpeed);

// drive type setter method:
void setDriveType(DriveType drive_type);

// mover method:
void step(int number_of_steps);

int version(void);

private:
void stepMotor(int this_step);
void stepMotor();
void fullStepMotor();
void halfStepMotor();
void waveStepMotor();

// Only even rows are used for full-stepping.
// Only odd rows are used for wave-stepping.
// All rows are used for half-stepping.
static const int STEP_VALUES[8][4];

DriveType drive_type; // What kind of stepping to use. Defaults to full.

int direction; // Direction of rotation
int speed; // Speed in RPMs
Expand All @@ -80,4 +123,3 @@ class Stepper {
};

#endif

1 change: 1 addition & 0 deletions libraries/Stepper/keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Stepper KEYWORD1

step KEYWORD2
setSpeed KEYWORD2
setDriveType KEYWORD2
version KEYWORD2

######################################
Expand Down