AccelStepper Library - Rotate Stepper Motor one time

Hello everyone,

I’m fairly new to Arduino and I’ve never worked with the AccelStepper Library before but I really need it for this project.

What I want to do: The stepper motor is running (speed 200). When I press the button once the stepper motor spins 400 steps (two rotations) faster (speed 400). After that the stepper is going to the “normal-modus” (speed 200)

HARDWARE: Arduino Mega2560, NEMA 17 stepper motor and a4988 stepper driver

any help would be GREATLY APPRECIATED! Here’s my code so far:

#include <AccelStepper.h>

//AccelStepper stepper (1, 3, 4); // pin 3 = step, pin 4 = direction

AccelStepper stepper (1, 3, 4); // pin 3 = step, pin 4 = direction
int buttonPin = 8;

void setup() {
  stepper.setMaxSpeed(600);
  stepper.setSpeed(200);
  pinMode(buttonPin, INPUT_PULLUP);  
}

void loop() { 
   if (digitalRead(buttonPin) == HIGH){ 
   stepper.setSpeed(200);
   stepper.runSpeed();
    }
   if (digitalRead(buttonPin) == LOW){ 
   stepper.setSpeed(400);
   stepper.runSpeed();
    }
}

Thanks
Lisa

What happens when you run you code? Knowing that is a great help for diagnosing problems?

…R

Hello everyone,

I’m fairly new to Arduino and I’ve never worked with the AccelStepper Library before but I really need it for this project.

What I want to do: The stepper motor is running (speed 200). When I press the button once the stepper motor spins 400 steps (two rotations) faster (speed 400). After that the stepper is going to the “normal-modus” (speed 200)

HARDWARE: Arduino Mega2560, NEMA 17 stepper motor and a4988 stepper driver

any help would be GREATLY APPRECIATED! Here’s my code so far:

#include <AccelStepper.h>

//AccelStepper stepper (1, 3, 4); // pin 3 = step, pin 4 = direction

AccelStepper stepper (1, 3, 4); // pin 3 = step, pin 4 = direction
int buttonPin = 8;

void setup() {
  stepper.setMaxSpeed(600);
  stepper.setSpeed(200);
  pinMode(buttonPin, INPUT_PULLUP);  
}

void loop() { 
   if (digitalRead(buttonPin) == HIGH){ 
   stepper.setSpeed(200);
   stepper.runSpeed();
    }
   if (digitalRead(buttonPin) == LOW){ 
   stepper.setSpeed(400);
   stepper.runSpeed();
    }
}

Thanks
Lisa

Okay, you are right!

The stepper is running (speed 200). When I press the button is going faster (speed 400)….but just when I press the button.

Please don't double post. I am suggesting that the Moderator merges this with your other Thread where I have already responded

...R

BeatSteak4849: The stepper is running (speed 200). When I press the button is going faster (speed 400)….but just when I press the button.

That's what I would expect it to do based on your program and it seems to be the requirement that you stated in your Original Post.

What do you actually want the motor to do?

...R

If I push the button once, the stepper should rotate two times (400 steps) with a higher speed (speed 400).

Until now, the stepper is just going faster as long as i push the button.

better? Thanks for your help!!

@BeatSteak4849, please do not cross-post. Threads merged.

Sorry, I hope you can help me anyway!

Now i fixed one problem but i got a new one.

What is the following Programm doing: The stepper is running (speed 200). When I press the button the stepper stops and accelerate to maxspeed (400) with acceleration (100) for four rotations. After that the stepper stops run the speed (200)

#include <AccelStepper.h>

//AccelStepper stepper (1, 3, 4); // pin 3 = step, pin 4 = direction

AccelStepper stepper (1, 3, 4); // pin 3 = step, pin 4 = direction
int buttonpin = 8;


void setup() {
  stepper.setMaxSpeed(400);
  stepper.setAcceleration(100);
  pinMode(buttonpin, INPUT_PULLUP);  
}

void loop() { 
   if (digitalRead(buttonpin) == HIGH){ 
   stepper.setSpeed(200);
   stepper.runSpeed();
}
   if (digitalRead(buttonpin) == LOW){ 
   stepper.move(800);
   stepper.runToPosition();
}
}

The new problems are the stops. The stepper should accelerate without any stop.
Thanks in advance
Lisa

BeatSteak4849: If I push the button once, the stepper should rotate two times (400 steps) with a higher speed (speed 400).

Then you will need a very different program.

Am I correct to think that you want the motor to run continuously (indefinitely) at 200 steps/sec and occasionally you want it to do 400 steps at the higher speed?

If so then I think when you press the button your code should call runToNewPosition(nnn) where nnn is calculated as currentPosition + 400

...R

I wrote Reply #9 while you were posting Reply #8 - I suspect it will display the same symptoms as your code in Reply #8.

