From 37dbfd44b67c465bf643c892de1b82839fa260e9 Mon Sep 17 00:00:00 2001 From: Joseph Brendler Date: Wed, 14 Dec 2022 13:09:25 -0500 Subject: [PATCH 1/8] add 3-phase; add interrupt method/flag; add yield --- src/Stepper.cpp | 380 +++++++++++++++++++++++++++++++----------------- src/Stepper.h | 87 ++++++----- 2 files changed, 299 insertions(+), 168 deletions(-) diff --git a/src/Stepper.cpp b/src/Stepper.cpp index 6361ce4..a0dd322 100644 --- a/src/Stepper.cpp +++ b/src/Stepper.cpp @@ -34,11 +34,21 @@ * 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 microcontroller pins, inverts the signals + * 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 shield's + * required for driving a stepper motor. Similarly the Arduino motor shields * 2 direction pins may be used. * + * The sequence of control signals for 3 phase, 3 control wires is as follows: + * + * Step C0 C1 C2 (change) + * 0 0 0 1 C1 Low + * 1 1 0 1 C0 High + * 2 1 0 0 C2 Low + * 3 1 1 0 C1 High + * 4 0 1 0 C0 Low + * 5 0 1 1 C2 High + * * The sequence of control signals for 5 phase, 5 control wires is as follows: * * Step C0 C1 C2 C3 C4 @@ -61,7 +71,7 @@ * 3 0 1 0 1 * 4 1 0 0 1 * - * The sequence of control signals for 2 control wires is as follows + * The sequence of controls signals for 2 control wires is as follows * (columns C1 and C2 from above): * * Step C0 C1 @@ -72,7 +82,7 @@ * * The circuits can be found at * - * https://docs.arduino.cc/learn/electronics/stepper-motors#circuit + * http://www.arduino.cc/en/Tutorial/Stepper */ #include "Arduino.h" @@ -84,9 +94,9 @@ */ 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->direction = 0; // motor direction - this->last_step_time = 0; // timestamp in us of the last step taken + this->step_number = 0; // which step the motor is on + 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: @@ -106,17 +116,46 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) this->pin_count = 2; } +/* + * constructor for three-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) +{ + this->step_number = 0; // which step the motor is on + 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; + + // setup the pins on the microcontroller: + pinMode(this->motor_pin_1, OUTPUT); + pinMode(this->motor_pin_2, OUTPUT); + pinMode(this->motor_pin_3, OUTPUT); + + // When there are 3 pins, set the others to 0: + this->motor_pin_4 = 0; + this->motor_pin_5 = 0; + + // pin_count is used by the stepMotor() method: + this->pin_count = 3; +} /* * 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) + int motor_pin_3, int motor_pin_4) { - this->step_number = 0; // which step the motor is on - this->direction = 0; // motor direction - this->last_step_time = 0; // timestamp in us of the last step taken + this->step_number = 0; // which step the motor is on + 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: @@ -143,12 +182,12 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, * 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) + int motor_pin_3, int motor_pin_4, + int motor_pin_5) { - this->step_number = 0; // which step the motor is on - this->direction = 0; // motor direction - this->last_step_time = 0; // timestamp in us of the last step taken + this->step_number = 0; // which step the motor is on + 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: @@ -183,16 +222,22 @@ void Stepper::setSpeed(long whatSpeed) */ void Stepper::step(int steps_to_move) { - int steps_left = abs(steps_to_move); // how many steps to take + 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) + while (steps_left > 0 && !INTERRUPTED) { + yield(); unsigned long now = micros(); // move only if the appropriate delay has passed: if (now - this->last_step_time >= this->step_delay) @@ -204,13 +249,15 @@ void Stepper::step(int steps_to_move) if (this->direction == 1) { this->step_number++; - if (this->step_number == this->number_of_steps) { + if (this->step_number == this->number_of_steps) + { this->step_number = 0; } } else { - if (this->step_number == 0) { + if (this->step_number == 0) + { this->step_number = this->number_of_steps; } this->step_number--; @@ -218,10 +265,18 @@ void Stepper::step(int steps_to_move) // decrement the steps left: steps_left--; // step the motor to step number 0, 1, ..., {3 or 10} - if (this->pin_count == 5) + switch (this->pin_count) + { + case 5: stepMotor(this->step_number % 10); - else + break; + case 3: + stepMotor(this->step_number % 6); + break; + default: // 2, 4 stepMotor(this->step_number % 4); + break; + } } } } @@ -231,135 +286,192 @@ void Stepper::step(int steps_to_move) */ 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); + 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); + break; + 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); break; - case 1: // 11 - digitalWrite(motor_pin_1, HIGH); - digitalWrite(motor_pin_2, HIGH); + } + } + if (this->pin_count == 3) + { + switch (thisStep) + { + case 0: // 001 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, HIGH); + break; + case 1: // 101 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, HIGH); break; - case 2: // 10 - digitalWrite(motor_pin_1, HIGH); - digitalWrite(motor_pin_2, LOW); + case 2: // 100 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, LOW); break; - case 3: // 00 - digitalWrite(motor_pin_1, LOW); - digitalWrite(motor_pin_2, LOW); + case 3: // 110 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, LOW); + break; + case 4: // 010 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, LOW); + break; + case 5: // 011 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, HIGH); 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); + 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); + 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; + 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; } } } +/* + set interrupt flag for otherwise blocking code +*/ +void Stepper::interrupt(void) +{ + this->INTERRUPTED = true; +} +/* + clear interrupt flag for otherwise blocking code +*/ +void Stepper::clear_interrupt(void) +{ + this->INTERRUPTED = false; +} + /* version() returns the version of the library: */ int Stepper::version(void) { - return 5; + return 7; } diff --git a/src/Stepper.h b/src/Stepper.h index b5578b4..a2e062f 100644 --- a/src/Stepper.h +++ b/src/Stepper.h @@ -8,6 +8,7 @@ * High-speed stepping mod by Eugene Kozlenko * Timer rollover fix by Eugene Kozlenko * Five phase five wire (1.1.0) by Ryan Orendorff + * Three phase three wire by Joe Brendler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,7 +25,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * - * Drives a unipolar, bipolar, or five phase stepper motor. + * 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. @@ -34,11 +35,21 @@ * 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 microcontroller pins, inverts the signals + * 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 shield's + * required for driving a stepper motor. Similarly the Arduino motor shields * 2 direction pins may be used. * + * The sequence of control signals for 3 phase, 3 control wires is as follows: + * + * Step C0 C1 C2 (change) + * 0 0 0 1 C1 Low + * 1 1 0 1 C0 High + * 2 1 0 0 C2 Low + * 3 1 1 0 C1 High + * 4 0 1 0 C0 Low + * 5 0 1 1 C2 High + * * The sequence of control signals for 5 phase, 5 control wires is as follows: * * Step C0 C1 C2 C3 C4 @@ -61,7 +72,7 @@ * 3 0 1 0 1 * 4 1 0 0 1 * - * The sequence of control signals for 2 control wires is as follows + * The sequence of controls signals for 2 control wires is as follows * (columns C1 and C2 from above): * * Step C0 C1 @@ -72,7 +83,7 @@ * * The circuits can be found at * - * https://docs.arduino.cc/learn/electronics/stepper-motors#circuit + * http://www.arduino.cc/en/Tutorial/Stepper */ // ensure this library description is only included once @@ -80,42 +91,50 @@ #define Stepper_h // library interface description -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, - int motor_pin_5); +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); + 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); - // speed setter method: - void setSpeed(long whatSpeed); + // mover method: + void step(int number_of_steps); - // mover method: - void step(int number_of_steps); + // interrupt otherwise blocking code + void interrupt(); + void clear_interrupt(); - int version(void); + int version(void); - private: - void stepMotor(int this_step); +private: + void stepMotor(int this_step); - int direction; // Direction of rotation - unsigned long step_delay; // delay between steps, in us, based on speed - int number_of_steps; // total number of steps this motor can take - int pin_count; // how many pins are in use. - int step_number; // which step the motor is on + int direction; // Direction of rotation + 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; // 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; - int motor_pin_5; // Only 5 phase motor + // motor pin numbers: + int motor_pin_1; + int motor_pin_2; + int motor_pin_3; + int motor_pin_4; + int motor_pin_5; // Only 5 phase motor - unsigned long last_step_time; // timestamp in us of when the last step was taken + unsigned long last_step_time; // time stamp in us of when the last step was taken + + bool INTERRUPTED; // bool to interrupt otherwise blocking code }; #endif - From 2431e78153413b041357486fd2d76e276f7a3ddd Mon Sep 17 00:00:00 2001 From: Joseph Brendler Date: Wed, 14 Dec 2022 13:35:25 -0500 Subject: [PATCH 2/8] add 3-phase; add interrupt method/flag; add yield 3-phase motor such as common HDD or FDD motor Note: tie common wire LOW, or invert control signals and tie common to +V interrupt() method allows external user code to interrupt long-running otherwise-blocking while() loop in void Stepper::step(int steps_to_move) yield() in same while loop avoids WDT-timeout crashes on some controllers, such as Heltec's wifi kit 32 --- src/Stepper.cpp | 958 ++++++++++++++++++++++++------------------------ src/Stepper.h | 280 +++++++------- 2 files changed, 621 insertions(+), 617 deletions(-) diff --git a/src/Stepper.cpp b/src/Stepper.cpp index a0dd322..769deca 100644 --- a/src/Stepper.cpp +++ b/src/Stepper.cpp @@ -1,477 +1,481 @@ -/* - * 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 3 phase, 3 control wires is as follows: - * - * Step C0 C1 C2 (change) - * 0 0 0 1 C1 Low - * 1 1 0 1 C0 High - * 2 1 0 0 C2 Low - * 3 1 1 0 C1 High - * 4 0 1 0 C0 Low - * 5 0 1 1 C2 High - * - * 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" - -/* - * two-wire constructor. - * Sets which wires should control the motor. - */ -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->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; - - // 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 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; -} - -/* - * constructor for three-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) -{ - this->step_number = 0; // which step the motor is on - 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; - - // setup the pins on the microcontroller: - pinMode(this->motor_pin_1, OUTPUT); - pinMode(this->motor_pin_2, OUTPUT); - pinMode(this->motor_pin_3, OUTPUT); - - // When there are 3 pins, set the others to 0: - this->motor_pin_4 = 0; - this->motor_pin_5 = 0; - - // pin_count is used by the stepMotor() method: - this->pin_count = 3; -} - -/* - * 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) -{ - this->step_number = 0; // which step the motor is on - 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; - - // 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); - - // 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; -} - -/* - * 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->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 * 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. - */ -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; - } - - // decrement the number of steps, moving one step each time: - while (steps_left > 0 && !INTERRUPTED) - { - yield(); - 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 = 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) - { - this->step_number = 0; - } - } - else - { - if (this->step_number == 0) - { - this->step_number = this->number_of_steps; - } - this->step_number--; - } - // decrement the steps left: - steps_left--; - // step the motor to step number 0, 1, ..., {3 or 10} - switch (this->pin_count) - { - case 5: - stepMotor(this->step_number % 10); - break; - case 3: - stepMotor(this->step_number % 6); - break; - default: // 2, 4 - stepMotor(this->step_number % 4); - break; - } - } - } -} - -/* - * 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); - break; - 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); - break; - } - } - if (this->pin_count == 3) - { - switch (thisStep) - { - case 0: // 001 - digitalWrite(motor_pin_1, LOW); - digitalWrite(motor_pin_2, LOW); - digitalWrite(motor_pin_3, HIGH); - break; - case 1: // 101 - digitalWrite(motor_pin_1, HIGH); - digitalWrite(motor_pin_2, LOW); - digitalWrite(motor_pin_3, HIGH); - break; - case 2: // 100 - digitalWrite(motor_pin_1, HIGH); - digitalWrite(motor_pin_2, LOW); - digitalWrite(motor_pin_3, LOW); - break; - case 3: // 110 - digitalWrite(motor_pin_1, HIGH); - digitalWrite(motor_pin_2, HIGH); - digitalWrite(motor_pin_3, LOW); - break; - case 4: // 010 - digitalWrite(motor_pin_1, LOW); - digitalWrite(motor_pin_2, HIGH); - digitalWrite(motor_pin_3, LOW); - break; - case 5: // 011 - digitalWrite(motor_pin_1, LOW); - digitalWrite(motor_pin_2, HIGH); - digitalWrite(motor_pin_3, HIGH); - 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); - 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; - } - } - - 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; - } - } -} - -/* - set interrupt flag for otherwise blocking code -*/ -void Stepper::interrupt(void) -{ - this->INTERRUPTED = true; -} -/* - clear interrupt flag for otherwise blocking code -*/ -void Stepper::clear_interrupt(void) -{ - this->INTERRUPTED = false; -} - -/* - version() returns the version of the library: -*/ -int Stepper::version(void) -{ - return 7; -} +/* + * 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 + * Three phase three wire by Joe Brendler + * + * 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 (SRM) control signals for 3 phase, 3 control wires is as follows: + * + * Step C0 C1 C2 (change) + * 0 0 0 1 C1 Low + * 1 1 0 1 C0 High + * 2 1 0 0 C2 Low + * 3 1 1 0 C1 High + * 4 0 1 0 C0 Low + * 5 0 1 1 C2 High + * + * 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" + +/* + * two-wire constructor. + * Sets which wires should control the motor. + */ +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->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; + + // 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 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; +} + +/* + * constructor for three-pin version + * Sets which wires should control the motor. + * Note: can drive with 3 x half H-Bridge chip like L293D, to control e.g. HDD motor + * (tie common line to ground, or invert control lines if driving with common HIGH) + */ +Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, + int motor_pin_3) +{ + this->step_number = 0; // which step the motor is on + 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; + + // setup the pins on the microcontroller: + pinMode(this->motor_pin_1, OUTPUT); + pinMode(this->motor_pin_2, OUTPUT); + pinMode(this->motor_pin_3, OUTPUT); + + // When there are 3 pins, set the others to 0: + this->motor_pin_4 = 0; + this->motor_pin_5 = 0; + + // pin_count is used by the stepMotor() method: + this->pin_count = 3; +} + +/* + * 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) +{ + this->step_number = 0; // which step the motor is on + 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; + + // 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); + + // 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; +} + +/* + * 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->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 * 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. + */ +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; + } + + // decrement the number of steps, moving one step each time, unless INTERRUPTED + // (flag set by interrupt() method, enabling external interruption of otherwise-blocking loop): + while (steps_left > 0 && !INTERRUPTED) + { + yield(); // guard against WDT-timeout crashes on some controllers, e.g. heltec's wifi kit 32 + 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 = 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) + { + this->step_number = 0; + } + } + else + { + if (this->step_number == 0) + { + this->step_number = this->number_of_steps; + } + this->step_number--; + } + // decrement the steps left: + steps_left--; + // step the motor to step number 0, 1, ..., {3 or 10} + switch (this->pin_count) + { + case 5: + stepMotor(this->step_number % 10); + break; + case 3: + stepMotor(this->step_number % 6); + break; + default: // 2, 4 + stepMotor(this->step_number % 4); + break; + } + } + } +} + +/* + * 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); + break; + 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); + break; + } + } + if (this->pin_count == 3) + { + switch (thisStep) + { + case 0: // 001 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, HIGH); + break; + case 1: // 101 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, HIGH); + break; + case 2: // 100 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, LOW); + break; + case 3: // 110 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, LOW); + break; + case 4: // 010 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, LOW); + break; + case 5: // 011 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, HIGH); + 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); + 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; + } + } + + 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; + } + } +} + +/* + set interrupt flag for otherwise blocking code +*/ +void Stepper::interrupt(void) +{ + this->INTERRUPTED = true; +} +/* + clear interrupt flag for otherwise blocking code +*/ +void Stepper::clear_interrupt(void) +{ + this->INTERRUPTED = false; +} + +/* + version() returns the version of the library: +*/ +int Stepper::version(void) +{ + return 7; +} diff --git a/src/Stepper.h b/src/Stepper.h index a2e062f..251ca8d 100644 --- a/src/Stepper.h +++ b/src/Stepper.h @@ -1,140 +1,140 @@ -/* - * 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 - * Three phase three wire by Joe Brendler - * - * 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 3 phase, 3 control wires is as follows: - * - * Step C0 C1 C2 (change) - * 0 0 0 1 C1 Low - * 1 1 0 1 C0 High - * 2 1 0 0 C2 Low - * 3 1 1 0 C1 High - * 4 0 1 0 C0 Low - * 5 0 1 1 C2 High - * - * 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 -#define Stepper_h - -// library interface description -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); - 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); - - // mover method: - void step(int number_of_steps); - - // interrupt otherwise blocking code - void interrupt(); - void clear_interrupt(); - - int version(void); - -private: - void stepMotor(int this_step); - - int direction; // Direction of rotation - 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; // 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; - int motor_pin_5; // Only 5 phase motor - - unsigned long last_step_time; // time stamp in us of when the last step was taken - - bool INTERRUPTED; // bool to interrupt otherwise blocking code -}; - -#endif +/* + * 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 + * Three phase three wire by Joe Brendler + * + * 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 3 phase, 3 control wires is as follows: + * + * Step C0 C1 C2 (change) + * 0 0 0 1 C1 Low + * 1 1 0 1 C0 High + * 2 1 0 0 C2 Low + * 3 1 1 0 C1 High + * 4 0 1 0 C0 Low + * 5 0 1 1 C2 High + * + * 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 +#define Stepper_h + +// library interface description +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); + 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); + + // mover method: + void step(int number_of_steps); + + // interrupt otherwise blocking code + void interrupt(); + void clear_interrupt(); + + int version(void); + +private: + void stepMotor(int this_step); + + int direction; // Direction of rotation + 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; // 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; + int motor_pin_5; // Only 5 phase motor + + unsigned long last_step_time; // time stamp in us of when the last step was taken + + bool INTERRUPTED; // bool to interrupt otherwise blocking code +}; + +#endif From 3e3c759c8952ac39057244d0a4672fe6de8e340f Mon Sep 17 00:00:00 2001 From: Joseph Brendler Date: Wed, 14 Dec 2022 14:06:28 -0500 Subject: [PATCH 3/8] add 3-phase --- src/Stepper.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Stepper.cpp b/src/Stepper.cpp index a0dd322..b0d2a34 100644 --- a/src/Stepper.cpp +++ b/src/Stepper.cpp @@ -8,6 +8,7 @@ * High-speed stepping mod by Eugene Kozlenko * Timer rollover fix by Eugene Kozlenko * Five phase five wire (1.1.0) by Ryan Orendorff + * Three phase three wire by Joe Brendler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,7 +40,7 @@ * required for driving a stepper motor. Similarly the Arduino motor shields * 2 direction pins may be used. * - * The sequence of control signals for 3 phase, 3 control wires is as follows: + * The sequence of (SRM) control signals for 3 phase, 3 control wires is as follows: * * Step C0 C1 C2 (change) * 0 0 0 1 C1 Low @@ -119,6 +120,8 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) /* * constructor for three-pin version * Sets which wires should control the motor. + * Note: can drive with 3 x half H-Bridge chip like L293D, to control e.g. HDD motor + * (tie common line to ground, or invert control lines if driving with common HIGH) */ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3) @@ -234,10 +237,11 @@ void Stepper::step(int steps_to_move) this->direction = 0; } - // decrement the number of steps, moving one step each time: + // decrement the number of steps, moving one step each time, unless INTERRUPTED + // (flag set by interrupt() method, enabling external interruption of otherwise-blocking loop): while (steps_left > 0 && !INTERRUPTED) { - yield(); + yield(); // guard against WDT-timeout crashes on some controllers, e.g. heltec's wifi kit 32 unsigned long now = micros(); // move only if the appropriate delay has passed: if (now - this->last_step_time >= this->step_delay) From b29ac8462e99a29c4364bc8f0576c14d7618b1a4 Mon Sep 17 00:00:00 2001 From: Joseph Brendler Date: Wed, 14 Dec 2022 14:33:50 -0500 Subject: [PATCH 4/8] spelling correction --- src/Stepper.cpp | 486 +----------------------------------------------- src/Stepper.h | 2 +- 2 files changed, 2 insertions(+), 486 deletions(-) diff --git a/src/Stepper.cpp b/src/Stepper.cpp index 1509861..0ad8c62 100644 --- a/src/Stepper.cpp +++ b/src/Stepper.cpp @@ -1,4 +1,3 @@ -<<<<<<< HEAD /* * Stepper.cpp - Stepper library for Wiring/Arduino - Version 1.1.0 * @@ -36,7 +35,7 @@ * 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 + * L293 H-bridge connects to only 2 microcontroller 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. @@ -480,486 +479,3 @@ int Stepper::version(void) { return 7; } -======= -/* - * 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 - * Three phase three wire by Joe Brendler - * - * 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 (SRM) control signals for 3 phase, 3 control wires is as follows: - * - * Step C0 C1 C2 (change) - * 0 0 0 1 C1 Low - * 1 1 0 1 C0 High - * 2 1 0 0 C2 Low - * 3 1 1 0 C1 High - * 4 0 1 0 C0 Low - * 5 0 1 1 C2 High - * - * 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" - -/* - * two-wire constructor. - * Sets which wires should control the motor. - */ -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->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; - - // 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 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; -} - -/* - * constructor for three-pin version - * Sets which wires should control the motor. - * Note: can drive with 3 x half H-Bridge chip like L293D, to control e.g. HDD motor - * (tie common line to ground, or invert control lines if driving with common HIGH) - */ -Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, - int motor_pin_3) -{ - this->step_number = 0; // which step the motor is on - 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; - - // setup the pins on the microcontroller: - pinMode(this->motor_pin_1, OUTPUT); - pinMode(this->motor_pin_2, OUTPUT); - pinMode(this->motor_pin_3, OUTPUT); - - // When there are 3 pins, set the others to 0: - this->motor_pin_4 = 0; - this->motor_pin_5 = 0; - - // pin_count is used by the stepMotor() method: - this->pin_count = 3; -} - -/* - * 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) -{ - this->step_number = 0; // which step the motor is on - 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; - - // 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); - - // 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; -} - -/* - * 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->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 * 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. - */ -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; - } - - // decrement the number of steps, moving one step each time, unless INTERRUPTED - // (flag set by interrupt() method, enabling external interruption of otherwise-blocking loop): - while (steps_left > 0 && !INTERRUPTED) - { - yield(); // guard against WDT-timeout crashes on some controllers, e.g. heltec's wifi kit 32 - 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 = 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) - { - this->step_number = 0; - } - } - else - { - if (this->step_number == 0) - { - this->step_number = this->number_of_steps; - } - this->step_number--; - } - // decrement the steps left: - steps_left--; - // step the motor to step number 0, 1, ..., {3 or 10} - switch (this->pin_count) - { - case 5: - stepMotor(this->step_number % 10); - break; - case 3: - stepMotor(this->step_number % 6); - break; - default: // 2, 4 - stepMotor(this->step_number % 4); - break; - } - } - } -} - -/* - * 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); - break; - 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); - break; - } - } - if (this->pin_count == 3) - { - switch (thisStep) - { - case 0: // 001 - digitalWrite(motor_pin_1, LOW); - digitalWrite(motor_pin_2, LOW); - digitalWrite(motor_pin_3, HIGH); - break; - case 1: // 101 - digitalWrite(motor_pin_1, HIGH); - digitalWrite(motor_pin_2, LOW); - digitalWrite(motor_pin_3, HIGH); - break; - case 2: // 100 - digitalWrite(motor_pin_1, HIGH); - digitalWrite(motor_pin_2, LOW); - digitalWrite(motor_pin_3, LOW); - break; - case 3: // 110 - digitalWrite(motor_pin_1, HIGH); - digitalWrite(motor_pin_2, HIGH); - digitalWrite(motor_pin_3, LOW); - break; - case 4: // 010 - digitalWrite(motor_pin_1, LOW); - digitalWrite(motor_pin_2, HIGH); - digitalWrite(motor_pin_3, LOW); - break; - case 5: // 011 - digitalWrite(motor_pin_1, LOW); - digitalWrite(motor_pin_2, HIGH); - digitalWrite(motor_pin_3, HIGH); - 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); - 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; - } - } - - 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; - } - } -} - -/* - set interrupt flag for otherwise blocking code -*/ -void Stepper::interrupt(void) -{ - this->INTERRUPTED = true; -} -/* - clear interrupt flag for otherwise blocking code -*/ -void Stepper::clear_interrupt(void) -{ - this->INTERRUPTED = false; -} - -/* - version() returns the version of the library: -*/ -int Stepper::version(void) -{ - return 7; -} ->>>>>>> 1c8624f25c5c726e3ebfa006d567644d2c91eb48 diff --git a/src/Stepper.h b/src/Stepper.h index 251ca8d..6537bd6 100644 --- a/src/Stepper.h +++ b/src/Stepper.h @@ -40,7 +40,7 @@ * required for driving a stepper motor. Similarly the Arduino motor shields * 2 direction pins may be used. * - * The sequence of control signals for 3 phase, 3 control wires is as follows: + * The sequence of (SRM) control signals for 3 phase, 3 control wires is as follows: * * Step C0 C1 C2 (change) * 0 0 0 1 C1 Low From bca3e167d3f254a7327238bd925ee3dd674c685e Mon Sep 17 00:00:00 2001 From: Joseph Brendler Date: Wed, 14 Dec 2022 15:29:20 -0500 Subject: [PATCH 5/8] spelling correction #2 --- src/Stepper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stepper.h b/src/Stepper.h index 6537bd6..4893d72 100644 --- a/src/Stepper.h +++ b/src/Stepper.h @@ -35,7 +35,7 @@ * 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 + * L293 H-bridge connects to only 2 microcontroller 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. From a9a9890a3c3fff6a3fb7dd61e7d791abbf91b343 Mon Sep 17 00:00:00 2001 From: Joseph Brendler Date: Wed, 14 Dec 2022 16:29:27 -0500 Subject: [PATCH 6/8] added example interruptible 3-ph stepper --- ...epper_3ph_knob_interrupt_oneRevolution.ino | 125 ++++++++++++++++++ .../stepper_oneRevolution.ino | 6 +- 2 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino diff --git a/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino b/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino new file mode 100644 index 0000000..19803a6 --- /dev/null +++ b/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino @@ -0,0 +1,125 @@ +/* + Interruptible Three-phase Stepper Motor Control - one revolution + + This program drives a three-phase unipolar stepper motor. + The motor is attached to GPIO pins 17, 18, 19 of a Heltec wifi kit 32 development board + (modify for your Arduino or whatever) + + The motor should revolve one revolution in one direction, then + one revolution in the other direction. + + A potentiometer is used to set speed (like the MotorKnob example) + If you select a slow speed (like 1), it can take a long time to step + + If you don't want to wait for a cycle to finish itself, you can + "interrupt" it by pressing the pushbutton -- the ISR calls + Stepper::interrupt() which sets a private boolean "INTERRUPTED" + value in your Stepper, which will cause the while() loop in Stepper::step() + to exit instead of running a long time. The user code will then call + Stepper::clear_interrupt(), which resets the INTERRUPTED boolean, in your Stepper + +Output should look like this: + config pushbutton ==> Done + Attach interrupt... ==> Done + Setting stepper speed... ==> Done + setup() complete + clockwise, speed: 1 button PRESSED + counterclockwise, speed: 23 button NOT pressed + clockwise, speed: 23 button NOT pressed + counterclockwise, speed: 24 button NOT pressed + clockwise, speed: 11 button PRESSED + counterclockwise, speed: 8 button NOT pressed + ... + + Created 11 Mar. 2007; Modified 30 Nov. 2009 by Tom Igoe + Modified 14 Dec 2022 by Joe Brendler + */ + +#include +#include + +#define pot A0 +#define pushbutton 37 + +const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution for your motor +long speed = 50; // analog input reading (in rpm) + +struct buttonInterruptLine +{ + const uint8_t PIN; // gpio pin number + volatile uint32_t numHits; // number of times fired + volatile bool PRESSED; // boolean logical; is triggered now +}; +buttonInterruptLine buttonPress = {pushbutton, 0, false}; + +// initialize the three-phase stepper library on GPIO +Stepper myStepper(stepsPerRevolution, 17, 18, 19); + +/*------------------------------------------------------------------------------ + handle_button_interrupt() - set flag and call stepper interrupt method + ------------------------------------------------------------------------------*/ +void IRAM_ATTR handle_button_interrupt() +{ + buttonPress.PRESSED = true; + myStepper.interrupt(); // method sets a flag +} + +void setup() +{ + // initialize the serial port: + Serial.begin(115200); + + // initialize analog input + pinMode(pot, INPUT); + + // Configure function pushbutton interrupt pin + Serial.print("config pushbutton"); + pinMode(buttonPress.PIN, INPUT_PULLDOWN); + Serial.println(" ==> Done"); + Serial.print("Attach interrupt... "); + attachInterrupt(buttonPress.PIN, handle_button_interrupt, FALLING); + Serial.println(" ==> Done"); + // set stepper speed + Serial.print("Setting stepper speed..."); + // set the speed + myStepper.setSpeed(speed); + Serial.println(" ==> Done"); + Serial.println("setup() complete"); +} + +void loop() +{ + // read speed from 12-bit ADC input (map 1-100; stepper doesn't like speed=0) + speed = (long)(map(analogRead(pot), 0, 4095, 1, 100)); + myStepper.setSpeed(speed); + Serial.printf("clockwise, speed: %d ", speed); + // step one revolution in one direction: + myStepper.step(stepsPerRevolution); + if (buttonPress.PRESSED) + Serial.println(" button PRESSED"); + else + Serial.println(" button NOT pressed"); + if (buttonPress.PRESSED) + { + buttonPress.PRESSED = false; + myStepper.clear_interrupt(); + } + delay(500); + + // read speed from 12-bit ADC input (map 1-100; stepper doesn't like speed=0) + speed = (long)(map(analogRead(pot), 0, 4095, 1, 100)); + myStepper.setSpeed(speed); + Serial.printf("counterclockwise, speed: %d ", speed); + // step one revolution in the other direction: + myStepper.step(-stepsPerRevolution); + if (buttonPress.PRESSED) + Serial.println(" button PRESSED"); + else + Serial.println(" button NOT pressed"); + if (buttonPress.PRESSED) + { + buttonPress.PRESSED = false; + myStepper.clear_interrupt(); + } + delay(500); +} diff --git a/examples/stepper_oneRevolution/stepper_oneRevolution.ino b/examples/stepper_oneRevolution/stepper_oneRevolution.ino index 2567a79..373eb60 100644 --- a/examples/stepper_oneRevolution/stepper_oneRevolution.ino +++ b/examples/stepper_oneRevolution/stepper_oneRevolution.ino @@ -1,3 +1,4 @@ + /* Stepper Motor Control - one revolution @@ -19,7 +20,7 @@ const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution // for your motor -// initialize the Stepper library on pins 8 through 11: +// initialize the stepper library on pins 8 through 11: Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11); void setup() { @@ -30,7 +31,7 @@ void setup() { } void loop() { - // step one revolution in one direction: + // step one revolution in one direction: Serial.println("clockwise"); myStepper.step(stepsPerRevolution); delay(500); @@ -40,3 +41,4 @@ void loop() { myStepper.step(-stepsPerRevolution); delay(500); } + From 2d386ebdd3ab56818235159f39823af9214e7f39 Mon Sep 17 00:00:00 2001 From: Joseph Brendler Date: Wed, 14 Dec 2022 16:41:08 -0500 Subject: [PATCH 7/8] typo fix --- .../stepper_3ph_knob_interrupt_oneRevolution.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino b/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino index 19803a6..cfc8aa4 100644 --- a/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino +++ b/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino @@ -35,7 +35,7 @@ Output should look like this: Modified 14 Dec 2022 by Joe Brendler */ -#include +// #include #include #define pot A0 From 01dee922c6fc160e569e9de4897a2b066ec24c82 Mon Sep 17 00:00:00 2001 From: Joseph Brendler Date: Wed, 14 Dec 2022 17:20:25 -0500 Subject: [PATCH 8/8] bugfix in new example code --- ...stepper_3ph_knob_interrupt_oneRevolution.ino | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino b/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino index cfc8aa4..752779a 100644 --- a/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino +++ b/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino @@ -35,11 +35,11 @@ Output should look like this: Modified 14 Dec 2022 by Joe Brendler */ -// #include +#include #include -#define pot A0 -#define pushbutton 37 +const int pot = 0; // A0 +const int pushbutton = 2; // D2, int0 const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution for your motor long speed = 50; // analog input reading (in rpm) @@ -58,7 +58,8 @@ Stepper myStepper(stepsPerRevolution, 17, 18, 19); /*------------------------------------------------------------------------------ handle_button_interrupt() - set flag and call stepper interrupt method ------------------------------------------------------------------------------*/ -void IRAM_ATTR handle_button_interrupt() +// void IRAM_ATTR handle_button_interrupt() +void handle_button_interrupt() { buttonPress.PRESSED = true; myStepper.interrupt(); // method sets a flag @@ -74,7 +75,7 @@ void setup() // Configure function pushbutton interrupt pin Serial.print("config pushbutton"); - pinMode(buttonPress.PIN, INPUT_PULLDOWN); + pinMode(buttonPress.PIN, INPUT); Serial.println(" ==> Done"); Serial.print("Attach interrupt... "); attachInterrupt(buttonPress.PIN, handle_button_interrupt, FALLING); @@ -92,7 +93,8 @@ void loop() // read speed from 12-bit ADC input (map 1-100; stepper doesn't like speed=0) speed = (long)(map(analogRead(pot), 0, 4095, 1, 100)); myStepper.setSpeed(speed); - Serial.printf("clockwise, speed: %d ", speed); + Serial.print("clockwise, speed: "); + Serial.print(speed); // step one revolution in one direction: myStepper.step(stepsPerRevolution); if (buttonPress.PRESSED) @@ -109,7 +111,8 @@ void loop() // read speed from 12-bit ADC input (map 1-100; stepper doesn't like speed=0) speed = (long)(map(analogRead(pot), 0, 4095, 1, 100)); myStepper.setSpeed(speed); - Serial.printf("counterclockwise, speed: %d ", speed); + Serial.print("clockwise, speed: "); + Serial.print(speed); // step one revolution in the other direction: myStepper.step(-stepsPerRevolution); if (buttonPress.PRESSED)