1

I'm using the AccelStepper library to control my stepper motor, and I'm having difficulty figuring out how to get my motor to stop when my button is pushed.

I can get the motor to stop once it completes its entire movement from the moveTo command, but I can't get it to stop before it finishes. I've tried using an if statement nested within the while loop I'm using to get the motor to run, but no dice.

The code as it stands is as follows:

#include <AccelStepper.h>

const int buttonPin=4;  //number of the pushbutton pin

int buttonState=0;
int motorSpeed = 9600; //maximum steps per second (about 3rps / at 16 microsteps)
int motorAccel = 80000; //steps/second/second to accelerate
int motorDirPin = 8; //digital pin 8
int motorStepPin = 9; //digital pin 9
int state = 0;
int currentPosition=0;

//set up the accelStepper intance
//the "1" tells it we are using a driver
AccelStepper stepper(1, motorStepPin, motorDirPin); 

void setup(){  
    pinMode(buttonPin,INPUT);  
    stepper.setMaxSpeed(motorSpeed);
    stepper.setSpeed(motorSpeed);
    stepper.setAcceleration(motorAccel);
    stepper.moveTo(-12000); //move 2000 steps (gets close to the top)
}

void loop(){
    while( stepper.currentPosition()!=-10000)
        stepper.run();

    // move to next state
    buttonState = digitalRead(buttonPin);
    currentPosition=stepper.currentPosition();

    // check if the pushbutton is pressed.
    // if it is, the buttonState is HIGH:
    //if stepper is at desired location
    if (buttonState == HIGH ){//need to find a way to alter current move to command
        stepper.stop();
        stepper.runToPosition();
        stepper.moveTo(12000);
    }

    if(stepper.distanceToGo() == 0)
        state=1;

    if(state==1){
        stepper.stop();
        stepper.runToPosition();
        stepper.moveTo(12000);
    }
    //these must be called as often as possible to ensure smooth operation
    //any delay will cause jerky motion
    stepper.run();
}
zmo
  • 24,463
  • 4
  • 54
  • 90
MikePinnell
  • 47
  • 2
  • 6

2 Answers2

1

I don't know if you've figured it out already, but I stumbled upon this thread and noticed something which might or might not solve your problem. I'm working with accelstepper too at the moment.

I'm having the feeling that even though you use .stop to stop the motor, you're still assigning a new destination (stepper.moveTo(12000)), after which you still run the stepper.run() command at the bottom, causing the stepper to 'run towards 12000 steps'. Maybe try this?

uint8_t button_state = 0; // cf problem 1.
void loop() {
if (digitalRead(buttonPin) == HIGH) {
    if (button_state == 0) {
        stepper.stop();
        stepper.moveTo(12000);
        button_state = 1;
    }
} else {
    button_state = 0;
}
if (stepper.distanceToGo() == 0) {
    stepper.stop();
    stepper.moveTo(12000);
}
if(button_state = 0) {
    stepper.run();
}
}

I don't know if this is going to work, but this way, if the button is pressed, the button_state variable should prevent the stepper from running when it's set on 1.

Hope this helps,

Just a passing by student

CKYong
  • 11
  • 1
0

I see three problems in your code:

  1. when you push the button, its state will be set to HIGH for the whole time you're pressing it, and it can be several loops. You'd better use a state variable that triggers what you want to do on button press only once.

  2. looking at the documentation, you're using stepper.runToPosition(), which blocks until it reaches the destination. So the more you click, the more it could get blocked. You'd better use only the stepper.moveTo() and stepper.run() method that enables to use a few cycles for interactions.

  3. at the beginning of your loop, you make your code block until stepper.currentPosition gets to -10000. So you surely are blocking until it gets there, removing all reactivity on every loop() iteration.

you may better work your loop() function out as follows:

uint8_t button_state = 0; // cf problem 1.
void loop() {
    if (digitalRead(buttonPin) == HIGH) {
        if (button_state == 0) {
            stepper.stop();
            stepper.moveTo(12000);
            button_state = 1;
        }
    } else {
        button_state = 0;
    }
    if (stepper.distanceToGo() == 0) {
        stepper.stop();
        stepper.moveTo(12000);
    }
    stepper.run();
}
zmo
  • 24,463
  • 4
  • 54
  • 90
  • I've been trying off and on to get the program to accept a state machine typr run pattern, but it for some reason refuses to do so. Though your code has fixed a bit of my problems, for some reason it still doesn't respond to the button input. I'll keep working on refining it and getting it to do what I want, but so far I've yet to get it to do what I want. Also, not sure what you meant by while loop(), did you mean it to run while the main loop is running? Sketch doesn't quite accept what you've done there, though I like the idea of it. – MikePinnell Jul 01 '13 at 20:16
  • uhuh... I saw your comment and forgot to post an answer, sorry :-s The `while loop()` was a typo, I corrected that. – zmo Jul 02 '13 at 12:19