To my mind you are using the AccelStepper library in a way that it is not really intended for. It is not difficult to control your motor without using any library - especially as you don't seem to need acceleration.

Have a look at the examples in this Simple Stepper Code - especially the second example that uses millis() and micros() for non-blocking timing.

...R Stepper Motor Basics

Before I used the accelstepper-lib. I tried the “simple programming”.

The real Projekt is a little bit more complicated. I want to use two stepper. The stepper_1 is running constantly with speed(200) and the speed of stepper_2 depends on the button (the actual problem).

My problem with the “simple programming” (following Code) was to set the higher speed. What is the following program doing: stepper_1 is running constantly with speed(200). If I push the button the stepper stops.

Is it possible to run to steppers with two different speeds? If yes how?

int dirPin1 = 4;
int stepPin1 = 3;
int dirPin2 = 7;
int stepPin2 = 6;
int buttonpin = 8;


void setup() {
  pinMode(buttonpin, INPUT_PULLUP); 
  pinMode(dirPin1,OUTPUT);     
  pinMode(stepPin1,OUTPUT);
  digitalWrite(dirPin1,HIGH);
  digitalWrite(stepPin1,LOW);
  pinMode(dirPin2,OUTPUT);     
  pinMode(stepPin2,OUTPUT);
  digitalWrite(dirPin2,HIGH);
  digitalWrite(stepPin2,LOW);
}

void loop() {

   if (digitalRead(buttonpin) == HIGH){ 
    digitalWrite(stepPin1,HIGH);
    digitalWrite(stepPin2,HIGH);    
    delay(10);    
    digitalWrite(stepPin1,LOW);   
    digitalWrite(stepPin2,LOW);     
    delay(10); 
    }
   if (digitalRead(buttonpin) == LOW){ 
    digitalWrite(stepPin1,HIGH);
    delay(10);       
    digitalWrite(stepPin1,LOW); 
    delay(10); 
    }   
}

BeatSteak4849: Is it possible to run to steppers with two different speeds? If yes how?

Of course it is. Every CNC machine and 3D printer makes its motors run at different speeds.

If you look at my examples (especially, as I already mentioned, the second one) you will see that the speed is defined by the value of the variable millisBetweenSteps. Changing that changes the speed.

And you can make duplicate the functions with slightly different names to operate your second motor.

...R

Thanks.

I tried that new way. In the beginning it was very confusing. Thats the code until now:

byte dirPin_2 = 4;
byte stepPin_2 = 3;
byte button = 8;
boolean buttonpressed = false;
unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps_normal = 10; // milliseconds
unsigned long millisBetweenSteps_fast = 5; // milliseconds

void setup() { 
  pinMode(dirPin_2, OUTPUT);
  pinMode(stepPin_2, OUTPUT); 
  pinMode(button, INPUT_PULLUP);
}

void loop() { 
 curMillis = millis();
 readButton();
 actOnButton();
}

void readButton() {
 buttonpressed = false;
 if (digitalRead(button) == LOW) {
 buttonpressed = true;
 }
}

void actOnButton() {
 if (buttonpressed == true) {
 digitalWrite(dirPin_2, LOW);
 singleStep();
 }
}

void singleStep() {
 if (curMillis - prevStepMillis >= millisBetweenSteps_fast) {
 prevStepMillis += millisBetweenSteps_fast;
 digitalWrite(stepPin_2, HIGH);
 digitalWrite(stepPin_2, LOW);
 }
}

Now, the Stepper_2 is just running when i push the button permanent. But the stepper should run continuously (normal-speed) and getting faster if the button pushed once (fast-speed, e.g. for three rotations). I dont know where to insert the Code for the normal-speed.

 if (curMillis - prevStepMillis >= millisBetweenSteps_normal) {
 prevStepMillis += millisBetweenSteps_normal;
 digitalWrite(stepPin_2, HIGH);
 digitalWrite(stepPin_2, LOW);
 }

BeatSteak4849: Now, the Stepper_2 is just running when i push the button permanent. But the stepper should run continuously (normal-speed) and getting faster if the button pushed once (fast-speed, e.g. for three rotations). I dont know where to insert the Code for the normal-speed.

Try this version - and if it works look carefully at the changes.

byte dirPin_2 = 4;
byte stepPin_2 = 3;
byte button = 8;
boolean buttonpressed = false;
unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps_normal = 10; // milliseconds
unsigned long millisBetweenSteps_fast = 5; // milliseconds
unsigned long millisBetweenSteps;

void setup() {
  pinMode(dirPin_2, OUTPUT);
  pinMode(stepPin_2, OUTPUT);
  pinMode(button, INPUT_PULLUP);
}

void loop() {
 curMillis = millis();
 readButton();
 singleStep();
}

