Replying to Geoff:
Yes, I think we could have a rich discussion about problem solving! And beer always helps.
Someday.
Replying to the OP:
Here's some code that I've actually tested. Seems to work fine, but the debounce delays I mention in the comments may be necessary. I think I saw bad behavior one time that seemed to be due to bouncing.
BTW, I copied the idea of the interrupt on the button. My original inclination of reading buttons every second or less was a method I used with multiple buttons. Not needed here.
#include <AccelStepper.h>
#define dirPin 5
#define stepPin 2
#define buttonPin 3
//AccelStepper stepper(1, stepPin, dirPin);
AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin); // works for a4988 (Bipolar, constant current, step/direction driver)
// State definitions
#define RUN 01
#define RESTART 02
#define STOP_NOW 03
#define STOPPED 04
// State variable
volatile int state; // must survive interrupts
volatile int enabFlag; // controls the button interrupt
int dir;
#define FWD 1
#define REV -1
// define movement limits here
long int fwdLimit = 1000; // OP had 8000
long int revLimit = -1000;
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // use pullup on interrupt
// fix this to use digital pin number, not absolute
attachInterrupt(digitalPinToInterrupt(buttonPin), buttonInt, FALLING);
enabFlag = 1; // enable the sensor interrupt
dir = FWD; // tracks the direction of movement
state = RUN; // initial state is to run
stepper.setMaxSpeed(1000);
stepper.setAcceleration(200);
stepper.moveTo(fwdLimit);
}
void loop() {
switch (state) {
case RUN:
// Check if the Stepper has reached desired position
if ((stepper.distanceToGo() != 0)) {
stepper.run();
} else { // reverse direction
if (dir > 0) {
stepper.moveTo(revLimit);
dir = REV;
} else {
stepper.moveTo(fwdLimit);
dir = FWD;
}
}
break;
case RESTART: // come here if button is pressed to restart.
if (dir >= FWD) {
stepper.moveTo(fwdLimit); // keep going in same direction
} else {
stepper.moveTo(revLimit);
}
enabFlag = 1; // rearm the interrupt -- may need a delay here to debounce?
state = RUN;
break;
case STOP_NOW:
stepper.stop();
enabFlag = 1; // rearm the interrupt -- may need a delay here to debounce?
state = STOPPED;
break;
case STOPPED:
// Check if the Stepper has reached desired position
if ((stepper.distanceToGo() != 0)) {
stepper.run();
}
break;
// should have a default!!
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++ Interrupt service routine +++++++++++++++++++++++++++++
// Come here if falling edge on D2.
// If enable flag is true, change state
void buttonInt() {
if (enabFlag == 1) {
enabFlag = 0;
if (state == RUN) {
state = STOP_NOW;
}
else if (state == STOPPED) {
state = RESTART;
}
}
}