Can't go back to void loop()

Hi,
Newbie here.

I'm trying to build a linear motion module by using start stop button, stepper motor and sensors.
I have a problem whenever I call a void goBackHome function, take me back to the initial state of void loop where I can re-press the start button and the cycles started again.

Below is the code I have so far, (still under development and a lot of thing to be asked :grin: ).
Appreciate if somebody could help.

void loop() {

  digitalWrite(laser_pin, HIGH);
  int onState = digitalRead(start_pin);      
  if (onState == 1) {                     // Check if on button is pressed
      if (isBusy == 0){                   // Check if motor is busy (at work)
        
        stepperX.setCurrentPosition(0);             // Set the current position
        stepperX.setMaxSpeed(1000.0);               // Set Max Speed of Stepper (Faster for regular movements)
        stepperX.setAcceleration(1000.0);           // Set Acceleration of Stepper
        isBusy = 1;                       // Set the motor to be busy (measuring is on going)
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Measuring... ");       // Inform user that a measurement is on going)

        // Loop to each measurement point
        for (int mtrPos = 0; mtrPos < stpCount; mtrPos++) {
            stepperX.moveTo(measPoint[mtrPos]);
            while(stepperX.distanceToGo() != 0) {   // While target position isn't reached up
              stepperX.run();                       // Move Stepper into position
            }
            digitalWrite(enable_pin, !digitalRead(enable_pin));
            digitalWrite(laser_pin,!digitalRead(laser_pin));
            delay(3000);                  // Conduct measurement at the position
            digitalWrite(laser_pin,!digitalRead(laser_pin));
            digitalWrite(enable_pin, !digitalRead(enable_pin));
        }                                 // Move to next measurement point/ measurement completed
        
        lcd.setCursor(0,0);
        lcd.print("Completed... ");
        goBackHome();                     // Call motor to go back home
        //isBusy = 0;                       // Set motor as not busy
      }                                   // End if isBusy
   }

  int offState = digitalRead(stop_pin);   // Check if on button is pressed
  if (offState == 1) {                    // Check if on button is pressed
      
      
      //isBusy = 0;                         // Set motor as not busy
      lcd.setCursor(0,0);
      lcd.print("Cancelled... ");
      goBackHome();
  }

 }

 void goBackHome(){
    digitalWrite(laser_pin,!digitalRead(laser_pin));
    stepperX.setMaxSpeed(1000.0);       // Set Max Speed of Stepper (Faster for regular movements)
    stepperX.setAcceleration(1000.0);   // Set Acceleration of Stepper
    stepperX.moveTo(-0);                // Set target position to home position
    TravelX = stepperX.distanceToGo();
    
    while(TravelX != 0) {               // While target position isn't reached up
      if (TravelX >= -500 && TravelX < -50) {     // Check if about to reach target position
        stepperX.setMaxSpeed(500.0);              // Slow down to set slower speed to get better accuracy
        stepperX.setAcceleration(500.0);
      }
      if (TravelX >= -50) {             // Check if about to reach target position
        stepperX.setMaxSpeed(100.0);    // Slow down to set slower speed to get better accuracy
        stepperX.setAcceleration(100.0);
      }
      stepperX.run();                   // Move Stepper into position
      }
    isBusy = 0;
    loop();
    //return true;
 }

When a routine (loop() for example) calls a subroutine, the microcontroller executes the subroutine's instructions and then resumes in the routine at the instruction immediately following that call.

But, in your case, you call loop() at the end of the subroutine goBackHome, this is unusual. I'm not sure but I think this runs the loop again from the beginning, and whatever comes after that goBackHome call is never executed. So you should remove the call to loop() at the end of your subroutine.

Here is a loop function from a large Arduino program that took several years to write...

void loop() {
  checkInputs();
  doCalculations();
  setOutputs();
  sendSerial();
}

And there is something similar to Reply #2 (although it did not take so long to write) in Several Things at a Time and in Planning and Implementing a Program

Note how each function runs very briefly and returns to loop() so the next one can be called. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

lesept:
When a routine (loop() for example) calls a subroutine, the microcontroller executes the subroutine's instructions and then resumes in the routine at the instruction immediately following that call.

Actually this is what I expect to happen.

lesept:
But, in your case, you call loop() at the end of the subroutine goBackHome, this is unusual. I'm not sure but I think this runs the loop again from the beginning, and whatever comes after that goBackHome call is never executed. So you should remove the call to loop() at the end of your subroutine.