void readButton() {
 buttonpressed = false;
 if (digitalRead(button) == LOW) {
   millisBetweenSteps = millisBetweenSteps_fast;
 }
 else {
   millisBetweenSteps = millisBetweenSteps_slow;
 }
}

void singleStep() {
 if (curMillis - prevStepMillis >= millisBetweenSteps) {
   prevStepMillis += millisBetweenSteps;
   digitalWrite(stepPin_2, HIGH);
   digitalWrite(stepPin_2, LOW);
 }
}

...R

Thanks a lot! I'm getting closer to the goal.

Now the stepper going faster but only so long as i press the button. I tried to solve the problem with the followinf code:

byte dirPin_2 = 4;
byte stepPin_2 = 3;
byte button = 8;
boolean buttonpressed = false;
unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps_slow = 10; // milliseconds
unsigned long millisBetweenSteps_fast = 5; // milliseconds
unsigned long millisBetweenSteps;
unsigned long turnOffDelayStepper = 2000;
unsigned long stepperTurneFastAT

void setup() {
  pinMode(dirPin_2, OUTPUT);
  pinMode(stepPin_2, OUTPUT);
  pinMode(button, INPUT_PULLUP);
}

void loop() {
 curMillis = millis();
 readButton();
 singleStep();
}

void readButton() {
 buttonpressed = false;
 if (digitalRead(button) == LOW) {
   stepperTurneFastAT = millis();
 }
 if (digitalRead(button) == LOW && turnOffDelayStepper - stepperTurneFastAT >= 0){
   millisBetweenSteps = millisBetweenSteps_fast;
 }
 else {
   millisBetweenSteps = millisBetweenSteps_slow;
 }
}

void singleStep() {
 if (curMillis - prevStepMillis >= millisBetweenSteps) {
   prevStepMillis += millisBetweenSteps;
   digitalWrite(stepPin_2, HIGH);
   digitalWrite(stepPin_2, LOW);
 }
}

Is there a better way to "hold" the fast-speed for a time? A defined distance (steps) would be better. Is there any solution for that? I couldn't test it. Im having some trouble, im getting this error. "error: expected initializer before 'void'"

Thanks Lisa

Here is a hint …

Imagine that you have a variable called fastStepsStillToGo and when it is zero the long interval is used.

Then when you press the button the number is changed to (say) 400 and the short interval is used. And for every step the variable is decremented (but not below 0, obviously).

That way you can choose any number of steps for the high speed.

…R

Thanks for your help! The use of millis() is quite cool!

Now, exchanged the button with one photoresistor (PR). At the beginning, light turns the PR-signal down (1-10) and both stepper are running slow (20 millis). If the light goes off the PR-signal turns high (200-500) and both stepper are running fast (5 mills).

//Stepper
  //Stepper_1
    byte dirPin_1 = 4;
    byte stepPin_1 = 3;
  //Stepper_2
    byte dirPin_2 = 7;
    byte stepPin_2 = 6;
  // Photoresistor
    int PRPin = A0;
    int StartValuePR;
    int Accuracy = 50;    
 // Time etc.
    unsigned long currentMillis;
    unsigned long prevStepMillis = 0;
    unsigned long prevStepMillis_slow = 0;
    unsigned long prevStepMillis_fast = 0;
    unsigned long millisBetweenSteps_fast = 5; // milliseconds 
    unsigned long millisBetweenSteps_slow = 20; // milliseconds
    unsigned long millisBetweenSteps;


void setup() {
    pinMode(PRPin,INPUT);
    pinMode(stepPin_1, OUTPUT);
    pinMode(dirPin_1, OUTPUT);
    pinMode(stepPin_2, OUTPUT);
    pinMode(dirPin_2, OUTPUT);
    StartValuePR = analogRead(PRPin);
    }

void loop() {
    currentMillis = millis();
    readPR();
    singleStep();
    }

void readPR(){
     if (analogRead(PRPin) - Accuracy < StartValuePR){
        millisBetweenSteps = millisBetweenSteps_slow;
        }
     if (analogRead(PRPin) - Accuracy > StartValuePR){
        millisBetweenSteps = millisBetweenSteps_fast;
        }
    }

void singleStep() {
     if (currentMillis - prevStepMillis >= millisBetweenSteps) {
        prevStepMillis += millisBetweenSteps;
        digitalWrite(stepPin_1, HIGH);
        digitalWrite(stepPin_1, LOW);
        digitalWrite(stepPin_2, HIGH);
        digitalWrite(stepPin_2, LOW);
        }
     }

Now, I want the following: If the light goes off (PR-signal turns high) → stepper_2 is running continuously (slow – 20 millis) and just stepper_1 are running faster (5 millis). How can I control the two different speeds?

thank you in advance!!
Lisa

You need to make separate singleStep() functions for each motor (with different function names) and then create a separate millisBetweenSteps variable for each motor (again with different names).

...R