Code Circumventing loops

Hi everyone, this is my first post here and upon reading the guidelines it says I should try to be as clear and concise as possible so here goes:

Essentially I’m attempting to use an Arduino DUE to create an XY gantry using stepper motors to move a sensor (external sensor doesn’t need to be a part of the code) around a room.

I have 2 limit switches one for each axis and I am trying to write a code that returns them to the ‘home point’ before starting again.

When I try to run the code it skips the initial loops and moves on to the actual moving of the sensor regardless if its at the home position (home position is when both limit switches are closed).

I would also like to add a function that will return it home at any time however I don’t know how to do this concurrently with the other code.

I really appreciate the assistance of anyone who sees this to have a look at my code and see why it isn’t doing the operation I expected.

Regards,

Isaac.

  #include <Stepper.h>

const int stepRate = 400;

Stepper myStepperX(stepRate,  8, 9, 10, 11); 
Stepper myStepperY(stepRate,  4, 5, 6, 7); 

const int systemOn = 14;
const int startButton = 15; 
//const int returnHome =31;
const int led =  16; 
const int limitY=1;
const int limitX=2;

int startButtonState = 0;
//int returnHomeState = 0;           
int systemOnState =  0;
 int imHome= 0;
 int xState =0;
 int yState=0;

void setup() 
{
  myStepperY.setSpeed(100);
  myStepperX.setSpeed(100);// set the speed at 100 rpm
  
  Serial.begin(9600); 
  
  pinMode(led, OUTPUT);
  pinMode(startButton,  INPUT);
//  pinMode(returnHome,  INPUT);
  pinMode(limitX, INPUT);
  pinMode(limitY, INPUT);
  pinMode(systemOn, INPUT);
            

}