Originally, I don't use loop() or return true; in the goBackHome function, but since it seems it fails to go back to the main loop(), I tried to call loop() at the end of the function. Unfortunately, it still fail to go back to the main loop(). It still 'freeze' after the function is called (it won't work when I press the start to again).

Below is the whole code, still can't find out what went wrong. I use external pullup resistors (10k) for each Start and Stop button.

#include <Wire.h>
//#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include "AccelStepper.h" 
// Library created by Mike McCauley at http://www.airspayce.com/mikem/arduino/AccelStepper/

// Define the pins used
//#define  1   //
//#define  2   //
#define relay_pin 3     // Pin 3 connected to sensors switching relay
#define start_pin 4            // Pin 4 connected to START button
#define stop_pin 5           // Pin 5 connected to STOP button
#define laser_pin 6     // Pin 6 connected to laser pointer
#define home_switch 7   // Pin 7 connected to Home Switch (MicroSwitch)
#define dir_pin 8       // Pin 8 connected to Direction pin
#define step_pin 9      // Pin 9 connected to Steps pin
#define MS2 10          // Pin 10 connected to MS2 pin
#define MS1 11          // Pin 11 connected to MS1 pin
#define MS0 12          // Pin 12 connected to MS1 pin
#define enable_pin 13        // Pin 13 connected to Enable pin

// AccelStepper Setup pins declaration
AccelStepper stepperX(AccelStepper::DRIVER, step_pin,dir_pin);

// Stepper travel variables
long TravelX;           // Used to store the X value entered in the Serial Monitor
int move_finished;      // Used to check if move is completed
long initial_homing;    // Used to Home Stepper at startup

//LCD I2C pins declaration
LiquidCrystal_I2C lcd(0x27,20,4);

//const int on = 4;       //on push button on pin 4
//const int off = 5;      //off push button on pin 5

int isBusy = 0;
int timer = 500;           
int measPoint[] = {0, 500, 1000, 1500, 2000, 2500};       // Array of measuring point
int stpCount = 6;       // the number of pins (i.e. the length of the array)


