#include <AccelStepper.h>

#define MOTOR_PIN_STEP 3  // Pin for the stepper motor step
#define MOTOR_PIN_DIR 2   // Pin for the stepper motor direction

// Create instance of AccelStepper
AccelStepper stepper(1, MOTOR_PIN_STEP, MOTOR_PIN_DIR);  // Create a stepper motor object

// Define motor connections and limit switch pin
#define limitSwitchPin 6


// Variables to track positions, speeds, and commands
long currentPosition = 0;
const int homePosition = 0;
const int slowSpeed = 200;    // Slow speed value
const int mediumSpeed = 400;  // Medium speed value
const int fastSpeed = 600;    // fast speed value
const int maxSpeed = 800;     // maximum speed value

void setup() {
  // Start Serial communication
  Serial.begin(9600);
  // Set initial parameters
  stepper.setMaxSpeed(maxSpeed);
  stepper.setAcceleration(100);
  pinMode(limitSwitchPin, INPUT_PULLUP);

  // Move to home position
  moveUntilSwitch();
}

void loop() {
  if (Serial.available() > 0) {
    char command = Serial.read();

    switch (command) {
      case 'e':  // Command to set low speed
        stepper.setMaxSpeed(slowSpeed);
        break;
      case 'f':  // Command to set Medium speed
        stepper.setMaxSpeed(mediumSpeed);
        break;
      case 'g':  // Command to set Fest speed
        stepper.setMaxSpeed(fastSpeed);
        break;
      case 'h':  // Command to set Maximum speed
        stepper.setMaxSpeed(maxSpeed);
        break;
      case 'a':             // Command to move 5 meter distance
        moveRelative(500);  // 5 meters set the steps here for 15 meter
        break;
      case 'b':              // Command to move 10 meter distance
        moveRelative(1000);  // 10 meters set the steps here for 15 meter
        break;
      case 'c':              // Command to move 15 meter distance
        moveRelative(1500);  // 15 meters set the steps here for 15 meter
        break;
      case 'd':              // Command to move 20 meter distance
        moveRelative(2000);  // 20 meters set the steps here for 15 meter
        break;
      case 'r':  // Command to Return to starting point
        returnHome();
        break;
      case 's':  // Command to Stop motor
        stepper.stop();
        break;
      case 'i':  // Command to move motor manually forward
     stepper.setMaxSpeed(maxSpeed);
     stepper.setSpeed(maxSpeed);
      stepper.moveTo(10000);
        while (Serial.read() != 'j') {
          stepper.runSpeed();
        }
        break;
      case 'k':  // Command to move motor manually backward
        stepper.setMaxSpeed(-maxSpeed);
        stepper.setSpeed(-maxSpeed);
        while (Serial.read() != 'l' && digitalRead(limitSwitchPin)) {
          stepper.runSpeed();
        }
        break;
    }
  }
}

void moveRelative(long distance) {
  long relativeDistance = distance;

  if (currentPosition != 0) {
    relativeDistance -= currentPosition;
  }

  if (relativeDistance != 0) {
    long targetPosition = currentPosition + relativeDistance;
    stepper.moveTo(targetPosition);
    while (stepper.distanceToGo() != 0) {
      stepper.run();
      if (Serial.available() > 0 && Serial.read() == 's') {
        stepper.stop();
        break;
      }
    }
    currentPosition = targetPosition;
  }
}

void returnHome() {
  stepper.setMaxSpeed(maxSpeed);
  stepper.moveTo(homePosition);
  while (stepper.distanceToGo() != 0) {
    stepper.run();
  }
  currentPosition = homePosition;
}

void moveUntilSwitch() {
  Serial.println("Moving to home");
  stepper.setMaxSpeed(slowSpeed);
  stepper.moveTo(-10000);  // Move in CCW direction
  while (digitalRead(limitSwitchPin)) {
    stepper.run();
  }
  stepper.setCurrentPosition(homePosition);
}
A4988