void loop() {

int stepCount = 0;

systemOnState= digitalRead(systemOn);

if (systemOnState==1)
{

tryagain:
xState=digitalRead(limitX);
yState=digitalRead(limitY);

 while (digitalRead(limitX)== 0)
         {
            myStepperX.step(-stepRate); 
         }
  
 while (digitalRead(limitY)==0)
          {
             myStepperY.step(-stepRate); 
          }

   if ((xState == HIGH) && (yState == HIGH))
  {
     imHome=1;
  }
  else
  {
    goto tryagain;
  }
  
  startButtonState=digitalRead(startButton);
  
  if ((startButtonState==1) && (imHome==1))
 {
    
    for ( int stepYCount =0; stepYCount <33; stepYCount++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate); 
    
   for ( int stepYCount2 =0; stepYCount2 <33; stepYCount2++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate); 
    
for ( int stepYCount3 =0; stepYCount3 <33; stepYCount3++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    
    for ( int stepYCount4 =0; stepYCount4 <33; stepYCount4++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    
    for ( int stepYCount5 =0; stepYCount5 <33; stepYCount5++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate); 

    for ( int stepYCount6 =0; stepYCount6 <33; stepYCount6++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    
    for ( int stepYCount7 =0; stepYCount7 <33; stepYCount7++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount8 =0; stepYCount8 <33; stepYCount8++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount9 =0; stepYCount9 <33; stepYCount9++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount10 =0; stepYCount10 <33; stepYCount10++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount11 =0; stepYCount11 <33; stepYCount11++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount12 =0; stepYCount12 <33; stepYCount12++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
myStepperX.step(stepRate);
    for ( int stepYCount13 =0; stepYCount13 <33; stepYCount13++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    
myStepperX.step(stepRate);
    
    for ( int stepXHome =0; stepXHome <13; stepXHome++)
    {
      myStepperX.step(-stepRate);
    }
  }
}
}
  pinMode(startButton,  INPUT);
//  pinMode(returnHome,  INPUT);
  pinMode(limitX, INPUT);
  pinMode(limitY, INPUT);

It is critical that you tell us how the switches are wired.

It would make for far simpler wiring if you used INPUT_PULLUP as the mode. Then, HIGH would mean not pressed, and LOW would mean pressed.

tryagain:

Get rid of all labels and goto statements.

Learn to write functions. goHome() should make the steppers move towards home until the carriage trips the limit switch. Whether you call that function, or not, would depend on whether or not the go-home switch had been pressed.

You can easily test whether goHome() is working. Testing that complete mess of code is much harder.

Once you KNOW that goHome() works, you never need to visit the code again.

PaulS:
It is critical that you tell us how the switches are wired.

The limit switches are connected to one side with 5V and the other to a port of the arudino ( i tried using external resistors but didnt get much luck, dont think i was using the right resistor value)

i really appreciate the advice! I just don't understand, if the code is in the middle of a loop how can it still run goHome(). Can it work concurrently?

Do you have an example of this?

kind regards,

Isaac

I just don't understand, if the code is in the middle of a loop how can it still run goHome().

Why would you need for the machine to go home "in the middle of a loop"?

Explain what circumstances would cause the machine to go home. Then, we can call the goHome() method at the proper point(s) in the loop() (or other) function(s).

PaulS:
Why would you need for the machine to go home "in the middle of a loop"?

I envisioned the return home button to be similar to a reset of which if the operator would like to return back to the home position at any time they would press the button.

also sorry did you have an example of the goHome() code?

Could you not check the button state while in the loop?

What stepper motors and stepper motor drivers are you using?

The usual way to make a stepper motor go home is to repeatedly move one step at a time towards the home switch and check the switch between each step.

If you have a system where you would like to verify the home position regularly then you could put the home switch near the centre of travel and when the motor gets to the home point set the position to NNNN rather than to 0. During subsequent moves if the switch is triggered and the position is not NNNN (as it should be) your code could correct it.

...R
Stepper Motor Basics
Simple Stepper Code

also look up the AccelStepper library

Hi guys I’ve tried to add a function I was wondering if this is what you mean?

Also you mentioned the code is a complete mess I was wondering if anyone had any advice on how to improve it.

  #include <Stepper.h>

const int stepRate = 400;

Stepper myStepperX(stepRate,  8, 9, 10, 11); 
Stepper myStepperY(stepRate,  4, 5, 6, 7); 

const int systemOn = 14;
const int startButton = 15; 
//const int returnHome =31;
const int led =  16; 
const int limitY=1;
const int limitX=2;

int startButtonState = 0;
//int returnHomeState = 0;           
int systemOnState =  0;
 int imHome= 0;
 int xState =0;
 int yState=0;

 void returnHome() {
   while (digitalRead(limitX)== HIGH)
         {
            myStepperX.step(-stepRate); 
         }
  
 while (digitalRead(limitY)==HIGH)
          {
             myStepperY.step(-stepRate); 
          }

   if ((xState == LOW) && (yState == LOW))
  {
     imHome=1;
  }
}

void setup() 
{
  myStepperY.setSpeed(100);
  myStepperX.setSpeed(100);// set the speed at 100 rpm
  
  Serial.begin(9600); 
  
  pinMode(led, OUTPUT);
  pinMode(startButton,  INPUT);
//  pinMode(returnHome,  INPUT);
  pinMode(limitX, INPUT_PULLUP);
  pinMode(limitY, INPUT_PULLUP);
  pinMode(systemOn, INPUT);
            

}

void loop() {

int stepCount = 0;

systemOnState= digitalRead(systemOn);

if (systemOnState==1)
{

xState=digitalRead(limitX);
yState=digitalRead(limitY);

  returnHome;
  
  startButtonState=digitalRead(startButton);
  
  if ((startButtonState==1) && (imHome==1))
 {
    
    for ( int stepYCount =0; stepYCount <33; stepYCount++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate); 
    
   for ( int stepYCount2 =0; stepYCount2 <33; stepYCount2++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate); 
    
for ( int stepYCount3 =0; stepYCount3 <33; stepYCount3++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    
    for ( int stepYCount4 =0; stepYCount4 <33; stepYCount4++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    
    for ( int stepYCount5 =0; stepYCount5 <33; stepYCount5++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate); 

    for ( int stepYCount6 =0; stepYCount6 <33; stepYCount6++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    
    for ( int stepYCount7 =0; stepYCount7 <33; stepYCount7++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount8 =0; stepYCount8 <33; stepYCount8++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount9 =0; stepYCount9 <33; stepYCount9++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount10 =0; stepYCount10 <33; stepYCount10++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount11 =0; stepYCount11 <33; stepYCount11++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    for ( int stepYCount12 =0; stepYCount12 <33; stepYCount12++)
    {
      digitalWrite(led, 1);
      myStepperY.step(-stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
myStepperX.step(stepRate);
    for ( int stepYCount13 =0; stepYCount13 <33; stepYCount13++)
    {
      digitalWrite(led, 1);
      myStepperY.step(stepRate); 
      delay(500); 
    }
    myStepperX.step(stepRate);
    
myStepperX.step(stepRate);
    
    for ( int stepXHome =0; stepXHome <13; stepXHome++)
    {
      myStepperX.step(-stepRate);
    }
  }
}
}
   if ((xState == LOW) && (yState == LOW))
  {
     imHome=1;
  }

You have not, in this function, assigned values to those variables, so it is probably not reasonable to test them.

You KNOW that you are home, because you kept stepping (although striding would be a better description) until you triggered one limit switch and then the other.

Re-read Robin2’s comment above. Move like you were in a dark room full of furniture - one step at a time, not one revolution of whatever.

 void returnHome() {
   while (digitalRead(limitX)== HIGH)
         {
            myStepperX.step(-stepRate);
         }

Consistent placement of curly braces looks a lot better. I prefer every { on a line by itself.

  returnHome;

You need () to call a function.

But, yes, that is the general idea. Put specific functionality in a function, with a reasonable name that describes what the function does, and call that function.

goHome() would be a better name, since you can go home at any time. You can only return home if you started from there.

ive amended it to the code below however the code is being stuck in the first while loop of the goHome() function regardless of input from the limit switches. Is there something in the code that would mean the limitX and limitY functions aren’t being read?

P.s the limit switches are outputting a voltage when closed and I have tested this using an LED.

Regards,

Isaac

isaacs77:
ive amended it to the code below

Code was not posted.

...R

This is a good example of the case to explain there are ‘easy’ and ‘appropriate’ ways to run a stepper.

EASY uses a driver / library that takes inputs for a direction & step count then set & forget. Worst case this will block until the motor completes the requested movement.

APPROPRIATE typically calls the step routine within your larger program to make individual steps. Then you can check limits, targets and other conditions to stop, reverse or abort the processing.
Also makes it easier to perform speed ramping and auto-homing operations.

I usually implement the latter - with a currentPosition set by sensors and motion events, and targetPosition which you adjust as needed. The repeated calls to move-stepper() checks the distance and direction, and makes the steps as needed.
You do nothing other than move-stepper() as fast as you can.

Without any real thought, I’ve used this to drive four large motors at up to 10kHz step rate.