Optimizing Movement of Stepper Motor

Hi Community,

i am building a measurement device with Three stepper motors driving a carriage to which sensors are attached as shown in the below diagram.

I have prepared a code for the movement and reading but the code is not so efficient . i feel that there is a delay in every iteration of the loop. Can someone help me to optimizing the movement of the motors without causing delay .i have attached the code below.
i want the motors to run until they hit limit switches.

void Scan_Start(){

   delay(200);

   //Boolean commands for stopping the scan process

   bool Motor1ScanStatus = false;
   bool Motor2ScanStatus = false;
   bool Motor3ScanStatus = false;

  delay(10);
  Serial.println("SCANNING STARTED");


  for (int scaniteration=0;scaniteration<=2000;scaniteration++){

    if (handleEmergencyStop()){
     
     delay(10);

     Serial.println("SCANNING STOPPED");

     return;
    }

    if (Serial.available()>0){
       
       Commandfromexcel=Serial.readStringUntil(10);
       
       if(Commandfromexcel==Stopcommand){

        delay(10);
        Serial.println("SCANNING STOPPED");
        delay(10);
        return;

       }
    }
  
      if (!LSLeftTopPressed){
       
       moveStepper(Dirpin1,Pulsepin1,10);
    

        RawSensorData1=AnalogRead(SensorLeft);

        Distance1=GetDistance(RawSensorData1,"LEFT");
       

    }
 
      if (!LSTopRightPressed) {
                     
            moveStepper(Dirpin2,Pulsepin2,10);
                
          RawSensorData3=AnalogRead(SensorLeft);
          Distance3=GetDistance(RawSensorData3,"RIGHT");
        

      } 
    
      if (!LSRightTopPressed) {
          
          moveStepper(Dirpin3,Pulsepin3,10);
          
           RawSensorData3=AnalogRead(SensorLeft);
          Distance3=GetDistance(RawSensorData3,"RIGHT");
        
      } 
       

      Serial.println((String) "DATA," + Distance1 + "," + Distance2 + "," + Distance3);
   

    
    
  
  
   if (LSLeftTopPressed && LSTopRightPressed&& LSRightTopPressed) {

      Serial.println("SCANNING COMPLETED");
      delay(10);
   
      return;

    } 
  
  }
 
}

The code for move stepper

void moveStepper(int dirPin, int pulsePin, int steps) {
    digitalWrite(dirPin, HIGH); 
    for (int i = 0; i < steps; i++) {
        digitalWrite(pulsePin, HIGH);
         delayMicroseconds(50);
         // Adjust for smooth motion
        digitalWrite(pulsePin, LOW);
        delayMicroseconds(50);
    }
}



Code for Analog Read


int AnalogRead(int Pinnumber) {
  int RawSensorData;
  RawSensorData = analogRead(Pinnumber);

  if (RawSensorData >= 1020) {
    return 0;
  } else {
    return RawSensorData;
  }
}

Code for Get Distance Function

float GetDistance(int RawSensorData, String Sensor) {
  float distance;

  //Convert from voltage to Distance

  if (RawSensorData != 0) {
    distance = 135.000 - (RawSensorData / 1023.0) * (135.000 - 65.000);

    return distance;
  } else {
    return 0;
  }
}

Function for Handle emergency

bool handleEmergencyStop() {
  static bool emergencyTriggered = false;

  if (digitalRead(emergencycuttoffpin) == LOW) {
    if (!emergencyTriggered) {
      delay(5);
      Serial.println("EMERGENCY ACTIVATED");  // Send only once
      emergencyTriggered = true;   
    }

    return true;

  } else {
    if (emergencyTriggered) {
      delay(5);
      Serial.println("EMERGENCY DEACTIVATED");  // Optional: Send when deactivated
      emergencyTriggered = false;
      waitingForCommandPrinted = false;
    }
    return false;
  }
}

I have used interupts for the limit switches.

i want to make the for loop more efficient so that there is no choppy movement of the motors.

I am using 57600 baud rate.

please let me know if any more information is needed.

Thank you ,
Abhi
sketch_sep16c_latest.ino (22.1 KB)

Please edit your post to include the complete code, in one set of code tags, rather than bits and pieces which are difficult or impossible to follow.

