From 3540590a01f5e56124a6afbff6a9c6cf3cf8c3c0 Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Sat, 5 Dec 2015 19:20:54 +0100 Subject: [PATCH 01/12] Support generic drivers for Stepper library Main features of this version: 1. 100% compatible with the actual master branch 2. generic driver support (see example stepper_oneRevolution_ULN2003 for driver ULN2003ERP & Motor_BYJ48) 3. constructors harmonization by introducing the initMotor method, 4. speed and size optimization of method stepMotor by introducing the phasesMatrix array --- .../stepper_oneRevolution_28BYJ48_ULN2003.ino | 71 +++++ libraries/Stepper/src/Stepper.cpp | 287 +++++------------- libraries/Stepper/src/Stepper.h | 71 ++++- 3 files changed, 209 insertions(+), 220 deletions(-) create mode 100644 libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino diff --git a/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino new file mode 100644 index 00000000000..dba27e4a40c --- /dev/null +++ b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino @@ -0,0 +1,71 @@ +/* + Stepper Motor Control - one revolution + + This program drives a unipolar or bipolar stepper motor. + The motor is attached to digital pins 8 - 11 of the Arduino. + + The motor should revolve one revolution in one direction, then + one revolution in the other direction. + + + Created 11 Mar. 2007 + Modified 30 Nov. 2009 + by Tom Igoe + + Example adapted for the combination of Motor 28BYJ-48 and driver ULN2003 + see http://www.amazon.de/gp/product/B00ATA5MFE?keywords=ULN2003%2028BYJ48 + Modified 05 Dec. 2015 + by Stanislav Kniazev + + */ + +#include +// Motor 28BYJ-48 has 4096 steps per one revolution +const int stepsPerRevolution = 4096; // change this to fit the number of steps per revolution for your motor + +/* Custom phase matrix for driver ULN2003. + * The sequence of control signals for 8 phases, 4 control wires is as follows: + * Step C0 C1 C2 C3 + * 1 0 0 0 1 + * 2 0 0 1 1 + * 3 0 0 1 0 + * 4 0 1 1 0 + * 5 0 1 0 0 + * 6 1 1 0 0 + * 7 1 0 0 0 + * 8 1 0 0 1 + */ +const unsigned char phasesMatrix[8]= { + 0b00010000, + 0b00110000, + 0b00100000, + 0b01100000, + 0b01000000, + 0b11000000, + 0b10000000, + 0b10010000 + }; + +//initialize the stepper library on pins 8 through 11, phasesMatrix, pin_count, phase_count: +Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11, 0, (unsigned char*)phasesMatrix, 4, 8); + +void setup() { + // 17 is the maximum for counterclockwise revolution of motor 28BYJ-48 + // set the speed at 17 rpm: + myStepper.setSpeed(17); + // initialize the serial port: + Serial.begin(9600); +} + +void loop() { + // step one revolution in one direction: + Serial.println("clockwise"); + myStepper.step(stepsPerRevolution); + delay(500); + + // step one revolution in the other direction: + Serial.println("counterclockwise"); + myStepper.step(-stepsPerRevolution); + delay(500); +} + diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index 1f76295d05b..c14470a2005 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -1,13 +1,19 @@ /* - * 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 + * Stepper.cpp - Stepper library for Wiring/Arduino - Version 1.1.1 + * + * 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 Kozlen + * Five phase five wire (1.1.0) by Ryan Orendorff + * Generic driver support (see example + * stepper_oneRevolution_ULN2003), + * constructors harmonization by + * introducing the initMotor method, + * optimization of method stepMotor by + * introducing the phasesMatrix array (1.1.1) by Stanislav Kniazev * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -84,26 +90,8 @@ */ 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; + initMotor(number_of_steps, motor_pin_1, motor_pin_2, + 0, 0, 0, (unsigned char*)phasesMatrix2, 2, 4); } @@ -114,28 +102,9 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) 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; + initMotor(number_of_steps, motor_pin_1, motor_pin_2, + motor_pin_3, motor_pin_4, + 0, (unsigned char*)phasesMatrix4, 4, 4); } /* @@ -146,27 +115,24 @@ 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); + initMotor(number_of_steps, motor_pin_1, motor_pin_2, + motor_pin_3, motor_pin_4, + motor_pin_5, (unsigned char*)phasesMatrix5, 5, 10); +} - // pin_count is used by the stepMotor() method: - this->pin_count = 5; +/* + * universal constructor for motors with maximum five wires + * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. + */ +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, unsigned char *phasesMatrix, + int pin_count, int phase_count) +{ + initMotor(number_of_steps, motor_pin_1, motor_pin_2, + motor_pin_3, motor_pin_4, + motor_pin_5, phasesMatrix, + pin_count, phase_count); } /* @@ -185,23 +151,19 @@ 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) { - 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; + delayMicroseconds(this->step_delay); // move only if the appropriate delay has passed +// 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) + if (steps_to_move >= 0) { this->step_number++; if (this->step_number == this->number_of_steps) { @@ -217,12 +179,9 @@ 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) - stepMotor(this->step_number % 10); - else - stepMotor(this->step_number % 4); - } + // step the motor to step number 0, 1, ..., {3 or 9} + stepMotor(this->step_number % phase_count); +// } } } @@ -231,128 +190,48 @@ 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); - 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 == 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; - } + unsigned char running_one = 0b10000000; + for (int i = 0; i < pin_count; i++, running_one >>= 1){ + digitalWrite(motor_pin[i], (phasesMatrix[thisStep] & running_one)); } +} - 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); +/* + * Initialize the motor + */ +void Stepper::initMotor(int number_of_steps, int motor_pin_1, int motor_pin_2, + int motor_pin_3, int motor_pin_4, + int motor_pin_5, unsigned char *phasesMatrix, + int pin_count, int phase_count) +{ + this->step_number = 0; // which step the motor is on + this->number_of_steps = number_of_steps; // total number of steps for this motor + + // pin_count is used by the stepMotor() method: + this->pin_count = pin_count; + // phase_count is used by the step() method: + this->phase_count = phase_count; + // phasesMatrix is used by the stepMotor() method: + this->phasesMatrix = phasesMatrix; + for (int i = 0; i < this->pin_count; i++){ + switch (i) { + case 0: + this->motor_pin[i] = motor_pin_1; // Arduino pin 1 for the motor control connection 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); + case 1: + this->motor_pin[i] = motor_pin_2; // Arduino pin 2 for the motor control connection 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); + case 2: + this->motor_pin[i] = motor_pin_3; // Arduino pin 3 for the motor control connection 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); + case 3: + this->motor_pin[i] = motor_pin_4; // Arduino pin 4 for the motor control connection 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); + case 4: + this->motor_pin[i] = motor_pin_5; // Arduino pin 5 for the motor control connection break; - } + } + pinMode(this->motor_pin[i], OUTPUT); // setup the pins on the microcontroller } } diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index 2e68979a1b1..0cd8dcb8dd4 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -1,13 +1,19 @@ /* - * 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 + * Stepper.h - Stepper library for Wiring/Arduino - Version 1.1.1 + * + * 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 Kozlen + * Five phase five wire (1.1.0) by Ryan Orendorff + * Generic driver support (see example + * stepper_oneRevolution_ULN2003), + * constructors harmonization by + * introducing the initMotor method, + * optimization of method stepMotor by + * introducing the phasesMatrix array (1.1.1) by Stanislav Kniazev * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -89,6 +95,10 @@ class 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); + 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, unsigned char *phasesMatrix, + int pin_count, int phase_count); // speed setter method: void setSpeed(long whatSpeed); @@ -100,21 +110,50 @@ class Stepper { private: void stepMotor(int this_step); + void initMotor(int number_of_steps, int motor_pin_1, int motor_pin_2, + int motor_pin_3, int motor_pin_4, + int motor_pin_5, unsigned char *phasesMatrix, + int pin_count, int phase_count); - 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 phase_count; // how many phases are in use. + unsigned char *phasesMatrix; // pointer to the phases Matrix 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 + int motor_pin[5]; // Maximum 5 control signals + + //Default phases matrix for 2 control wires is as follows + const unsigned char phasesMatrix2[4] = { + 0b01000000, + 0b11000000, + 0b10000000, + 0b00000000 + }; + + //Default phases matrix for 4 control wires is as follows + const unsigned char phasesMatrix4[4] = { + 0b10100000, + 0b01100000, + 0b01010000, + 0b10010000 + }; - unsigned long last_step_time; // time stamp in us of when the last step was taken + //Default phases matrix for 5 control wires is as follows + const unsigned char phasesMatrix5[10] = { + 0b01101000, + 0b01001000, + 0b01011000, + 0b01010000, + 0b11010000, + 0b10010000, + 0b10110000, + 0b10100000, + 0b10101000, + 0b00101000 + }; }; #endif From c046a3f748751da1e165450ff60b0ae8f394d03d Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Mon, 7 Dec 2015 23:20:25 +0100 Subject: [PATCH 02/12] PROGMEM approach This version saves 28 bytes of dynamic memory in library code by using PROGMEM for driver patterns. File stepper_oneRevolution_28BYJ48_ULN2003.ino shows, how to use PROGMEM also for patterns of custom drivers. --- .../stepper_oneRevolution_28BYJ48_ULN2003.ino | 2 +- libraries/Stepper/src/Stepper.cpp | 5 +- libraries/Stepper/src/Stepper.h | 64 ++++++++++--------- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino index dba27e4a40c..9cf87f423b0 100644 --- a/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino +++ b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino @@ -35,7 +35,7 @@ const int stepsPerRevolution = 4096; // change this to fit the number of steps * 7 1 0 0 0 * 8 1 0 0 1 */ -const unsigned char phasesMatrix[8]= { +const unsigned char phasesMatrix[8] PROGMEM = { 0b00010000, 0b00110000, 0b00100000, diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index c14470a2005..bb0d3c3dc74 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -188,11 +188,12 @@ void Stepper::step(int steps_to_move) /* * Moves the motor forward or backwards. */ -void Stepper::stepMotor(int thisStep) +void Stepper::stepMotor(int thisPhase) { + unsigned char phase = pgm_read_byte_near(phasesMatrix + thisPhase); unsigned char running_one = 0b10000000; for (int i = 0; i < pin_count; i++, running_one >>= 1){ - digitalWrite(motor_pin[i], (phasesMatrix[thisStep] & running_one)); + digitalWrite(motor_pin[i], (phase & running_one)); } } diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index 0cd8dcb8dd4..2c4ef92c039 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -85,6 +85,38 @@ #ifndef Stepper_h #define Stepper_h +#include + + //Default phases matrix for 2 control wires is as follows + const unsigned char phasesMatrix2[4] PROGMEM = { + 0b01000000, + 0b11000000, + 0b10000000, + 0b00000000 + }; + + //Default phases matrix for 4 control wires is as follows + const unsigned char phasesMatrix4[4] PROGMEM = { + 0b10100000, + 0b01100000, + 0b01010000, + 0b10010000 + }; + + //Default phases matrix for 5 control wires is as follows + const unsigned char phasesMatrix5[10] PROGMEM = { + 0b01101000, + 0b01001000, + 0b01011000, + 0b01010000, + 0b11010000, + 0b10010000, + 0b10110000, + 0b10100000, + 0b10101000, + 0b00101000 + }; + // library interface description class Stepper { public: @@ -109,7 +141,7 @@ class Stepper { int version(void); private: - void stepMotor(int this_step); + void stepMotor(int thisPhase); void initMotor(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4, int motor_pin_5, unsigned char *phasesMatrix, @@ -124,36 +156,6 @@ class Stepper { // motor pin numbers: int motor_pin[5]; // Maximum 5 control signals - - //Default phases matrix for 2 control wires is as follows - const unsigned char phasesMatrix2[4] = { - 0b01000000, - 0b11000000, - 0b10000000, - 0b00000000 - }; - - //Default phases matrix for 4 control wires is as follows - const unsigned char phasesMatrix4[4] = { - 0b10100000, - 0b01100000, - 0b01010000, - 0b10010000 - }; - - //Default phases matrix for 5 control wires is as follows - const unsigned char phasesMatrix5[10] = { - 0b01101000, - 0b01001000, - 0b01011000, - 0b01010000, - 0b11010000, - 0b10010000, - 0b10110000, - 0b10100000, - 0b10101000, - 0b00101000 - }; }; #endif From 9f55a756a98296d7a5db77e996bc4e8ded0b3d7c Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Tue, 8 Dec 2015 00:00:03 +0100 Subject: [PATCH 03/12] unsigned char approach This version saves further 7 bytes of dynamic memory by changing unnessary int variables for unsigned char in private methods and members. 100% compatibility with the current version of master branch. --- libraries/Stepper/src/Stepper.cpp | 30 +++++++++++------------------- libraries/Stepper/src/Stepper.h | 16 ++++++++-------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index bb0d3c3dc74..a824ef54ac3 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -94,7 +94,6 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) 0, 0, 0, (unsigned char*)phasesMatrix2, 2, 4); } - /* * constructor for four-pin version * Sets which wires should control the motor. @@ -155,44 +154,37 @@ void Stepper::step(int steps_to_move) while (steps_left > 0) { delayMicroseconds(this->step_delay); // move only if the appropriate delay has passed -// 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 (steps_to_move >= 0) { 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--; } - // decrement the steps left: - steps_left--; // step the motor to step number 0, 1, ..., {3 or 9} stepMotor(this->step_number % phase_count); -// } + // decrement the steps left: + steps_left--; } } /* * Moves the motor forward or backwards. */ -void Stepper::stepMotor(int thisPhase) +void Stepper::stepMotor(unsigned char thisPhase) { unsigned char phase = pgm_read_byte_near(phasesMatrix + thisPhase); unsigned char running_one = 0b10000000; - for (int i = 0; i < pin_count; i++, running_one >>= 1){ + for (unsigned char i = 0; i < pin_count; i++, running_one >>= 1){ digitalWrite(motor_pin[i], (phase & running_one)); } } @@ -200,10 +192,10 @@ void Stepper::stepMotor(int thisPhase) /* * Initialize the motor */ -void Stepper::initMotor(int number_of_steps, int motor_pin_1, int motor_pin_2, - int motor_pin_3, int motor_pin_4, - int motor_pin_5, unsigned char *phasesMatrix, - int pin_count, int phase_count) +void Stepper::initMotor(int number_of_steps, unsigned char motor_pin_1, unsigned char motor_pin_2, + unsigned char motor_pin_3, unsigned char motor_pin_4, + unsigned char motor_pin_5, unsigned char *phasesMatrix, + unsigned char pin_count, unsigned char phase_count) { this->step_number = 0; // which step the motor is on this->number_of_steps = number_of_steps; // total number of steps for this motor @@ -214,7 +206,7 @@ void Stepper::initMotor(int number_of_steps, int motor_pin_1, int motor_pin_2, this->phase_count = phase_count; // phasesMatrix is used by the stepMotor() method: this->phasesMatrix = phasesMatrix; - for (int i = 0; i < this->pin_count; i++){ + for (unsigned char i = 0; i < this->pin_count; i++){ switch (i) { case 0: this->motor_pin[i] = motor_pin_1; // Arduino pin 1 for the motor control connection diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index 2c4ef92c039..b5f333e4a21 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -141,21 +141,21 @@ class Stepper { int version(void); private: - void stepMotor(int thisPhase); - void initMotor(int number_of_steps, int motor_pin_1, int motor_pin_2, - int motor_pin_3, int motor_pin_4, - int motor_pin_5, unsigned char *phasesMatrix, - int pin_count, int phase_count); + void stepMotor(unsigned char thisPhase); + void initMotor(int number_of_steps, unsigned char motor_pin_1, unsigned char motor_pin_2, + unsigned char motor_pin_3, unsigned char motor_pin_4, + unsigned char motor_pin_5, unsigned char *phasesMatrix, + unsigned char pin_count, unsigned char phase_count); 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 phase_count; // how many phases are in use. + unsigned char pin_count; // how many pins are in use. + unsigned char phase_count; // how many phases are in use. unsigned char *phasesMatrix; // pointer to the phases Matrix int step_number; // which step the motor is on // motor pin numbers: - int motor_pin[5]; // Maximum 5 control signals + unsigned char motor_pin[5]; // Maximum 5 control signals }; #endif From a6e3b3caf26c237f10567385209036eb8fe19e96 Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Wed, 9 Dec 2015 23:38:59 +0100 Subject: [PATCH 04/12] Prevent division by zero in method setSpeed Prevent division by zero in method setSpeed --- libraries/Stepper/src/Stepper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index a824ef54ac3..2b26a1a15c0 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -139,7 +139,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, */ void Stepper::setSpeed(long whatSpeed) { - this->step_delay = 60L * 1000L * 1000L / this->number_of_steps / whatSpeed; + this->step_delay = (whatSpeed) ? 60L * 1000L * 1000L / this->number_of_steps / whatSpeed : 0; } /* From a9278c5c9cfe860a2a6342fd02d7288167d28f34 Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Wed, 9 Dec 2015 23:56:39 +0100 Subject: [PATCH 05/12] Optimization of method initMotor() Optimization of method initMotor() by refusing of the case switch --- libraries/Stepper/src/Stepper.cpp | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index 2b26a1a15c0..4efd35f2ba0 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -206,24 +206,12 @@ void Stepper::initMotor(int number_of_steps, unsigned char motor_pin_1, unsign this->phase_count = phase_count; // phasesMatrix is used by the stepMotor() method: this->phasesMatrix = phasesMatrix; + this->motor_pin[0] = motor_pin_1; + this->motor_pin[1] = motor_pin_2; + this->motor_pin[2] = motor_pin_3; + this->motor_pin[3] = motor_pin_4; + this->motor_pin[4] = motor_pin_5; for (unsigned char i = 0; i < this->pin_count; i++){ - switch (i) { - case 0: - this->motor_pin[i] = motor_pin_1; // Arduino pin 1 for the motor control connection - break; - case 1: - this->motor_pin[i] = motor_pin_2; // Arduino pin 2 for the motor control connection - break; - case 2: - this->motor_pin[i] = motor_pin_3; // Arduino pin 3 for the motor control connection - break; - case 3: - this->motor_pin[i] = motor_pin_4; // Arduino pin 4 for the motor control connection - break; - case 4: - this->motor_pin[i] = motor_pin_5; // Arduino pin 5 for the motor control connection - break; - } pinMode(this->motor_pin[i], OUTPUT); // setup the pins on the microcontroller } } From 0a4ea580b376d9398676c67f56ca4873dca6d71c Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Thu, 17 Dec 2015 22:08:57 +0100 Subject: [PATCH 06/12] Revert "Prevent division by zero in method setSpeed" This reverts commit a6e3b3caf26c237f10567385209036eb8fe19e96. --- libraries/Stepper/src/Stepper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index 4efd35f2ba0..c18666562fd 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -139,7 +139,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, */ void Stepper::setSpeed(long whatSpeed) { - this->step_delay = (whatSpeed) ? 60L * 1000L * 1000L / this->number_of_steps / whatSpeed : 0; + this->step_delay = 60L * 1000L * 1000L / this->number_of_steps / whatSpeed; } /* From 8ed5d414b589b4f4c2cd44368cf21949179ec119 Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Thu, 17 Dec 2015 23:55:54 +0100 Subject: [PATCH 07/12] Change of pin numbering renumber the pin number argument names, e.g. start at motor_pin_0, to prevent confusing between the argument names and the array positions --- libraries/Stepper/src/Stepper.cpp | 52 +++++++++++++++---------------- libraries/Stepper/src/Stepper.h | 24 +++++++------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index c18666562fd..6284d1e3a3a 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -88,9 +88,9 @@ * two-wire constructor. * Sets which wires should control the motor. */ -Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) +Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1) { - initMotor(number_of_steps, motor_pin_1, motor_pin_2, + initMotor(number_of_steps, motor_pin_0, motor_pin_1, 0, 0, 0, (unsigned char*)phasesMatrix2, 2, 4); } @@ -98,11 +98,11 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) * constructor for four-pin version * Sets which wires should control the motor. */ -Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, - int motor_pin_3, int motor_pin_4) +Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int motor_pin_3) { - initMotor(number_of_steps, motor_pin_1, motor_pin_2, - motor_pin_3, motor_pin_4, + initMotor(number_of_steps, motor_pin_0, motor_pin_1, + motor_pin_2, motor_pin_3, 0, (unsigned char*)phasesMatrix4, 4, 4); } @@ -110,27 +110,27 @@ Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, * 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) +Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int motor_pin_3, + int motor_pin_4) { - initMotor(number_of_steps, motor_pin_1, motor_pin_2, - motor_pin_3, motor_pin_4, - motor_pin_5, (unsigned char*)phasesMatrix5, 5, 10); + initMotor(number_of_steps, motor_pin_0, motor_pin_1, + motor_pin_2, motor_pin_3, + motor_pin_4, (unsigned char*)phasesMatrix5, 5, 10); } /* * universal constructor for motors with maximum five wires * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. */ -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, unsigned char *phasesMatrix, +Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int motor_pin_3, + int motor_pin_4, unsigned char *phasesMatrix, int pin_count, int phase_count) { - initMotor(number_of_steps, motor_pin_1, motor_pin_2, - motor_pin_3, motor_pin_4, - motor_pin_5, phasesMatrix, + initMotor(number_of_steps, motor_pin_0, motor_pin_1, + motor_pin_2, motor_pin_3, + motor_pin_4, phasesMatrix, pin_count, phase_count); } @@ -192,9 +192,9 @@ void Stepper::stepMotor(unsigned char thisPhase) /* * Initialize the motor */ -void Stepper::initMotor(int number_of_steps, unsigned char motor_pin_1, unsigned char motor_pin_2, - unsigned char motor_pin_3, unsigned char motor_pin_4, - unsigned char motor_pin_5, unsigned char *phasesMatrix, +void Stepper::initMotor(int number_of_steps, unsigned char motor_pin_0, unsigned char motor_pin_1, + unsigned char motor_pin_2, unsigned char motor_pin_3, + unsigned char motor_pin_4, unsigned char *phasesMatrix, unsigned char pin_count, unsigned char phase_count) { this->step_number = 0; // which step the motor is on @@ -206,11 +206,11 @@ void Stepper::initMotor(int number_of_steps, unsigned char motor_pin_1, unsign this->phase_count = phase_count; // phasesMatrix is used by the stepMotor() method: this->phasesMatrix = phasesMatrix; - this->motor_pin[0] = motor_pin_1; - this->motor_pin[1] = motor_pin_2; - this->motor_pin[2] = motor_pin_3; - this->motor_pin[3] = motor_pin_4; - this->motor_pin[4] = motor_pin_5; + this->motor_pin[0] = motor_pin_0; + 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; for (unsigned char i = 0; i < this->pin_count; i++){ pinMode(this->motor_pin[i], OUTPUT); // setup the pins on the microcontroller } diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index b5f333e4a21..1c8b74921e1 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -121,15 +121,15 @@ 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); - 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, unsigned char *phasesMatrix, + Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1); + Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int motor_pin_3); + Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int motor_pin_3, + int motor_pin_4); + Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int motor_pin_3, + int motor_pin_4, unsigned char *phasesMatrix, int pin_count, int phase_count); // speed setter method: @@ -142,9 +142,9 @@ class Stepper { private: void stepMotor(unsigned char thisPhase); - void initMotor(int number_of_steps, unsigned char motor_pin_1, unsigned char motor_pin_2, - unsigned char motor_pin_3, unsigned char motor_pin_4, - unsigned char motor_pin_5, unsigned char *phasesMatrix, + void initMotor(int number_of_steps, unsigned char motor_pin_0, unsigned char motor_pin_1, + unsigned char motor_pin_2, unsigned char motor_pin_3, + unsigned char motor_pin_4, unsigned char *phasesMatrix, unsigned char pin_count, unsigned char phase_count); unsigned long step_delay; // delay between steps, in ms, based on speed From 4c173e37ffd0e47f2c3b792894c6c9889967c07d Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Fri, 18 Dec 2015 00:56:22 +0100 Subject: [PATCH 08/12] Right-aligned patterns instead of left-aligned matthijskooijman wrote: > I think it might be clearer to right-align the patterns > instead of left-align. E.g., looking at the first line from > the 4-phase pattern, that looks like 0b10100000. > Here, the first 4 bits are meaningful, whereas the last > 4 bits are zero padding. This makes it harder to read > this table. By right-aligning, this line would look like > 0b00001010, or even simpler 0b1010, which makes > it a lot more clear. The commit implements this approach. --- .../stepper_oneRevolution_28BYJ48_ULN2003.ino | 16 ++++----- libraries/Stepper/src/Stepper.cpp | 4 +-- libraries/Stepper/src/Stepper.h | 36 +++++++++---------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino index 9cf87f423b0..bb0e86afab9 100644 --- a/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino +++ b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino @@ -36,14 +36,14 @@ const int stepsPerRevolution = 4096; // change this to fit the number of steps * 8 1 0 0 1 */ const unsigned char phasesMatrix[8] PROGMEM = { - 0b00010000, - 0b00110000, - 0b00100000, - 0b01100000, - 0b01000000, - 0b11000000, - 0b10000000, - 0b10010000 + 0b0001, + 0b0011, + 0b0010, + 0b0110, + 0b0100, + 0b1100, + 0b1000, + 0b1001 }; //initialize the stepper library on pins 8 through 11, phasesMatrix, pin_count, phase_count: diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index 6284d1e3a3a..d3ddaf31a82 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -183,8 +183,8 @@ void Stepper::step(int steps_to_move) void Stepper::stepMotor(unsigned char thisPhase) { unsigned char phase = pgm_read_byte_near(phasesMatrix + thisPhase); - unsigned char running_one = 0b10000000; - for (unsigned char i = 0; i < pin_count; i++, running_one >>= 1){ + unsigned char running_one = 1; + for (char i = pin_count - 1; i >= 0; i--, running_one <<= 1){ digitalWrite(motor_pin[i], (phase & running_one)); } } diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index 1c8b74921e1..6420a627c4f 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -89,32 +89,32 @@ //Default phases matrix for 2 control wires is as follows const unsigned char phasesMatrix2[4] PROGMEM = { - 0b01000000, - 0b11000000, - 0b10000000, - 0b00000000 + 0b01, + 0b11, + 0b10, + 0b00 }; //Default phases matrix for 4 control wires is as follows const unsigned char phasesMatrix4[4] PROGMEM = { - 0b10100000, - 0b01100000, - 0b01010000, - 0b10010000 + 0b1010, + 0b0110, + 0b0101, + 0b1001 }; //Default phases matrix for 5 control wires is as follows const unsigned char phasesMatrix5[10] PROGMEM = { - 0b01101000, - 0b01001000, - 0b01011000, - 0b01010000, - 0b11010000, - 0b10010000, - 0b10110000, - 0b10100000, - 0b10101000, - 0b00101000 + 0b01101, + 0b01001, + 0b01011, + 0b01010, + 0b11010, + 0b10010, + 0b10110, + 0b10100, + 0b10101, + 0b00101 }; // library interface description From 388460fbb8c5a2f490dd7251bd4ad7e6a81c1362 Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Sat, 19 Dec 2015 01:30:24 +0100 Subject: [PATCH 09/12] Change number_of_steps and step_number to unsigned matthijskooijman wrote: > Yeah, I think changing the interface is fine. > Passing in a negative number was never a supported > case, so there is no correct code that would break > by the change. --- libraries/Stepper/src/Stepper.cpp | 12 ++++++------ libraries/Stepper/src/Stepper.h | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index d3ddaf31a82..e39ca77a340 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -88,7 +88,7 @@ * two-wire constructor. * Sets which wires should control the motor. */ -Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1) +Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1) { initMotor(number_of_steps, motor_pin_0, motor_pin_1, 0, 0, 0, (unsigned char*)phasesMatrix2, 2, 4); @@ -98,7 +98,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1) * constructor for four-pin version * Sets which wires should control the motor. */ -Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, +Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, int motor_pin_2, int motor_pin_3) { initMotor(number_of_steps, motor_pin_0, motor_pin_1, @@ -110,7 +110,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, * constructor for five phase motor with five wires * Sets which wires should control the motor. */ -Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, +Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4) { @@ -123,7 +123,7 @@ Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, * universal constructor for motors with maximum five wires * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. */ -Stepper::Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, +Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4, unsigned char *phasesMatrix, int pin_count, int phase_count) @@ -165,7 +165,7 @@ void Stepper::step(int steps_to_move) } else { - if (this->step_number <= 0) { + if (this->step_number == 0) { this->step_number = this->number_of_steps; } this->step_number--; @@ -192,7 +192,7 @@ void Stepper::stepMotor(unsigned char thisPhase) /* * Initialize the motor */ -void Stepper::initMotor(int number_of_steps, unsigned char motor_pin_0, unsigned char motor_pin_1, +void Stepper::initMotor(unsigned number_of_steps, unsigned char motor_pin_0, unsigned char motor_pin_1, unsigned char motor_pin_2, unsigned char motor_pin_3, unsigned char motor_pin_4, unsigned char *phasesMatrix, unsigned char pin_count, unsigned char phase_count) diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index 6420a627c4f..722c8bef692 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -121,13 +121,13 @@ class Stepper { public: // constructors: - Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1); - Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, + Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1); + Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, int motor_pin_2, int motor_pin_3); - Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, + Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4); - Stepper(int number_of_steps, int motor_pin_0, int motor_pin_1, + Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4, unsigned char *phasesMatrix, int pin_count, int phase_count); @@ -142,17 +142,17 @@ class Stepper { private: void stepMotor(unsigned char thisPhase); - void initMotor(int number_of_steps, unsigned char motor_pin_0, unsigned char motor_pin_1, + void initMotor(unsigned number_of_steps, unsigned char motor_pin_0, unsigned char motor_pin_1, unsigned char motor_pin_2, unsigned char motor_pin_3, unsigned char motor_pin_4, unsigned char *phasesMatrix, unsigned char pin_count, unsigned char phase_count); unsigned long step_delay; // delay between steps, in ms, based on speed - int number_of_steps; // total number of steps this motor can take + unsigned number_of_steps; // total number of steps this motor can take unsigned char pin_count; // how many pins are in use. unsigned char phase_count; // how many phases are in use. unsigned char *phasesMatrix; // pointer to the phases Matrix - int step_number; // which step the motor is on + unsigned step_number; // which step the motor is on // motor pin numbers: unsigned char motor_pin[5]; // Maximum 5 control signals From 5b947dcc35c65ed2653dc4122fcd3700b6dd2b78 Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Sat, 19 Dec 2015 02:10:46 +0100 Subject: [PATCH 10/12] Revert implementation of motor delay in method step Motor delay must support multitasking. See: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay --- libraries/Stepper/src/Stepper.cpp | 8 +++++++- libraries/Stepper/src/Stepper.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index e39ca77a340..9f57c7a0b0f 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -153,7 +153,12 @@ void Stepper::step(int steps_to_move) // decrement the number of steps, moving one step each time: while (steps_left > 0) { - delayMicroseconds(this->step_delay); // move only if the appropriate delay has passed + 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 (steps_to_move >= 0) @@ -174,6 +179,7 @@ void Stepper::step(int steps_to_move) stepMotor(this->step_number % phase_count); // decrement the steps left: steps_left--; + } } } diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index 722c8bef692..b1d86f53a04 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -156,6 +156,7 @@ class Stepper { // motor pin numbers: unsigned char motor_pin[5]; // Maximum 5 control signals + unsigned long last_step_time; // time stamp in us of when the last step was taken }; #endif From c1442a5f17d2bae1afb4ef1b5ed7bca9e47c458b Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Sat, 19 Dec 2015 03:11:19 +0100 Subject: [PATCH 11/12] Generic constructors without zero parameters matthijskooijman wrote: > I don't think the generic constructor's arguments are > really easy to use, having to pass zeroes for unused > pins. Why not just add versions of the current > constructors, but with the added phases matrix > arguments? Fixed with this commit. --- .../stepper_oneRevolution_28BYJ48_ULN2003.ino | 2 +- libraries/Stepper/src/Stepper.cpp | 72 ++++++++++++++++--- libraries/Stepper/src/Stepper.h | 18 +++-- 3 files changed, 78 insertions(+), 14 deletions(-) diff --git a/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino index bb0e86afab9..26c62725339 100644 --- a/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino +++ b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino @@ -47,7 +47,7 @@ const unsigned char phasesMatrix[8] PROGMEM = { }; //initialize the stepper library on pins 8 through 11, phasesMatrix, pin_count, phase_count: -Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11, 0, (unsigned char*)phasesMatrix, 4, 8); +Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11, 0, 4, (unsigned char*)phasesMatrix, 8); void setup() { // 17 is the maximum for counterclockwise revolution of motor 28BYJ-48 diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index 9f57c7a0b0f..023cf4d2e69 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -91,7 +91,7 @@ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1) { initMotor(number_of_steps, motor_pin_0, motor_pin_1, - 0, 0, 0, (unsigned char*)phasesMatrix2, 2, 4); + 0, 0, 0, 2, (unsigned char*)phasesMatrix2, 4); } /* @@ -103,7 +103,7 @@ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, { initMotor(number_of_steps, motor_pin_0, motor_pin_1, motor_pin_2, motor_pin_3, - 0, (unsigned char*)phasesMatrix4, 4, 4); + 0, 4, (unsigned char*)phasesMatrix4, 4); } /* @@ -116,7 +116,61 @@ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, { initMotor(number_of_steps, motor_pin_0, motor_pin_1, motor_pin_2, motor_pin_3, - motor_pin_4, (unsigned char*)phasesMatrix5, 5, 10); + motor_pin_4, 5, (unsigned char*)phasesMatrix5, 10); +} + +/* + * universal constructor for motors with only one wire + * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. + */ +Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, + int pin_count, unsigned char *phasesMatrix, int phase_count) +{ + initMotor(number_of_steps, motor_pin_0, 0, + 0, 0, + 0, pin_count, + phasesMatrix,phase_count); +} + +/* + * universal constructor for motors with maximum two wires + * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. + */ +Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, + int pin_count, unsigned char *phasesMatrix, int phase_count) +{ + initMotor(number_of_steps, motor_pin_0, motor_pin_1, + 0, 0, + 0, pin_count, + phasesMatrix,phase_count); +} + +/* + * universal constructor for motors with maximum three wires + * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. + */ +Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int pin_count, + unsigned char *phasesMatrix, int phase_count) +{ + initMotor(number_of_steps, motor_pin_0, motor_pin_1, + motor_pin_2, 0, + 0, pin_count, + phasesMatrix,phase_count); +} + +/* + * universal constructor for motors with maximum four wires + * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. + */ +Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int motor_pin_3, int pin_count, + unsigned char *phasesMatrix, int phase_count) +{ + initMotor(number_of_steps, motor_pin_0, motor_pin_1, + motor_pin_2, motor_pin_3, + 0, pin_count, + phasesMatrix,phase_count); } /* @@ -125,13 +179,13 @@ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, */ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, int motor_pin_2, int motor_pin_3, - int motor_pin_4, unsigned char *phasesMatrix, - int pin_count, int phase_count) + int motor_pin_4, int pin_count, + unsigned char *phasesMatrix, int phase_count) { initMotor(number_of_steps, motor_pin_0, motor_pin_1, motor_pin_2, motor_pin_3, - motor_pin_4, phasesMatrix, - pin_count, phase_count); + motor_pin_4, pin_count, + phasesMatrix,phase_count); } /* @@ -200,8 +254,8 @@ void Stepper::stepMotor(unsigned char thisPhase) */ void Stepper::initMotor(unsigned number_of_steps, unsigned char motor_pin_0, unsigned char motor_pin_1, unsigned char motor_pin_2, unsigned char motor_pin_3, - unsigned char motor_pin_4, unsigned char *phasesMatrix, - unsigned char pin_count, unsigned char phase_count) + unsigned char motor_pin_4, unsigned char pin_count, + unsigned char *phasesMatrix,unsigned char phase_count) { this->step_number = 0; // which step the motor is on this->number_of_steps = number_of_steps; // total number of steps for this motor diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index b1d86f53a04..7e118aaaf7a 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -127,10 +127,20 @@ class Stepper { Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4); + Stepper(unsigned number_of_steps, int motor_pin_0, + int pin_count, unsigned char *phasesMatrix, int phase_count); + Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, + int pin_count, unsigned char *phasesMatrix, int phase_count); + Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int pin_count, + unsigned char *phasesMatrix, int phase_count); + Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int motor_pin_3, int pin_count, + unsigned char *phasesMatrix, int phase_count); Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, int motor_pin_2, int motor_pin_3, - int motor_pin_4, unsigned char *phasesMatrix, - int pin_count, int phase_count); + int motor_pin_4, int pin_count, + unsigned char *phasesMatrix, int phase_count); // speed setter method: void setSpeed(long whatSpeed); @@ -144,8 +154,8 @@ class Stepper { void stepMotor(unsigned char thisPhase); void initMotor(unsigned number_of_steps, unsigned char motor_pin_0, unsigned char motor_pin_1, unsigned char motor_pin_2, unsigned char motor_pin_3, - unsigned char motor_pin_4, unsigned char *phasesMatrix, - unsigned char pin_count, unsigned char phase_count); + unsigned char motor_pin_4, unsigned char pin_count, + unsigned char *phasesMatrix,unsigned char phase_count); unsigned long step_delay; // delay between steps, in ms, based on speed unsigned number_of_steps; // total number of steps this motor can take From de42af93f3378f07a8d57202ea723ecf3f5db136 Mon Sep 17 00:00:00 2001 From: Stanislav Kniazev Date: Sat, 19 Dec 2015 13:31:25 +0100 Subject: [PATCH 12/12] Removal of pin_count from generic constructors' interface matthijskooijman wrote: > I think pin_count can be removed here (and below) as well? Fixed with this commit. --- .../stepper_oneRevolution_28BYJ48_ULN2003.ino | 2 +- libraries/Stepper/src/Stepper.cpp | 32 +++++++++---------- libraries/Stepper/src/Stepper.h | 14 ++++---- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino index 26c62725339..7c2d6ba4eca 100644 --- a/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino +++ b/libraries/Stepper/examples/stepper_oneRevolution_28BYJ48_ULN2003/stepper_oneRevolution_28BYJ48_ULN2003.ino @@ -47,7 +47,7 @@ const unsigned char phasesMatrix[8] PROGMEM = { }; //initialize the stepper library on pins 8 through 11, phasesMatrix, pin_count, phase_count: -Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11, 0, 4, (unsigned char*)phasesMatrix, 8); +Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11, (unsigned char*)phasesMatrix, 8); void setup() { // 17 is the maximum for counterclockwise revolution of motor 28BYJ-48 diff --git a/libraries/Stepper/src/Stepper.cpp b/libraries/Stepper/src/Stepper.cpp index 023cf4d2e69..751624baa09 100644 --- a/libraries/Stepper/src/Stepper.cpp +++ b/libraries/Stepper/src/Stepper.cpp @@ -124,67 +124,65 @@ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. */ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, - int pin_count, unsigned char *phasesMatrix, int phase_count) + unsigned char *phasesMatrix, int phase_count) { initMotor(number_of_steps, motor_pin_0, 0, 0, 0, - 0, pin_count, + 0, 1, phasesMatrix,phase_count); } /* - * universal constructor for motors with maximum two wires + * universal constructor for motors with two wires * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. */ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, - int pin_count, unsigned char *phasesMatrix, int phase_count) + unsigned char *phasesMatrix, int phase_count) { initMotor(number_of_steps, motor_pin_0, motor_pin_1, 0, 0, - 0, pin_count, + 0, 2, phasesMatrix,phase_count); } /* - * universal constructor for motors with maximum three wires + * universal constructor for motors with three wires * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. */ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, - int motor_pin_2, int pin_count, - unsigned char *phasesMatrix, int phase_count) + int motor_pin_2, unsigned char *phasesMatrix, int phase_count) { initMotor(number_of_steps, motor_pin_0, motor_pin_1, motor_pin_2, 0, - 0, pin_count, + 0, 3, phasesMatrix,phase_count); } /* - * universal constructor for motors with maximum four wires + * universal constructor for motors with four wires * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. */ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, - int motor_pin_2, int motor_pin_3, int pin_count, + int motor_pin_2, int motor_pin_3, unsigned char *phasesMatrix, int phase_count) { initMotor(number_of_steps, motor_pin_0, motor_pin_1, motor_pin_2, motor_pin_3, - 0, pin_count, + 0, 4, phasesMatrix,phase_count); } /* - * universal constructor for motors with maximum five wires + * universal constructor for motors with five wires * Sets which wires should control the motor, pointer to the phases matrix, number of pins and phases. */ Stepper::Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, - int motor_pin_2, int motor_pin_3, - int motor_pin_4, int pin_count, - unsigned char *phasesMatrix, int phase_count) + int motor_pin_2, int motor_pin_3, int motor_pin_4, + unsigned char *phasesMatrix, int phase_count) { initMotor(number_of_steps, motor_pin_0, motor_pin_1, motor_pin_2, motor_pin_3, - motor_pin_4, pin_count, + motor_pin_4, 5, phasesMatrix,phase_count); } diff --git a/libraries/Stepper/src/Stepper.h b/libraries/Stepper/src/Stepper.h index 7e118aaaf7a..6f62a52f001 100644 --- a/libraries/Stepper/src/Stepper.h +++ b/libraries/Stepper/src/Stepper.h @@ -128,19 +128,17 @@ class Stepper { int motor_pin_2, int motor_pin_3, int motor_pin_4); Stepper(unsigned number_of_steps, int motor_pin_0, - int pin_count, unsigned char *phasesMatrix, int phase_count); - Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, - int pin_count, unsigned char *phasesMatrix, int phase_count); + unsigned char *phasesMatrix, int phase_count); Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, - int motor_pin_2, int pin_count, unsigned char *phasesMatrix, int phase_count); Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, - int motor_pin_2, int motor_pin_3, int pin_count, + int motor_pin_2, unsigned char *phasesMatrix, int phase_count); + Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, + int motor_pin_2, int motor_pin_3, unsigned char *phasesMatrix, int phase_count); Stepper(unsigned number_of_steps, int motor_pin_0, int motor_pin_1, - int motor_pin_2, int motor_pin_3, - int motor_pin_4, int pin_count, - unsigned char *phasesMatrix, int phase_count); + int motor_pin_2, int motor_pin_3, int motor_pin_4, + unsigned char *phasesMatrix, int phase_count); // speed setter method: void setSpeed(long whatSpeed);