问题
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();
}
回答1:
I see three problems in your code:
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.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()
andstepper.run()
method that enables to use a few cycles for interactions.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 everyloop()
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();
}
回答2:
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
来源:https://stackoverflow.com/questions/17385136/having-trouble-getting-my-stepper-motor-to-respond-to-my-button-sensor-in-arduin