So, something a bit like this:
#include <AccelStepper.h>
/*
An accelstepper with an associated home and limit pin.
*/
class LimitedStepper {
public:
enum State {
GOING_HOME, GOING_LIMIT, STOPPED
};
private:
AccelStepper& stepper;
const byte homePin;
const byte limitPin;
const int homeSpeed;
const int limitSpeed;
State state;
public:
LimitedStepper(AccelStepper &attach_stepper,
byte attach_homePin,
byte attach_limitPin,
int homeSpeed,
int limitSpeed) :
stepper(attach_stepper),
homePin(attach_homePin),
limitPin(attach_limitPin),
homeSpeed(homeSpeed),
limitSpeed(limitSpeed)
{}
void setup() {
pinMode(homePin, INPUT_PULLUP);
pinMode(limitPin, INPUT_PULLUP);
}
void run() {
stepper.run();
switch (state) {
case GOING_HOME:
if (digitalRead(homePin) == LOW) {
stepper.setSpeed(0);
state = STOPPED;
}
break;
case GOING_LIMIT: if (digitalRead(limitPin) == LOW) {
stepper.setSpeed(0);
state = STOPPED;
}
break;
case STOPPED:
break;
}
}
void go_home() {
if (digitalRead(homePin) != LOW) {
stepper.setSpeed(homeSpeed);
state = GOING_HOME;
}
}
void go_limit() {
if (digitalRead(homePin) != LOW) {
stepper.setSpeed(limitSpeed);
state = GOING_LIMIT;
}
}
boolean stopped() {
return state == STOPPED;
}
};
// this depends on the details of what steppers you have.
// see the AccelStepper library docs for details - there are a couple of options, here
AccelStepper accelsteppery; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
AccelStepper accelstepperz(AccelStepper::FULL2WIRE, 6, 7);
LimitedStepper ystepper(accelsteppery,
8, 9, // home and limit pins
50, -50 // speed to move when going to the home and limit, for example
);
LimitedStepper zstepper(accelstepperz,
10, 11, // home and limit pins
-20, 20 // speed to move when going to the home and limit, for example
);
const byte controlPin = 12;
byte controlValue;
// it might be an idea to give these meaningful names.
// if the Y stepper is a cutting arm, rename 'Y_TO_LIMIT' to
// 'EXTEND_CUTTING_ARM', or something
enum State {
INIT,
HOME,
Y_TO_LIMIT,
Y_HOLDING,
Z_TO_LIMIT,
Z_HOLDING,
Z_TO_HOME,
Y_TO_HOME
} state;
const uint32_t Z_HOLDING_ms = 3000; // three seconds z delay, for example
uint32_t z_holding_start_ms;
void setup() {
// I don't know if the pinmodes for the stepper need to be set to output
// none of the accelstepper examples have that, so I assume not.
pinMode(controlPin, INPUT_PULLUP);
controlValue = digitalRead(controlPin);
ystepper.setup();
zstepper.setup();
ystepper.go_home();
zstepper.go_home();
state = INIT;
}
void loop() {
byte prevControlValue = controlValue;
controlValue = digitalRead(controlPin);
boolean controlPressed = (prevControlValue == HIGH && controlValue == LOW);
ystepper.run();
zstepper.run();
switch (state) {
case INIT:
if (ystepper.stopped() && zstepper.stopped()) {
state = HOME;
}
break;
case HOME:
if (controlPressed) {
ystepper.go_limit();
state = Y_TO_LIMIT;
}
break;
case Y_TO_LIMIT:
if (ystepper.stopped()) {
state = Y_HOLDING;
}
break;
case Y_HOLDING:
if (controlPressed) {
zstepper.go_limit();
state = Z_TO_LIMIT;
}
break;
case Z_TO_LIMIT:
if (zstepper.stopped()) {
z_holding_start_ms = millis();
state = Z_HOLDING;
}
break;
case Z_HOLDING:
if (millis() - z_holding_start_ms > Z_HOLDING_ms) {
zstepper.go_home();
state = Z_TO_HOME;
}
break;
case Z_TO_HOME:
if (zstepper.stopped()) {
ystepper.go_home();
state = Y_TO_HOME;
}
break;
case Y_TO_HOME:
if (ystepper.stopped()) {
state = HOME;
}
break;
}
}
You will need to install the accelstepper library.