The use of delay() in lines like the following is completely pointless.

    if (handleEmergencyStop()){
     delay(10);
     Serial.println("SCANNING STOPPED");

Attaching the complete code .
sketch_sep16c_latest.ino (22.1 KB)

The delay statements at the beginning and ending of the loop function are also completely pointless.

void loop() {
  delay(5);
// other code ...
delay(5);
}

Where in the stepper movement code are you testing for the limit switches?

I am focusing on the void scan_start() function.

for (int scaniteration=0;scaniteration<=2000;scaniteration++){

    if (handleEmergencyStop()){
     
     delay(10);

     Serial.println("SCANNING STOPPED");

     return;
    }

    if (Serial.available()>0){
       
       Commandfromexcel=Serial.readStringUntil(10);
       
       if(Commandfromexcel==Stopcommand){

        delay(10);
        Serial.println("SCANNING STOPPED");
        delay(10);
        return;

       }
    }
  
      if (!LSLeftTopPressed){
       
       moveStepper(Dirpin1,Pulsepin1,10);
    

        RawSensorData1=AnalogRead(SensorLeft);

        Distance1=GetDistance(RawSensorData1,"LEFT");
       

    }
 
      if (!LSTopRightPressed) {
                     
            moveStepper(Dirpin2,Pulsepin2,10);
                
          RawSensorData3=AnalogRead(SensorLeft);
          Distance3=GetDistance(RawSensorData3,"RIGHT");
        

      } 
    
      if (!LSRightTopPressed) {
          
          moveStepper(Dirpin3,Pulsepin3,10);
          
           RawSensorData3=AnalogRead(SensorLeft);
          Distance3=GetDistance(RawSensorData3,"RIGHT");
        
      } 
       

      Serial.println((String) "DATA," + Distance1 + "," + Distance2 + "," + Distance3);
   
   if (LSLeftTopPressed && LSTopRightPressed&& LSRightTopPressed) {

      Serial.println("SCANNING COMPLETED");
      delay(10);
   
      return;

    } 
  
  }

This is part that i am focusing on .

Thank you for pointing that out.

Then increase you focus to where you actually move a stepper motor. You must check the switch status BEFORE moving a stepper a single step, or otherwise you will run over the switch and miss the switch change.

There is because you are doing some floating point calculations and a bunch of other stuff which take time. You either need to optimize operations, or use a faster CPU.

i am running at 800 steps per revolution . So believe 10 steps is a very small movement to overtravel .

Also i tried running 1 step per motor every loop and the motor moves very slowly on this setting that is the reason i make motor move ten steps take a analog reading and repeat the process until i hit a limit switch .

My question is is there a better way to code this . i want three motors to move simultaneously and take readings along the path .

And that part has several completely pointless delays. What on Earth are you thinking?

I understand but these delays are only executed when if statements are satisfied . so in a normal circumstance i am not executing these delays .

Correct me if i am wrong.

one more question .
i have a print statement in every loop .

Serial.println((String) "DATA," + Distance1 + "," + Distance2 + "," + Distance3);
   

i have observed that when i increase the baudrate to 115200 the loop execution becomes faster. Does print statements take too much time to execute?

The UART serial baud rate is the number of bits transferred per second.

Divide by 11 to get the number of ASCII characters transferred per second.

i just calculated and i am sending around 17 -19 characters every loop so that is around 2 milli seconds in 115200 baud rate and 3.3 milliseconds at 57600 baud rate .

Search the forum for stepper motor library and see if you can find one that will do the simultaneous movements that you want. As you already know, your code will not move three steppers at the same time.

@Abhishyanth03

you did not manage to make it work as you want. So please follow the advice to post your complete sketch. From the very first line to the very last line.

In 98% of all users that think they can "focus" on a certain part of the code it turns out that the bug was outside the part of the code they have posted.
Are you sure that you belong to the 2% exceptions?

You should describe the wanted functionality of your code in normal words.
Normal words because you were yet unable to makeit work as you want. This demonstrates the limitations of your programming-knowledge. Having limited knowledge is no problem and the usual thing to all forum-members but it is a problem if you want to describe a functionality by code that does not show the wanted functionality. And this is the reason why you shall write the description in normal words.

The most important thing is:
do all three motors have to run in perfect syncronisation?
or
shall all three steppermotors just start at the same time but they don't have to run in perfect syncronisation?

you wrote

Your pictures show the sensors but it is unclear what sensors this are.
Mechanical touching sensors just outputting unswitched / switched
or
electronic sensors that output an analog signal?

The MobaTools library offers step-pulse creation based on a timer-interrupt.
This means the step-pulses are created independant of the other code.
You can stop each motor at any time you want by simply calling the stop-function

Thank you @StefanL38

I have edited my post to include full code .

I'll explain my needed functionality .

I have a windows application developed for this project. In the application when i click on scan button ,It sends a serial signal to Arduino . Arduino recognizes this as a command and enters the function Start_scan in Arduino sketch . This is when the motors start moving .

Right now in my code i am making the motors to travel 10 steps each and read analog signal from the sensor . At the end of each loop i send the readings to my computer application with Serial.println command . This process continues until Limit switches are pressed.

i don't want the three motors to run in perfect sync. I want them to run smoothly without any pause between each step.

The sensors that i am using are analog laser sensors with 0-5 V output.

Thank you.

Use MobaTools to run the steppers, it runs via interrupt and does not need constant polling. Then in you loop, you can read the sensor and send readings repeatedly. I think you can get the current step from MobaTools so you know what position corresponds to the reading.

The easiest way to analyse your code is to post it as a code-section
I deleted those many many many empty lines in between

//Pin Info in MEGA
//51,50,52,53---->MOSI,MISO,SCK,CS ------->Data logging pins for SD card Module
// 20,21-----> SDA,SCL ------->D23221 Module for RTC

//including libraries
#include <SoftwareSerial.h>
#include <SPI.h>
#include <avr/wdt.h>
//comand code recieved from Excel for starting scan

// allocating Limit switches 6
// Connecting all limit switches in NC condition to avoid aacidental overtravel.
// by default the switfhes will read LOW . If wire breaks down the contorller will detect HIGH.

#define DEBOUNCE_DELAY 50
unsigned long lastDebounceTime = 0;

//Interupt pins for arduino

#define LSLeftTop 2
#define LSLeftBottom 3
#define LSTopLeft 18
#define LSTopRight 19
#define LSRightTop 20
#define LSRightBottom 21

//Defining boolean values for interupts
volatile bool LSLeftTopPressed = false;
volatile bool LSLeftBottomPressed = false;
volatile bool LSTopLeftPressed = false;
volatile bool LSTopRightPressed = false;
volatile bool LSRightTopPressed = false;
volatile bool LSRightBottomPressed = false;

bool prev_LSLeftTop = HIGH;
bool prev_LSLeftBottom = HIGH;
bool prev_LSTopLeft = HIGH;
bool prev_LSTopRight = HIGH;
bool prev_LSRightTop = HIGH;
bool prev_LSRightBottom = HIGH;

//To print state only once
bool lastLSLeftTopState = false;

String Commandfromexcel;

//Basic Function Commands
String ResetControllerCommand = "8269836984";
String TroubleShootcommand = "6869668571";
String ExitCommandFromDiagnostic = "69887384";
String Stopcommand = "83847980";
String HomeCommand = "87737676";
String Startcommand = "65667273";
String Resetvoidloop = "8276797980";

String LeftMotorUp = "768580";
String LeftMotorDown = "7668798778";
String TopMotorLeft = "8476697084";
String TopMotorRight = "848273717284";
String RightMotorUp = "828580";
String RightMotorDown = "8268798778";
String LeftMotorStop = "7683847980";
String TopMotorStop = "8483847980";
String RightMotorStop = "8283847980";

//Troubleshooting Commands
//Commands for LED indicators
String GreenLEDON = "71766968";
String GreenLEDOFF = "7176797070";
String BlueLedON = "66767978";
String BlueLedOFF = "6676797070";
String BuzzerON = "66857978";
String BuzzerOFF = "6685797070";

//Troubleshooting commands for Sensors
String LeftSesnorTestON = "76837978";
String LeftSesnorTestOFF = "7683797070";
String TopSensorTestON = "84837978";
String TopSesnsorTestOFF = "8483797070";
String RightSensorTestON = "82837978";
String RightSensorTestOFF = "8283797070";

//allocating pins for buzzer and led
const int LedGreen = 41;  // This Led will blink if Ardunio has power

//alocating pins for sensor data
const int SensorLeft = A0;
const int SensorTop = A1;
const int SensorRight = A2;

//Allocating pins for stepper motor

//Left stepper motor pins
const int Enablepin1 = 9;
const int Pulsepin1 = 10;
const int Dirpin1 = 11;

//Top motor pins
const int Enablepin2 = 5;
const int Pulsepin2 = 6;
const int Dirpin2 = 7;

//Right Stepper motors
const int Enablepin3 = 24;
const int Pulsepin3 = 23;
const int Dirpin3 = 24;

//Boolean commands for Homing motors
bool Motor1HomeStatus = false;
bool Motor2HomeStatus = false;
bool Motor3HomeStatus = false;

//Allocating pins for SD Card module
//const int chipselect = 53;
//initiating steps per revolution which is constant for all drivers

const int StepsPerRevolution = 400;

//allocating variables for
String Distance1;
String Distance2;
String Distance3;

int RawSensorData1;
int RawSensorData2;
int RawSensorData3;

//pin allocation for emergency switch
const int emergencycuttoffpin = 44;

//making waiting for command print only once.
bool waitingForCommandPrinted = false;
bool serialConnected = false;
bool InDiagnosticmodecommandprinted = false;


//Functions for 6 interupsts
void LimitSwitchLeftTop() {
  unsigned long currentMillis = millis();

  if (currentMillis - lastDebounceTime > DEBOUNCE_DELAY) {
    LSLeftTopPressed = true;  // Set flag when switch is pressed
    lastDebounceTime = currentMillis;
  }
}


void LimitSwitchLeftBottom() {

  unsigned long currentMillis = millis();
  if (currentMillis - lastDebounceTime > DEBOUNCE_DELAY) {
    LSLeftBottomPressed = true;  // Set flag when switch is pressed
    lastDebounceTime = currentMillis;
  }
}


void LimitSwitchTopLeft() {
  unsigned long currentMillis = millis();

  if (currentMillis - lastDebounceTime > DEBOUNCE_DELAY) {
    LSTopLeftPressed = true;  // Set flag when switch is pressed
    lastDebounceTime = currentMillis;
  }
}

void LimitSwitchTopRight() {
  unsigned long currentMillis = millis();

  if (currentMillis - lastDebounceTime > DEBOUNCE_DELAY) {
    LSTopRightPressed = true;  // Set flag when switch is pressed
    lastDebounceTime = currentMillis;
  }
}


void LimitSwitchRightTop() {
  unsigned long currentMillis = millis();

  if (currentMillis - lastDebounceTime > DEBOUNCE_DELAY) {
    LSRightTopPressed = true;  // Set flag when switch is pressed
    lastDebounceTime = currentMillis;
  }
}

void LimitSwitchRightBottom() {
  unsigned long currentMillis = millis();

  if (currentMillis - lastDebounceTime > DEBOUNCE_DELAY) {
    LSRightBottomPressed = true;  // Set flag when switch is pressed
    lastDebounceTime = currentMillis;
  }
}







void setup() {
  // put your setup code here, to run once:
  Serial.begin(57600);
  //initializing pins for Sensor
  //Initiallizing SD Card
  //while (!Serial)
  // ;

  //Serial.print("Initializing SD card...");

  //if (!SD.begin(chipselect)) {
  //  Serial.println("initialization failed. Things to check:");
  //  Serial.println("1. is a card inserted?");
  // Serial.println("2. is your wiring correct?");
  // Serial.println("3. did you change the chipSelect pin to match your shield or module?");
  // Serial.println("Note: press reset button on the board and reopen this Serial Monitor after fixing your issue!");

  // } else {
  // Serial.println("initialization done.");
  // }

  //Intializing pins for LED this will indicate if the controller is on or off.
  pinMode(LedGreen, OUTPUT);
  //digitalWrite(LedGreen,HIGH);

  //Intializing the Limit switch pins
  pinMode(LSLeftTop, INPUT_PULLUP);
  pinMode(LSLeftBottom, INPUT_PULLUP);
  pinMode(LSTopLeft, INPUT_PULLUP);
  pinMode(LSTopRight, INPUT_PULLUP);
  pinMode(LSRightTop, INPUT_PULLUP);
  pinMode(LSRightBottom, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(LSLeftTop), LimitSwitchLeftTop, RISING);
  attachInterrupt(digitalPinToInterrupt(LSLeftBottom), LimitSwitchLeftBottom, RISING);
  attachInterrupt(digitalPinToInterrupt(LSTopLeft), LimitSwitchTopLeft, RISING);
  attachInterrupt(digitalPinToInterrupt(LSTopRight), LimitSwitchTopRight, RISING);
  attachInterrupt(digitalPinToInterrupt(LSRightTop), LimitSwitchRightTop, RISING);
  attachInterrupt(digitalPinToInterrupt(LSRightBottom), LimitSwitchRightBottom, RISING);

  //Initializing Motors Left pins

  pinMode(Dirpin1, OUTPUT);
  pinMode(Pulsepin1, OUTPUT);
  pinMode(Enablepin1, OUTPUT);

  //Initializing Motors Top pins

  pinMode(Dirpin2, OUTPUT);
  pinMode(Pulsepin2, OUTPUT);
  pinMode(Enablepin2, OUTPUT);

  //Initializing Motors Right pins
  pinMode(Dirpin3, OUTPUT);
  pinMode(Pulsepin3, OUTPUT);
  pinMode(Enablepin3, OUTPUT);

  //Intializing pins for emegencycuttoffswitch
  pinMode(emergencycuttoffpin, INPUT_PULLUP);
}

void loop() {
  delay(5);
  handleEmergencyStop();

  if (!waitingForCommandPrinted) {
    Serial.println("Waiting for command.");
    waitingForCommandPrinted = true;  // Update state to prevent re-printing
  }

  if (Serial.available() > 0) {
    handleCommand();
    waitingForCommandPrinted = false;  //when exiting from other functions making sure to print waiting for command again
  }

  //Reseting interupts flag based on state
  ResettingFlagsForInterrupts();

  delay(5);
}

//Reads Analog Data from the sensor
int AnalogRead(int Pinnumber) {
  int RawSensorData;
  RawSensorData = analogRead(Pinnumber);

  if (RawSensorData >= 1020) {
    return 0;
  } else {
    return RawSensorData;
  }
}


//Converts voltage to distance
float GetDistance(int RawSensorData, String Sensor) {
  float distance;

  //Convert from voltage to Distance

  if (RawSensorData != 0) {
    distance = 135.000 - (RawSensorData / 1023.0) * (135.000 - 65.000);

    return distance;
  } else {
    return 0;
  }
}


void Step(int Dirpin, int Pulsepin, int steps, int RPM, String Direction) {

  int stepsPerRevolution = 400;
  float pulseRate = RPM * (stepsPerRevolution / 60);
  float delayTime = 1000000 / (pulseRate); // Delay in microseconds

  if (Direction.equals("CW") || Direction.equals("clockwise")) {
    digitalWrite(Dirpin, HIGH);

  }
  else if (Direction.equals("CCW") || Direction.equals("counterclockwise")) {

    digitalWrite(Dirpin, LOW);
  }

  for (int i = 0; i < steps; i++) {

    digitalWrite(Pulsepin, HIGH);
    delayMicroseconds(delayTime / 2);
    digitalWrite(Pulsepin, LOW);
    delayMicroseconds(delayTime / 2);
  }
}

void Homemotors() {

  bool Motor1Moving = true;
  bool Motor2Moving = true;
  bool Motor3Moving = true;

  while (Motor1Moving || Motor2Moving || Motor3Moving) {
    if (Motor1Moving && !LSLeftBottomPressed) {
      Step(Dirpin1, Pulsepin1, 5, 500, "CCW");
    } else {
      Motor1Moving = false;
    }

    if (Motor2Moving && !LSTopRightPressed) {
      Step(Dirpin2, Pulsepin2, 5, 500, "CCW");
    } else {
      Motor2Moving = false;
    }

    if (Motor3Moving && !LSRightBottom) {
      Step(Dirpin3, Pulsepin3, 5, 500, "CCW");
    } else {
      Motor3Moving = false;
    }
  }
  Serial.println("Homing Motors completed");
}

void Troubleshoot() {

  Serial.println("ENTERING DIAGNOSTIC MODE");

  while (true) {

    if (!InDiagnosticmodecommandprinted) {
      Serial.println("Waiting for command.");
      InDiagnosticmodecommandprinted = true;  // Update state to prevent re-printing
    }

    handleEmergencyStop();
    HandleLimitSwitches();
    ResettingFlagsForInterrupts();

    if (Serial.available() > 0) {

      Commandfromexcel = Serial.readStringUntil(10);
      delay(50);

      //using Switch statement to Handle various buttonpress in excel
      if (Commandfromexcel == ExitCommandFromDiagnostic) {
        Serial.flush();
        delay(10);
        Serial.println("EXITING DIAGNOSTIC MODE");
        delay(10);

        //before exiting the Diagnostic mode making sure every LED, Buzzer are turned off
        /*
          delay(10);
          Serial.println("Turning Green Led OFF.");
          digitalWrite(LedGreen, LOW);
        */
        return;
      }
      else if (Commandfromexcel == LeftMotorUp) {
        delay(50);
        bool LeftMotorRunningUp = true;
        Serial.println("LeftMotor Rotating Clockwise.");
        while (LeftMotorRunningUp && !LSLeftTopPressed) {
          Step(Dirpin1, Pulsepin1, 1, 150, "CW");
          handleEmergencyStop();
          HandleLimitSwitches();

          if (Serial.available()) {
            Commandfromexcel = Serial.readStringUntil(10);
            if (Commandfromexcel == LeftMotorStop) {
              Serial.println("Stopping LeftMotor");
              LeftMotorRunningUp = false;
            }
          }
        }
      }
      else if (Commandfromexcel == LeftMotorDown) {
        delay(50);
        bool LeftMotorRunningDown = true;

        Serial.println("LeftMotor Rotating Counter clockwise");
        while (LeftMotorRunningDown && !LSLeftBottomPressed) {
          Step(Dirpin1, Pulsepin1, 1, 150, "CCW");
          handleEmergencyStop();
          HandleLimitSwitches();
          
          if (Serial.available()) {
            Commandfromexcel = Serial.readStringUntil(10);

            if (Commandfromexcel == LeftMotorStop) {
              Serial.println("Stopping LeftMotor");
              LeftMotorRunningDown = false;
            }
          }
        }
      }
      else if (Commandfromexcel == TopMotorRight) {
        delay(50);
        bool TopMotorRunningRight = true;
        Serial.println("TopMotor Rotating Clockwise");

        while (TopMotorRunningRight && digitalRead(LSTopRight) == LOW) {
          Step(Dirpin2, Pulsepin2, 1, 400, "CW");
          handleEmergencyStop();
          HandleLimitSwitches();

          if (Serial.available()) {
            Commandfromexcel = Serial.readStringUntil(10);

            if (Commandfromexcel == TopMotorStop) {
              Serial.println("Stopping TopMotor");
              TopMotorRunningRight = false;
            }
          }
        }
      }
      else if (Commandfromexcel == TopMotorLeft) {
        delay(50);
        bool TopMotorRunningLeft = true;
        Serial.println("TopMotor Rotating Counter Clockwise.");

        while (TopMotorRunningLeft && digitalRead(LSTopLeft) == LOW) {
          Step(Dirpin2, Pulsepin2, 400, 1, "CCW");
          handleEmergencyStop();
          HandleLimitSwitches();

          if (Serial.available()) {
            Commandfromexcel = Serial.readStringUntil(10);
            if (Commandfromexcel == TopMotorStop) {
              Serial.println("Stopping TopMotor");
              TopMotorRunningLeft = false;
            }
          }
        }
      }
      else if (Commandfromexcel == RightMotorUp) {
        delay(50);
        bool RightMotorRunningUp = true;
        Serial.println("RightMotor Rotating Counter Clockwise");

        while (RightMotorRunningUp && digitalRead(LSRightTop) == LOW) {
          Step(Dirpin3, Pulsepin3, 400, 1, "CW");
          handleEmergencyStop();

          if (Serial.available()) {
            Commandfromexcel = Serial.readStringUntil(10);
            if (Commandfromexcel == RightMotorStop) {
              Serial.println("Stopping Right Motor");
              RightMotorRunningUp = false;
            }
          }
        }
        HandleLimitSwitches();
      }
      else if (Commandfromexcel == RightMotorDown) {
        delay(50);
        bool RightMotorRunningDown = true;
        Serial.println("RightMotor Rotating Clockwise");

        while (RightMotorRunningDown && digitalRead(LSRightBottom) == LOW) {
          Step(Dirpin3, Pulsepin3, 200, 1, "CCW");
          handleEmergencyStop();

          if (Serial.available()) {
            Commandfromexcel = Serial.readStringUntil(10);
            
            if (Commandfromexcel == RightMotorStop) {
              Serial.println("Stopping Right Motor");
              RightMotorRunningDown = false;
            }
          }
        }

        HandleLimitSwitches();
      }
      else if (Commandfromexcel == GreenLEDON) {
        Serial.println("Turning Green LED ON.");
        digitalWrite(LedGreen, HIGH);

      } 
      else if (Commandfromexcel == GreenLEDOFF) {
        Serial.println("Turning Green Led OFF.");
        digitalWrite(LedGreen, LOW);
      }
      else if (Commandfromexcel == LeftSesnorTestON) {

        while (true) {
          if (Serial.available() > 0){
            Commandfromexcel = Serial.readStringUntil(10);

            if (Commandfromexcel == LeftSesnorTestOFF) {
              Serial.flush();
              break;
            }

          } 
          else {
            // int sensorData = random(25, 28);
            int SensorData;
            SensorData = AnalogRead(A0);
            String distance1;
            distance1 = GetDistance(SensorData, "left");

            //Serial.println("TROUBLESHOOT SENSOR1," + String(distance1));
            Serial.print("TROUBLESHOOT SENSOR1,");
            Serial.println(String(distance1));
            delay(200);
          }
        }
      }
      else if (Commandfromexcel == TopSensorTestON) {

        while (true) {
          if (Serial.available() > 0){
            Commandfromexcel = Serial.readStringUntil(10);

            if (Commandfromexcel == TopSesnsorTestOFF) {
              Serial.flush();
              break;
            }

          } 
          else {
            int sensorData = random(25, 28);
            Serial.println("TROUBLESHOOT SENSOR2," + String(sensorData));
            delay(200);
          }
        }
      }
      else if (Commandfromexcel == RightSensorTestON) {

        while (true) {
          if (Serial.available() > 0) {
            Commandfromexcel = Serial.readStringUntil(10);

            if (Commandfromexcel == RightSensorTestOFF) {
              Serial.flush();
              break;
            }

          } 
          else {
            int sensorData = random(25, 28);
            Serial.println("TROUBLESHOOT SENSOR3," + String(sensorData));
            delay(200);
          }
        }
      }
      //
    }
  }
}

void ResetController() {
  delay(10);
  Serial.println("Resetting Controller.. Please Wait 5 Seconds before proceding.");
  delay(500);
  wdt_enable(WDTO_15MS);  // Trigger a watchdog reset
  while (1);
}


void handleCommand() {
  Commandfromexcel = Serial.readStringUntil(10);
  if (Commandfromexcel == Startcommand) {
    Scan_Start();
  } else if (Commandfromexcel == HomeCommand) {
    Homemotors();
  } else if (Commandfromexcel == TroubleShootcommand) {
    Troubleshoot();
  } else if (Commandfromexcel == ResetControllerCommand) {
    ResetController();
  } else if (Commandfromexcel == Resetvoidloop) {
    return;
  }
}

bool handleEmergencyStop() {
  static bool emergencyTriggered = false;

  if (digitalRead(emergencycuttoffpin) == LOW) {
    if (!emergencyTriggered) {
      delay(5);
      Serial.println("EMERGENCY ACTIVATED");  // Send only once
      emergencyTriggered = true;
    }

    return true;

  } 
  else {
    if (emergencyTriggered) {
      delay(5);
      Serial.println("EMERGENCY DEACTIVATED");  // Optional: Send when deactivated
      emergencyTriggered = false;
      waitingForCommandPrinted = false;
    }
    return false;
  }
}


void Scan_Start() {
  delay(200);

  //Boolean commands for stopping the scan process
  bool Motor1ScanStatus = false;
  bool Motor2ScanStatus = false;
  bool Motor3ScanStatus = false;

  delay(10);
  Serial.println("SCANNING STARTED");

  for (int scaniteration = 0; scaniteration <= 2000; scaniteration++) {

    if (handleEmergencyStop()) {
      delay(10);
      Serial.println("SCANNING STOPPED");
      return;
    }

    if (Serial.available() > 0) {
      Commandfromexcel = Serial.readStringUntil(10);

      if (Commandfromexcel == Stopcommand) {
        delay(10);
        Serial.println("SCANNING STOPPED");
        delay(10);
        return;
      }
    }

    if (!LSLeftTopPressed) {
      moveStepper(Dirpin1, Pulsepin1, 10);
      RawSensorData1 = AnalogRead(SensorLeft);
      Distance1 = GetDistance(RawSensorData1, "LEFT");
    }

    if (!LSTopRightPressed) {
      moveStepper(Dirpin2, Pulsepin2, 10);
      RawSensorData3 = AnalogRead(SensorLeft);
      Distance3 = GetDistance(RawSensorData3, "RIGHT");
    }

    if (!LSRightTopPressed) {
      moveStepper(Dirpin3, Pulsepin3, 10);
      RawSensorData3 = AnalogRead(SensorLeft);
      Distance3 = GetDistance(RawSensorData3, "RIGHT");
    }

    Serial.println((String) "DATA," + Distance1 + "," + Distance2 + "," + Distance3);

    if (LSLeftTopPressed && LSTopRightPressed && LSRightTopPressed) {
      Serial.println("SCANNING COMPLETED");
      delay(10);
      return;
    }
  }
}

void HandleLimitSwitches() {
  // Check if the switch was pressed and only print if the state changed
  unsigned long currentMillis = millis();

  if (LSLeftTopPressed && prev_LSLeftTop == LOW) {
    Serial.println("LSLTON");
    prev_LSLeftTop = HIGH;
  }
  
  if (LSLeftBottomPressed && prev_LSLeftBottom == LOW) {
    Serial.println("LSLBON");
    prev_LSLeftBottom = HIGH;
  }
  
  if (LSTopLeftPressed && prev_LSTopLeft == LOW) {
    Serial.println("LSTL ON");
    prev_LSTopLeft = HIGH;
  }
  
  if (LSTopRightPressed && prev_LSTopRight == LOW) {
    Serial.println("LSTRON");
    prev_LSTopRight = HIGH;
  }
  
  if (LSRightTopPressed && prev_LSRightTop == LOW) {
    Serial.println("LSRTON");
    prev_LSRightTop = HIGH;
  }
  
  if (LSRightBottomPressed && prev_LSRightBottom == LOW) {
    Serial.println("LSRBON");
    prev_LSRightBottom = HIGH;
  }

  if (digitalRead(LSLeftTop) == LOW && prev_LSLeftTop == HIGH) {
    Serial.println("LSLTOFF");
    prev_LSLeftTop = LOW;
  }
  
  if (digitalRead(LSLeftBottom) == LOW && prev_LSLeftBottom == HIGH) {
    Serial.println("LSLBOFF");
    prev_LSLeftBottom = LOW;
  }
  
  if (digitalRead(LSTopLeft) == LOW && prev_LSTopLeft == HIGH) {
    Serial.println("LSTLOFF");
    prev_LSTopLeft = LOW;
  }
  
  if (digitalRead(LSTopRight) == LOW && prev_LSTopRight == HIGH) {
    Serial.println("LSTROFF");
    prev_LSTopRight = LOW;
  }
  
  if (digitalRead(LSRightTop) == LOW && prev_LSRightTop == HIGH) {
    Serial.println("LSRTOFF");
    prev_LSRightTop = LOW;
  }
  
  if (digitalRead(LSRightBottom) == LOW && prev_LSRightBottom == HIGH) {
    Serial.println("LSRBOFF");
    prev_LSRightBottom = LOW;
  }
  // Reset interrupt flags after processing
  ResettingFlagsForInterrupts();
}

void moveStepper(int dirPin, int pulsePin, int steps) {
  digitalWrite(dirPin, HIGH);
  for (int i = 0; i < steps; i++) {
    digitalWrite(pulsePin, HIGH);
    delayMicroseconds(50);
    // Adjust for smooth motion
    digitalWrite(pulsePin, LOW);
    delayMicroseconds(50);
  }
}


void ResettingFlagsForInterrupts() {
  if (digitalRead(LSLeftTop) == LOW) {
    LSLeftTopPressed = false;  // Reset flag when switch is released
  }

  if (digitalRead(LSLeftBottom) == LOW) {
    LSLeftBottomPressed = false;  // Reset flag when switch is released
  }

  if (digitalRead(LSTopLeft) == LOW) {
    LSTopLeftPressed = false;  // Reset flag when switch is released
  }

  if (digitalRead(LSTopRight) == LOW) {
    LSTopRightPressed = false;  // Reset flag when switch is released
  }


  if (digitalRead(LSRightTop) == LOW) {
    LSRightTopPressed = false;  // Reset flag when switch is released
  }

  if (digitalRead(LSRightBottom) == LOW) {
    LSRightBottomPressed = false;  // Reset flag when switch is released
  }
}