diff --git a/libraries/Stepper/library.properties b/libraries/Stepper/library.properties index f1347c91810..ea47a87f6f4 100644 --- a/libraries/Stepper/library.properties +++ b/libraries/Stepper/library.properties @@ -1,5 +1,5 @@ name=Stepper -version=1.0.2 +version=1.1.0 author=Arduino maintainer=Arduino sentence=Allows Arduino boards to control a variety of stepper motors. For all Arduino boards. diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index b1cbee6d17c..03d635fadb9 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -1,63 +1,80 @@ /* - Stepper.cpp - - Stepper library for Wiring/Arduino - Version 0.4 - - Original library (0.1) by Tom Igoe. - Two-wire modifications (0.2) by Sebastian Gassner - Combination version (0.3) by Tom Igoe and David Mellis - Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley - - Drives a unipolar or bipolar stepper motor using 2 wires or 4 wires - - When wiring multiple stepper motors to a microcontroller, - you quickly run out of output pins, with each motor requiring 4 connections. - - By making use of the fact that at any time two of the four motor - coils are the inverse of the other two, the number of - control connections can be reduced from 4 to 2. - - A slightly modified circuit around a Darlington transistor array or an L293 H-bridge - connects to only 2 microcontroler pins, inverts the signals received, - and delivers the 4 (2 plus 2 inverted ones) output signals required - for driving a stepper motor. - - The sequence of control signals for 4 control wires is as follows: - - Step C0 C1 C2 C3 - 1 1 0 1 0 - 2 0 1 1 0 - 3 0 1 0 1 - 4 1 0 0 1 - - The sequence of controls signals for 2 control wires is as follows - (columns C1 and C2 from above): - - Step C0 C1 - 1 0 1 - 2 1 1 - 3 1 0 - 4 0 0 - - The circuits can be found at - -http://www.arduino.cc/en/Tutorial/Stepper - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - + * Stepper.cpp - Stepper library for Wiring/Arduino - Version 1.1.0 + * + * Original library (0.1) by Tom Igoe. + * Two-wire modifications (0.2) by Sebastian Gassner + * Combination version (0.3) by Tom Igoe and David Mellis + * Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley + * High-speed stepping mod by Eugene Kozlenko + * Timer rollover fix by Eugene Kozlenko + * Five phase five wire (1.1.0) by Ryan Orendorff + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * Drives a unipolar, bipolar, or five phase stepper motor. + * + * When wiring multiple stepper motors to a microcontroller, you quickly run + * out of output pins, with each motor requiring 4 connections. + * + * By making use of the fact that at any time two of the four motor coils are + * the inverse of the other two, the number of control connections can be + * reduced from 4 to 2 for the unipolar and bipolar motors. + * + * A slightly modified circuit around a Darlington transistor array or an + * L293 H-bridge connects to only 2 microcontroler pins, inverts the signals + * received, and delivers the 4 (2 plus 2 inverted ones) output signals + * required for driving a stepper motor. Similarly the Arduino motor shields + * 2 direction pins may be used. + * + * The sequence of control signals for 5 phase, 5 control wires is as follows: + * + * Step C0 C1 C2 C3 C4 + * 1 0 1 1 0 1 + * 2 0 1 0 0 1 + * 3 0 1 0 1 1 + * 4 0 1 0 1 0 + * 5 1 1 0 1 0 + * 6 1 0 0 1 0 + * 7 1 0 1 1 0 + * 8 1 0 1 0 0 + * 9 1 0 1 0 1 + * 10 0 0 1 0 1 + * + * The sequence of control signals for 4 control wires is as follows: + * + * Step C0 C1 C2 C3 + * 1 1 0 1 0 + * 2 0 1 1 0 + * 3 0 1 0 1 + * 4 1 0 0 1 + * + * The sequence of controls signals for 2 control wires is as follows + * (columns C1 and C2 from above): + * + * Step C0 C1 + * 1 0 1 + * 2 1 1 + * 3 1 0 + * 4 0 0 + * + * The circuits can be found at + * + * http://www.arduino.cc/en/Tutorial/Stepper */ - #include "Arduino.h" #include "Stepper.h" @@ -67,12 +84,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) { - this->step_number = 0; // which step the motor is on - this->speed = 0; // the motor speed, in revolutions per minute + this->step_number = 0; // which step the motor is on + this->speed = 0; // the motor speed, in revolutions per minute 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->last_step_time = 0; // time stamp in us of the last step taken + this->number_of_steps = number_of_steps; // total number of steps for this motor + // Arduino pins for the motor control connection: this->motor_pin_1 = motor_pin_1; this->motor_pin_2 = motor_pin_2; @@ -80,11 +97,12 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) // setup the pins on the microcontroller: pinMode(this->motor_pin_1, OUTPUT); pinMode(this->motor_pin_2, OUTPUT); - - // When there are only 2 pins, set the other two to 0: + + // When there are only 2 pins, set the others to 0: this->motor_pin_3 = 0; this->motor_pin_4 = 0; - + this->motor_pin_5 = 0; + // pin_count is used by the stepMotor() method: this->pin_count = 2; } @@ -94,15 +112,15 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) * constructor for four-pin version * Sets which wires should control the motor. */ - -Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4) +Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, + int motor_pin_3, int motor_pin_4) { - this->step_number = 0; // which step the motor is on - this->speed = 0; // the motor speed, in revolutions per minute + this->step_number = 0; // which step the motor is on + this->speed = 0; // the motor speed, in revolutions per minute 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->last_step_time = 0; // time stamp in us of the last step taken + this->number_of_steps = number_of_steps; // total number of steps for this motor + // Arduino pins for the motor control connection: this->motor_pin_1 = motor_pin_1; this->motor_pin_2 = motor_pin_2; @@ -115,47 +133,86 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int moto pinMode(this->motor_pin_3, OUTPUT); pinMode(this->motor_pin_4, OUTPUT); - // pin_count is used by the stepMotor() method: - this->pin_count = 4; + // When there are 4 pins, set the others to 0: + this->motor_pin_5 = 0; + + // pin_count is used by the stepMotor() method: + this->pin_count = 4; } /* - Sets the speed in revs per minute + * constructor for five phase motor with five wires + * Sets which wires should control the motor. + */ +Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, + int motor_pin_3, int motor_pin_4, + int motor_pin_5) +{ + this->step_number = 0; // which step the motor is on + this->speed = 0; // the motor speed, in revolutions per minute + this->direction = 0; // motor direction + this->last_step_time = 0; // time stamp in us of the last step taken + this->number_of_steps = number_of_steps; // total number of steps for this motor -*/ + // Arduino pins for the motor control connection: + this->motor_pin_1 = motor_pin_1; + this->motor_pin_2 = motor_pin_2; + this->motor_pin_3 = motor_pin_3; + this->motor_pin_4 = motor_pin_4; + this->motor_pin_5 = motor_pin_5; + + // setup the pins on the microcontroller: + pinMode(this->motor_pin_1, OUTPUT); + pinMode(this->motor_pin_2, OUTPUT); + pinMode(this->motor_pin_3, OUTPUT); + pinMode(this->motor_pin_4, OUTPUT); + pinMode(this->motor_pin_5, OUTPUT); + + // pin_count is used by the stepMotor() method: + this->pin_count = 5; +} + +/* + * 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 * 1000L * 1000L / this->number_of_steps / whatSpeed; } /* - Moves the motor steps_to_move steps. If the number is negative, - the motor moves in the reverse direction. + * Moves the motor steps_to_move steps. If the number is negative, + * the motor moves in the reverse direction. */ void Stepper::step(int steps_to_move) -{ +{ int steps_left = abs(steps_to_move); // how many steps to take - + // 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;} - - + if (steps_to_move > 0) { this->direction = 1; } + if (steps_to_move < 0) { this->direction = 0; } + + // 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) { + while (steps_left > 0) + { + unsigned long now = micros(); + // move only if the appropriate delay has passed: + if (now - this->last_step_time >= this->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) { + if (this->direction == 1) + { this->step_number++; if (this->step_number == this->number_of_steps) { this->step_number = 0; } - } - else { + } + else + { if (this->step_number == 0) { this->step_number = this->number_of_steps; } @@ -163,8 +220,11 @@ void Stepper::step(int steps_to_move) } // 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 to step number 0, 1, ..., {3 or 10} + if (this->pin_count == 5) + stepMotor(this->step_number % 10); + else + stepMotor(this->step_number % 4); } } } @@ -176,51 +236,126 @@ 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); + 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); + case 1: // 11 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, HIGH); break; - case 2: /* 10 */ - digitalWrite(motor_pin_1, HIGH); - digitalWrite(motor_pin_2, LOW); + case 2: // 10 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); break; - case 3: /* 00 */ - digitalWrite(motor_pin_1, LOW); - digitalWrite(motor_pin_2, LOW); + case 3: // 00 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, LOW); break; - } + } } 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); + 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); + 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); + 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); + case 3: //1001 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, LOW); + digitalWrite(motor_pin_4, HIGH); break; - } + } + } + + if (this->pin_count == 5) { + switch (thisStep) { + case 0: // 01101 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, HIGH); + digitalWrite(motor_pin_4, LOW); + digitalWrite(motor_pin_5, HIGH); + break; + case 1: // 01001 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, LOW); + digitalWrite(motor_pin_4, LOW); + digitalWrite(motor_pin_5, HIGH); + break; + case 2: // 01011 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, LOW); + digitalWrite(motor_pin_4, HIGH); + digitalWrite(motor_pin_5, HIGH); + break; + case 3: // 01010 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, LOW); + digitalWrite(motor_pin_4, HIGH); + digitalWrite(motor_pin_5, LOW); + break; + case 4: // 11010 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, LOW); + digitalWrite(motor_pin_4, HIGH); + digitalWrite(motor_pin_5, LOW); + break; + case 5: // 10010 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, LOW); + digitalWrite(motor_pin_4, HIGH); + digitalWrite(motor_pin_5, LOW); + break; + case 6: // 10110 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, HIGH); + digitalWrite(motor_pin_4, HIGH); + digitalWrite(motor_pin_5, LOW); + break; + case 7: // 10100 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, HIGH); + digitalWrite(motor_pin_4, LOW); + digitalWrite(motor_pin_5, LOW); + break; + case 8: // 10101 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, HIGH); + digitalWrite(motor_pin_4, LOW); + digitalWrite(motor_pin_5, HIGH); + break; + case 9: // 00101 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, HIGH); + digitalWrite(motor_pin_4, LOW); + digitalWrite(motor_pin_5, HIGH); + break; + } } } @@ -229,5 +364,5 @@ void Stepper::stepMotor(int thisStep) */ int Stepper::version(void) { - return 4; + return 5; } diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index e0441ffe738..6c875883a88 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -1,59 +1,79 @@ /* - Stepper.h - - Stepper library for Wiring/Arduino - Version 0.4 - - Original library (0.1) by Tom Igoe. - Two-wire modifications (0.2) by Sebastian Gassner - Combination version (0.3) by Tom Igoe and David Mellis - Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley - - Drives a unipolar or bipolar stepper motor using 2 wires or 4 wires - - When wiring multiple stepper motors to a microcontroller, - you quickly run out of output pins, with each motor requiring 4 connections. - - By making use of the fact that at any time two of the four motor - coils are the inverse of the other two, the number of - control connections can be reduced from 4 to 2. - - A slightly modified circuit around a Darlington transistor array or an L293 H-bridge - connects to only 2 microcontroler pins, inverts the signals received, - and delivers the 4 (2 plus 2 inverted ones) output signals required - for driving a stepper motor. - - The sequence of control signals for 4 control wires is as follows: - - Step C0 C1 C2 C3 - 1 1 0 1 0 - 2 0 1 1 0 - 3 0 1 0 1 - 4 1 0 0 1 - - The sequence of controls signals for 2 control wires is as follows - (columns C1 and C2 from above): - - Step C0 C1 - 1 0 1 - 2 1 1 - 3 1 0 - 4 0 0 - - The circuits can be found at - http://www.arduino.cc/en/Tutorial/Stepper - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Stepper.h - Stepper library for Wiring/Arduino - Version 1.1.0 + * + * Original library (0.1) by Tom Igoe. + * Two-wire modifications (0.2) by Sebastian Gassner + * Combination version (0.3) by Tom Igoe and David Mellis + * Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley + * High-speed stepping mod by Eugene Kozlenko + * Timer rollover fix by Eugene Kozlenko + * Five phase five wire (1.1.0) by Ryan Orendorff + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * Drives a unipolar, bipolar, or five phase stepper motor. + * + * When wiring multiple stepper motors to a microcontroller, you quickly run + * out of output pins, with each motor requiring 4 connections. + * + * By making use of the fact that at any time two of the four motor coils are + * the inverse of the other two, the number of control connections can be + * reduced from 4 to 2 for the unipolar and bipolar motors. + * + * A slightly modified circuit around a Darlington transistor array or an + * L293 H-bridge connects to only 2 microcontroler pins, inverts the signals + * received, and delivers the 4 (2 plus 2 inverted ones) output signals + * required for driving a stepper motor. Similarly the Arduino motor shields + * 2 direction pins may be used. + * + * The sequence of control signals for 5 phase, 5 control wires is as follows: + * + * Step C0 C1 C2 C3 C4 + * 1 0 1 1 0 1 + * 2 0 1 0 0 1 + * 3 0 1 0 1 1 + * 4 0 1 0 1 0 + * 5 1 1 0 1 0 + * 6 1 0 0 1 0 + * 7 1 0 1 1 0 + * 8 1 0 1 0 0 + * 9 1 0 1 0 1 + * 10 0 0 1 0 1 + * + * The sequence of control signals for 4 control wires is as follows: + * + * Step C0 C1 C2 C3 + * 1 1 0 1 0 + * 2 0 1 1 0 + * 3 0 1 0 1 + * 4 1 0 0 1 + * + * The sequence of controls signals for 2 control wires is as follows + * (columns C1 and C2 from above): + * + * Step C0 C1 + * 1 0 1 + * 2 1 1 + * 3 1 0 + * 4 0 0 + * + * The circuits can be found at + * + * http://www.arduino.cc/en/Tutorial/Stepper + */ // ensure this library description is only included once #ifndef Stepper_h @@ -64,7 +84,11 @@ class Stepper { public: // 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); + Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, + int motor_pin_3, int motor_pin_4); + Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, + int motor_pin_3, int motor_pin_4, + int motor_pin_5); // speed setter method: void setSpeed(long whatSpeed); @@ -76,21 +100,22 @@ class Stepper { private: void stepMotor(int this_step); - - int direction; // Direction of rotation - int speed; // Speed in RPMs - unsigned long step_delay; // delay between steps, in ms, based on speed + + int direction; // Direction of rotation + int speed; // Speed in RPMs + unsigned long step_delay; // delay between steps, in ms, based on speed int number_of_steps; // total number of steps this motor can take - int pin_count; // whether you're driving the motor with 2 or 4 pins - int step_number; // which step the motor is on - + int pin_count; // how many pins are in use. + int step_number; // which step the motor is on + // motor pin numbers: int motor_pin_1; int motor_pin_2; int motor_pin_3; int motor_pin_4; - - long last_step_time; // time stamp in ms of when the last step was taken + int motor_pin_5; // Only 5 phase motor + + unsigned long last_step_time; // time stamp in us of when the last step was taken }; #endif