I'm using a stepper motor to run a small pump, there are a couple of different modes of operation one being a purge mode where the pump turns one revolution when a button is pressed. The program is a bit long so I broke just the purge mode out into a separate sketch but I get the same results. I'm using a Uno with a 28BYJ-48 stepper motor with a ULN2003 driver board.
I want to set the speed of the motor, I set the speed, at different rates, then run the motor and runSpeed(). The motor speed doesn't change and the motor will rotate one revolution then goes reverse about an 1/8 of a turn. If I comment out just the line with the runSpeed() call in goes the one revolution then stops, no reverse.
How do I control the speed? and why does it go reverse after stopping?
Thanks for all comments and advise
Here's the code
[code]
// Purge Mode development sketch
#include <AccelStepper.h>
#define HALFSTEP 8
#define motorPin1 3 // IN1 on the ULN2003 driver 1
#define motorPin2 4 // IN2 on the ULN2003 driver 1
#define motorPin3 5 // IN3 on the ULN2003 driver 1
#define motorPin4 6 // IN4 on the ULN2003 driver 1
#define purgePb 9 // purge cycle pushbutton
int i = 0;
int purgeMode = 0; // purge mode run bit
int purgeSteps = 0;
float purgeDwell = 0.014; // Purge dwell time between steps
int purgeIncr = 0; // purge step counter
int totalPurgeSteps = 4096; // number of steps in purge cycle 1 revolution
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepMotor(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
Serial.begin(9600);
stepMotor.setMaxSpeed(500.0);
stepMotor.setAcceleration(100.0);
stepMotor.setSpeed(50);
pinMode(purgePb, INPUT_PULLUP); // input for purge pushbutton
}
void loop() {
// run purge cycle from pushbutton control
if (digitalRead(purgePb) == LOW) {
purgeMode = 1;
stepMotor.setCurrentPosition(0);
stepMotor.moveTo(4096);
stepMotor.setSpeed(250);
} // end if(digitalRead(purgePb)
// Run Purge Mode
if (purgeMode == 1) {
stepMotor.enableOutputs(); // turn on stepper motor
stepMotor.run();
stepMotor.runSpeed();
// while (stepMotor.isRunning()) {
// stepMotor.run();
// }
if (!stepMotor.isRunning()) {
stepMotor.stop();
stepMotor.disableOutputs();
stepMotor.setCurrentPosition(0);
purgeMode = 0;
}
} // end if(purgeMode == 1)
}
For some strange reason your code calls both the run() and the runSpeed() functions. You can only use one of them so you need to decide which you want to use.
If you still have a problem post the latest version of your program and tell us in detail what it actually does and what you want it to do that is different.
Robin2, the strange reason is I don't really know what I'm doing, trying to learn and figure it out. I assumed, you know what that means, is that run() ran the stepper and runSpeed() was to run it at the speed I had set in speedSet(). I'll make the changes you suggest and let you know how I make out.
Robin2, one of the benefits of working from home is I was able to give this a try. If I comment out the line with stepMotor.runSpeed() and leave the stepMotor.Run() the motor does do 1 revolution and stop, I tried a couple of different values in stepMotor.setSpeed() but that didn't change the speed, I didn't think it would but thought I would try.
I then commented out stepMotor.run() and ran it with stepMotor.runSpeed(). this time it didn't stop after 1 revolution, I let it go a couple of times before I stopped it. It would change speed based on the value I put in stepMotor.setSpeed().
So using just stepMotor.runSpeed() will help me control the speed but now why doesn't it stop after 1 revolution as it does with stepMotor,run()?
Robin2, a second thought, am I telling it to go one revolution the best way or is there a different way I should do it? When I press the button to start the purge cycle I first set the stepper motors position to 0, stepMotor,setCurrenPosition(0), then I tell it to go to position 4096 for the 1 revolution, stepMotor.moveTo(4096).
Here's the revised code. I commented out the stepMotor.run()) and enabled the stepMotor.runSpeed(). I can now control the speed but now it doesn't stop after 1 revolution, just keeps going.
thanks
// Purge Mode development sketch
#include <AccelStepper.h>
#define HALFSTEP 8
#define motorPin1 3 // IN1 on the ULN2003 driver 1
#define motorPin2 4 // IN2 on the ULN2003 driver 1
#define motorPin3 5 // IN3 on the ULN2003 driver 1
#define motorPin4 6 // IN4 on the ULN2003 driver 1
#define purgePb 9 // purge cycle pushbutton
int i = 0;
int purgeMode = 0; // purge mode run bit
int purgeSteps = 0;
float purgeDwell = 0.014; // Purge dwell time between steps
int purgeIncr = 0; // purge step counter
int totalPurgeSteps = 4096; // number of steps in purge cycle 1 revolution
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepMotor(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
Serial.begin(9600);
stepMotor.setMaxSpeed(500.0);
stepMotor.setAcceleration(100.0);
stepMotor.setSpeed(50);
pinMode(purgePb, INPUT_PULLUP); // input for purge pushbutton
}
void loop() {
// run purge cycle from pushbutton control
if (digitalRead(purgePb) == LOW) {
purgeMode = 1;
stepMotor.setCurrentPosition(0);
stepMotor.moveTo(4096);
stepMotor.setSpeed(250);
} // end if(digitalRead(purgePb)
// Run Purge Mode
if (purgeMode == 1) {
stepMotor.enableOutputs(); // turn on stepper motor
// stepMotor.run();
stepMotor.runSpeed();
// while (stepMotor.isRunning()) {
// stepMotor.run();
// }
if (!stepMotor.isRunning()) {
stepMotor.stop();
stepMotor.disableOutputs();
stepMotor.setCurrentPosition(0);
purgeMode = 0;
}
} // end if(purgeMode == 1)
}
I loaded in your sketch and the motor barely moves. It's trying to as I can see the LED's on the driver board blinking but it's about 1 or 2 seconds between blinks. I tried giving it a faster speed, 250, but the same thing.
I then tried your previous suggestion of using runToPosition, that works as far as I can control how far the motor goes by setting a different value in stepMotor.moveToPosition() but I can't change the speed with setSpeed().
I then tried runToNewPosition, had to comment out runToPosition and put the value in runToNewPosition(4096) that also works as far as being able to set the distance traveled but also can not set the speed.
Here's the revised sketch
// Purge Mode development sketch
#include <AccelStepper.h>
#define HALFSTEP 8
#define motorPin1 3 // IN1 on the ULN2003 driver 1
#define motorPin2 4 // IN2 on the ULN2003 driver 1
#define motorPin3 5 // IN3 on the ULN2003 driver 1
#define motorPin4 6 // IN4 on the ULN2003 driver 1
#define purgePb 9 // purge cycle pushbutton
int i = 0;
int purgeMode = 0; // purge mode run bit
int purgeSteps = 0;
float purgeDwell = 0.014; // Purge dwell time between steps
int purgeIncr = 0; // purge step counter
int totalPurgeSteps = 4096; // number of steps in purge cycle 1 revolution
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepMotor(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
Serial.begin(9600);
stepMotor.setMaxSpeed(500.0);
stepMotor.setAcceleration(100.0);
stepMotor.setSpeed(50);
pinMode(purgePb, INPUT_PULLUP); // input for purge pushbutton
}
void loop() {
// run purge cycle from pushbutton control
if (digitalRead(purgePb) == LOW) {
purgeMode = 1;
stepMotor.setCurrentPosition(0);
//stepMotor.moveTo(4096);
// stepMotor.setSpeed(50);
} // end if(digitalRead(purgePb)
// Run Purge Mode
if (purgeMode == 1) {
stepMotor.enableOutputs(); // turn on stepper motor
// stepMotor.run();
stepMotor.setSpeed(250);
stepMotor.runSpeed();
stepMotor.runToNewPosition(2096);
// while (stepMotor.isRunning()) {
// stepMotor.run();
// }
if (!stepMotor.isRunning()) {
stepMotor.stop();
stepMotor.disableOutputs();
stepMotor.setCurrentPosition(0);
purgeMode = 0;
}
} // end if(purgeMode == 1)
}
Stumpy_L:
I loaded in your sketch and the motor barely moves. It's trying to as I can see the LED's on the driver board blinking but it's about 1 or 2 seconds between blinks. I tried giving it a faster speed, 250, but the same thing.
How do you know that the HalfStep setting uses the value 8?
I suggest you make life even simpler and use AccelStepper::FULL4WIRE - see the AccelStepper documentation
Good point on the HALFSTEP, this program started out as one my customer had given me and he had defined that, I did try changing the number from 8 to 16 thinking that would give me full step, I just got an error, I then tried changing it to FULL4WIRE as you suggested but also got an error, that was a week or so ago. I had other things to work on so I left it for now hoping to get back to it. I tried again now but see what I was doing wrong, I replaced HALFSTEP with FULL4WIRE and got an error that it wasn't declared in this scope, I see that I had to put "AccelStepper::FULL4WIRE" there instead. I did that and loaded the sketch. It works as before, will go to the position I defined but I can't control the speed.
The revised sketch is below.
I thank you for your time and patience with this, most appreciated.
// Purge Mode development sketch
#include <AccelStepper.h>
// #define HALFSTEP 8
#define motorPin1 3 // IN1 on the ULN2003 driver 1
#define motorPin2 4 // IN2 on the ULN2003 driver 1
#define motorPin3 5 // IN3 on the ULN2003 driver 1
#define motorPin4 6 // IN4 on the ULN2003 driver 1
#define purgePb 9 // purge cycle pushbutton
int i = 0;
int purgeMode = 0; // purge mode run bit
int purgeSteps = 0;
float purgeDwell = 0.014; // Purge dwell time between steps
int purgeIncr = 0; // purge step counter
int totalPurgeSteps = 4096; // number of steps in purge cycle 1 revolution
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepMotor(AccelStepper::FULL4WIRE, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
Serial.begin(9600);
stepMotor.setMaxSpeed(500.0);
stepMotor.setAcceleration(100.0);
stepMotor.setSpeed(50);
pinMode(purgePb, INPUT_PULLUP); // input for purge pushbutton
}
void loop() {
// run purge cycle from pushbutton control
if (digitalRead(purgePb) == LOW) {
purgeMode = 1;
stepMotor.setCurrentPosition(0);
//stepMotor.moveTo(4096);
// stepMotor.setSpeed(50);
} // end if(digitalRead(purgePb)
// Run Purge Mode
if (purgeMode == 1) {
stepMotor.enableOutputs(); // turn on stepper motor
// stepMotor.run();
stepMotor.setSpeed(50);
stepMotor.runSpeed();
stepMotor.runToNewPosition(2096);
// while (stepMotor.isRunning()) {
// stepMotor.run();
// }
if (!stepMotor.isRunning()) {
stepMotor.stop();
stepMotor.disableOutputs();
stepMotor.setCurrentPosition(0);
purgeMode = 0;
}
} // end if(purgeMode == 1)
}
I tried the FULL4WIRE in you sketch and get the same results, it driver the motor extremely slow, I have that sketch in case I've missed something. I also tried 4 as JCA34F suggested in both your sketch and mine and get the same results as before.
I do try to keep my codes simple and build on them a step at a time, that's why I took this part of the main program and made a seperate sketch out of it.
thanks
John
#include <AccelStepper.h>
// #define HALFSTEP 8
#define motorPin1 3 // IN1 on the ULN2003 driver 1
#define motorPin2 4 // IN2 on the ULN2003 driver 1
#define motorPin3 5 // IN3 on the ULN2003 driver 1
#define motorPin4 6 // IN4 on the ULN2003 driver 1
AccelStepper stepMotor(AccelStepper::FULL4WIRE, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
Serial.begin(9600);
stepMotor.setSpeed(500);
stepMotor.moveTo(4096);
}
void loop() {
stepMotor.runSpeed();
}
@Robin2 I have gotten my sketch to work as I wanted, the motor will do 1 revolution at the speed I set. I went back to reply #6 where I could control the speed but the motor didn't stop. I modified the stop logic I had. In the if statement I changed "if(!stepMotor.isRunning())" to if(stepMotor.distanceToGo <= 0)" I saw the distanceToGo function while reviewing the document you sent me the link for in reply #10.
I can now control the distance the motor travels and the speed it goes. The sketch is below.
Thanks again for all your help and the time you have spent to help me with my problem.
John
// Purge Mode development sketch
#include <AccelStepper.h>
#define motorPin1 3 // IN1 on the ULN2003 driver 1
#define motorPin2 4 // IN2 on the ULN2003 driver 1
#define motorPin3 5 // IN3 on the ULN2003 driver 1
#define motorPin4 6 // IN4 on the ULN2003 driver 1
#define purgePb 9 // purge cycle pushbutton
int i = 0;
int purgeMode = 0; // purge mode run bit
int purgeSteps = 0;
float purgeDwell = 0.014; // Purge dwell time between steps
int purgeIncr = 0; // purge step counter
int totalPurgeSteps = 4096; // number of steps in purge cycle 1 revolution
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepMotor(AccelStepper::FULL4WIRE, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
Serial.begin(9600);
stepMotor.setMaxSpeed(500.0);
stepMotor.setAcceleration(100.0);
pinMode(purgePb, INPUT_PULLUP); // input for purge pushbutton
}
void loop() {
// run purge cycle from pushbutton control
if (digitalRead(purgePb) == LOW) {
purgeMode = 1;
stepMotor.setCurrentPosition(0);
stepMotor.moveTo(2048);
} // end if(digitalRead(purgePb)
// Run Purge Mode
if (purgeMode == 1) {
stepMotor.enableOutputs(); // turn on stepper motor
stepMotor.setSpeed(75);
stepMotor.runSpeed();
if (stepMotor.distanceToGo() <= 0) { //stop stepper when at entered distance
stepMotor.stop();
stepMotor.disableOutputs();
stepMotor.setCurrentPosition(0);
purgeMode = 0;
}
} // end if(purgeMode == 1)
} // end loop
Stumpy_L:
I do try to keep my codes simple and build on them a step at a time, that's why I took this part of the main program and made a seperate sketch out of it.
Yet in the updated program in Reply #14 you still could not resist changing the speed from what it was in the code in Reply #8
And while you have posted the updated program you have not told us what happens when you run it.
I don't know how to include a quote from the previous reply, I'll look into that more later. In my reply this morning I said "I can now control the distance the motor travels and the speed it goes". By changing the value in stepMotor.moveTo() The motor will go a full turn, 2048, a half turn, 1024, or twice around, 4096. Then by changing the value in stepMotor.setSpeed() it will go very slow, 25, or fast, 450.
I change the values, download the sketch and press the button, goes where I want it and how fast I want it to go.
Thanks again
John