#include "AccelStepper.h"

// Define stepper motor connections and motor interface type
#define dirPin 3
#define stepPin 2
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

// Variables to store motor state and position
bool halted = false;
long storedPosition = 0;
bool accelerating = true;

void setup() {
  // Initialize Serial communication
  Serial.begin(9600);

  // Set the maximum speed and acceleration
  stepper.setMaxSpeed(500);
  stepper.setAcceleration(100);
}

void loop() {
  if (Serial.available() > 0) {
    char command = Serial.read();
    if (command == 'h') {
      // Halt command received
      halted = true;
      storedPosition = stepper.currentPosition();
      stepper.stop();
      Serial.println("Motor halted.");
    } else if (command == 'r') {
      // Resume command received
      halted = false;
      Serial.println("Motor resumed.");
    }
  }

  if (!halted) {
    if (accelerating) {
      accelerate();
    } else {
      deaccelerate();
    }
  } else {
    // Ensure the motor stays at the halted position
    stepper.setCurrentPosition(storedPosition);
  }
}

void accelerate() {
  stepper.moveTo(600);
  while (stepper.distanceToGo() != 0) {
    stepper.run();
    checkForHalt();
    if (halted) return;
  }
  accelerating = false; // Switch to deceleration after reaching target
}

void deaccelerate() {
  stepper.moveTo(0);
  while (stepper.distanceToGo() != 0) {
    stepper.run();
    checkForHalt();
    if (halted) return;
  }
  accelerating = true; // Switch to acceleration after reaching target
}

void checkForHalt() {
  if (Serial.available() > 0) {
    char command = Serial.read();
    if (command == 'h') {
      halted = true;
      storedPosition = stepper.currentPosition();
      stepper.stop();
      Serial.println("Motor halted.");
    }
  }
}
A4988