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..752779a --- /dev/null +++ b/examples/stepper_3ph_knob_interrupt_oneRevolution/stepper_3ph_knob_interrupt_oneRevolution.ino @@ -0,0 +1,128 @@ +/* + 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 + +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) + +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() +void 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); + 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.print("clockwise, speed: "); + Serial.print(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.print("clockwise, speed: "); + Serial.print(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); } + diff --git a/src/Stepper.cpp b/src/Stepper.cpp index 6361ce4..0ad8c62 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 @@ -36,9 +37,19 @@ * A slightly modified circuit around a Darlington transistor array or an * 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 shield's + * 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 @@ -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 */ #include "Arduino.h" @@ -84,9 +95,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 +117,48 @@ 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. + * 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) + 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 +185,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 +225,23 @@ 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) + // 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) @@ -204,13 +253,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 +269,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 +290,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..4893d72 100644 --- a/src/Stepper.h +++ b/src/Stepper.h @@ -1,121 +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 - * - * 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 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 shield's - * 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 control 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 - * - * https://docs.arduino.cc/learn/electronics/stepper-motors#circuit - */ - -// 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, int motor_pin_4, - int motor_pin_5); - - // speed setter method: - void setSpeed(long whatSpeed); - - // mover method: - void step(int number_of_steps); - - int version(void); - - 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 - - // 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 -}; - -#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 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. + * + * 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 + */ + +// 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