// Pin Definitions
const int dirPin = 2;
const int stepPin = 3;
const int enablePin = 4;
const int stopButtonPin = 5;
const int returnButtonPin = 6;
const int resetButtonPin = 7;
// Motor settings
const int stepDelay = 800; // µs
long stepCount = 0;
// State control
enum Mode { FORWARD, REVERSE, WAIT_RESET };
Mode currentMode = FORWARD;
bool stopped = false;
// Timing for non-blocking step
unsigned long lastStepTime = 0;
// Debounce handling
bool prevReturnButton = LOW;
bool prevResetButton = LOW;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
void setup() {
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(stopButtonPin, INPUT);
pinMode(returnButtonPin, INPUT);
pinMode(resetButtonPin, INPUT);
digitalWrite(enablePin, LOW); // Enable driver
digitalWrite(dirPin, HIGH); // Initial direction: forward
}
void loop() {
unsigned long currentTime = millis();
// Read buttons
bool stopButton = digitalRead(stopButtonPin);
bool returnButton = digitalRead(returnButtonPin);
bool resetButton = digitalRead(resetButtonPin);
// Handle Return Button press (edge detection with debounce)
if (returnButton == HIGH && prevReturnButton == LOW && (currentTime - lastDebounceTime > debounceDelay)) {
if (currentMode == FORWARD) {
currentMode = REVERSE;
digitalWrite(dirPin, LOW); // Set direction to reverse
}
lastDebounceTime = currentTime;
}
prevReturnButton = returnButton;
// Handle Reset Button press
if (resetButton == HIGH && prevResetButton == LOW && (currentTime - lastDebounceTime > debounceDelay)) {
if (currentMode == WAIT_RESET) {
currentMode = FORWARD;
digitalWrite(dirPin, HIGH); // Set direction to forward
}
lastDebounceTime = currentTime;
}
prevResetButton = resetButton;
// Handle Stop Button (live read)
stopped = (stopButton == HIGH);
// === Motor control state machine ===
if (currentMode == FORWARD && !stopped) {
if (micros() - lastStepTime >= stepDelay * 2) {
stepMotor();
stepCount++;
lastStepTime = micros();
}
}
else if (currentMode == REVERSE) {
if (stepCount > 0) {
if (micros() - lastStepTime >= stepDelay * 2) {
stepMotor();
stepCount--;
lastStepTime = micros();
}
} else {
currentMode = WAIT_RESET;
}
}
// WAIT_RESET: motor remains idle until reset button is pressed
}
// Step motor one step
void stepMotor() {
digitalWrite(stepPin, HIGH);
delayMicroseconds(stepDelay);
digitalWrite(stepPin, LOW);
delayMicroseconds(stepDelay);
}