void setup() {
  //initilize LCD
  lcd.init();
  lcd.backlight();
 
  
  
  lcd.setCursor(0,0);
  lcd.print(" Initializing... ");

  pinMode(relay_pin, OUTPUT);
  pinMode(start_pin, INPUT);
  pinMode(stop_pin, INPUT);
  pinMode(laser_pin, OUTPUT);
  pinMode(home_switch, INPUT_PULLUP);

   /* Configure type of Steps of the Driver:
   MODE0 MODE1 MODE2 Microstep Resolution
   Low   Low   Low   Full step
   High  Low   Low   Half step
   Low   High  Low   1/4 step
   High  High  Low   1/8 step
   Low   Low   High  1/16 step
   High  Low   High  1/32 step
   Low   High  High  1/32 step
   High  High  High  1/32 step
   */
  pinMode(MS0, OUTPUT);
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(enable_pin, OUTPUT);
     
  // Configures to Half Steps
  digitalWrite(MS0, LOW);      
  digitalWrite(MS1, HIGH);
  digitalWrite(MS2, LOW);
  digitalWrite(enable_pin, LOW);

  //  Set Max Speed and Acceleration of each Steppers at startup for homing
  stepperX.setMaxSpeed(100.0);            // Set Max Speed of Stepper
  stepperX.setAcceleration(100.0);        // Set Acceleration of Stepper
 
  // Start Homing procedure of Stepper Motor at startup
  initial_homing=-1;
  while (digitalRead(home_switch)) {      // Make the Stepper move CCW until the switch is activated   
    stepperX.moveTo(initial_homing);      // Set the position to move to
    initial_homing--;                     // Decrease by 1 for next move if needed
    stepperX.run();                       // Start moving the stepper
    delay(5);
  }

  stepperX.setCurrentPosition(0);         // Set the current position as zero for now
  stepperX.setMaxSpeed(50.0);             // Set slower speed to get better accuracy
  stepperX.setAcceleration(50.0);         // Set Acceleration of Stepper
  initial_homing=1;
  while (!digitalRead(home_switch)) {     // Make the Stepper move CW until the switch is deactivated
    stepperX.moveTo(initial_homing);  
    stepperX.run();
    initial_homing++;
    delay(5);
  }

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Standby... ");
  
}
void loop() {

  digitalWrite(laser_pin, HIGH);
  int onState = digitalRead(start_pin);      
  if (onState == 1) {                     // Check if on button is pressed
      if (isBusy == 0){                   // Check if motor is busy (at work)
        
        stepperX.setCurrentPosition(0);             // Set the current position
        stepperX.setMaxSpeed(1000.0);               // Set Max Speed of Stepper (Faster for regular movements)
        stepperX.setAcceleration(1000.0);           // Set Acceleration of Stepper
        isBusy = 1;                       // Set the motor to be busy (measuring is on going)
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Measuring... ");       // Inform user that a measurement is on going)

        // Loop to each measurement point
        for (int mtrPos = 0; mtrPos < stpCount; mtrPos++) {
            stepperX.moveTo(measPoint[mtrPos]);
            while(stepperX.distanceToGo() != 0) {   // While target position isn't reached up
              stepperX.run();                       // Move Stepper into position
            }
            digitalWrite(enable_pin, !digitalRead(enable_pin));
            digitalWrite(laser_pin,!digitalRead(laser_pin));
            delay(3000);                  // Conduct measurement at the position
            digitalWrite(laser_pin,!digitalRead(laser_pin));
            digitalWrite(enable_pin, !digitalRead(enable_pin));
        }                                 // Move to next measurement point/ measurement completed
        
        lcd.setCursor(0,0);
        lcd.print("Completed... ");
        goBackHome();                     // Call motor to go back home
        //isBusy = 0;                       // Set motor as not busy
      }                                   // End if isBusy
   }

  int offState = digitalRead(stop_pin);   // Check if on button is pressed
  if (offState == 1) {                    // Check if on button is pressed
      
      
      //isBusy = 0;                         // Set motor as not busy
      lcd.setCursor(0,0);
      lcd.print("Cancelled... ");
      goBackHome();
  }

 }

 void goBackHome(){
    digitalWrite(laser_pin,!digitalRead(laser_pin));
    stepperX.setMaxSpeed(1000.0);       // Set Max Speed of Stepper (Faster for regular movements)
    stepperX.setAcceleration(1000.0);   // Set Acceleration of Stepper
    stepperX.moveTo(-0);                // Set target position to home position
    TravelX = stepperX.distanceToGo();
    
    while(TravelX != 0) {               // While target position isn't reached up
      if (TravelX >= -500 && TravelX < -50) {     // Check if about to reach target position
        stepperX.setMaxSpeed(500.0);              // Slow down to set slower speed to get better accuracy
        stepperX.setAcceleration(500.0);
      }
      if (TravelX >= -50) {             // Check if about to reach target position
        stepperX.setMaxSpeed(100.0);    // Slow down to set slower speed to get better accuracy
        stepperX.setAcceleration(100.0);
      }
      stepperX.run();                   // Move Stepper into position
      }
    isBusy = 0;
    //loop();
    //return true;
 }

What datatype is TravelX?

If it doesn't reach EXACTLY 0 the while-loop will never finish.
You might want to implement a acceptable range instead of a comparison to single value.

calling loop() is definitely wrong here.

GoBackHome is void so it doesn't return anything. Your code is good now.

You should try to troubleshoot it to understand what is blocking in the GoBackHome function.
Is it for example stepperX.moveTo(-0); ?

To do that, add serial prints before all the instructions you think might be a source of the problem, and see what appears in the serial monitor.

Ah,,it's a 'forever while' in the goBackHome function, the TravelX is never updated after it's set.
And in fact, I don't need that variable at all, the function can be make more simple.
Thank you for pointing this to me.

void goBackHome(){
    digitalWrite(laser_pin,!digitalRead(laser_pin));
    stepperX.setMaxSpeed(1000.0);         // Set Max Speed of Stepper (Faster for regular movements)
    stepperX.setAcceleration(1000.0);     // Set Acceleration of Stepper
    stepperX.moveTo(0);                   // Set target position to home position
    while(stepperX.distanceToGo()!= 0) {  // While target position isn't reached up
      stepperX.run();                     // Move Stepper into position
    }
    isBusy = 0;
}

@Robin2
I read lot of your amazing posts (which I believe it just a small part of all of your post).
I found them very useful (but sometimes they confused me also :grin: )
Would like to thank you Robin2 and all for the contribution in the learning curve of newbie people like me (even-though I can't take them all in).

P.S
I'll be back.