Exit Loop with Button Press

How do I exit this loop when a button is pressed? Also is there a better way to write this code maybe with some kind of function? Thank you!

enum DIR_ENUM {
  DIR_UP = 0, // Black
  DIR_DN,     // Blue
  DIR_LT,     // Yellow
  DIR_RT,     // Green
  DIR_CNT
};

int DirectionPin[DIR_CNT] = {10, 8, 6, 4};

int Steps [100][2];


int Purple = 3;

void setup() {
  // put your setup code here, to run once:
Steps[0][0] = DIR_UP;
Steps[0][1] = 2000; //delay for 2 seconds
Steps[1][0] = DIR_DN;
Steps[1][1] = 2000;
Steps[2][0] = DIR_LT;
Steps[2][1] = 4000;
Steps[3][0] = DIR_RT;
Steps[3][1] = 4000;

}

void loop() {


  // put your main code here, to run repeatedly:
                  
                  //UP
                  
                  digitalWrite(DirectionPin[Steps[0][0]], HIGH);    // Go UP for 2 seconds
                  delay(Steps[0][1]);
                  digitalWrite(DirectionPin[Steps[0][0]], LOW);
                  
                  

               
                  
                  //DOWN

                 
                  digitalWrite(DirectionPin[Steps[1][0]], HIGH);    // Go DOWN for 2 seconds
                  delay(Steps[1][1]);
                  digitalWrite(DirectionPin[Steps[1][0]], LOW);
                  
                  
               

                  //LEFT

                  digitalWrite(DirectionPin[Steps[2][0]], HIGH);    // Go LEFT for 4 seconds
                  delay(Steps[2][1]);
                  digitalWrite(DirectionPin[Steps[2][0]], LOW);
                  
                  
              


                  //RIGHT

                  digitalWrite(DirectionPin[Steps[3][0]], HIGH);    // Go RIGHT for 4 seconds
                  delay(Steps[3][1]);
                  digitalWrite(DirectionPin[Steps[3][0]], LOW);
                  
                  
              
                  

                  
                 

                 

                  
                
}

Let's start by Auto Formatting your code in the IDE to make it more readable

enum DIR_ENUM
{
  DIR_UP = 0, // Black
  DIR_DN,     // Blue
  DIR_LT,     // Yellow
  DIR_RT,     // Green
  DIR_CNT
};

int DirectionPin[DIR_CNT] = {10, 8, 6, 4};

int Steps [100][2];


int Purple = 3;

void setup()
{
  // put your setup code here, to run once:
  Steps[0][0] = DIR_UP;
  Steps[0][1] = 2000; //delay for 2 seconds
  Steps[1][0] = DIR_DN;
  Steps[1][1] = 2000;
  Steps[2][0] = DIR_LT;
  Steps[2][1] = 4000;
  Steps[3][0] = DIR_RT;
  Steps[3][1] = 4000;
}

void loop()
{
  // put your main code here, to run repeatedly:
  //UP
  digitalWrite(DirectionPin[Steps[0][0]], HIGH);    // Go UP for 2 seconds
  delay(Steps[0][1]);
  digitalWrite(DirectionPin[Steps[0][0]], LOW);
  //DOWN
  digitalWrite(DirectionPin[Steps[1][0]], HIGH);    // Go DOWN for 2 seconds
  delay(Steps[1][1]);
  digitalWrite(DirectionPin[Steps[1][0]], LOW);
  //LEFT
  digitalWrite(DirectionPin[Steps[2][0]], HIGH);    // Go LEFT for 4 seconds
  delay(Steps[2][1]);
  digitalWrite(DirectionPin[Steps[2][0]], LOW);
  //RIGHT
  digitalWrite(DirectionPin[Steps[3][0]], HIGH);    // Go RIGHT for 4 seconds
  delay(Steps[3][1]);
  digitalWrite(DirectionPin[Steps[3][0]], LOW);
}

What exactly do you want to do when a button is pressed ? Do you want to detect when a button becomes pressed or when it is pressed ?

Your "Steps" array is 100 entries large, but you are only using 4 entries - that is a waste of memory.

Here's a method that might work:

#define POLL_BUTTON 5 //Button pin

bool poll_delay(uint32_t ms)
{
  uint32_t start = millis();
  while (millis() - start < ms)
  {
    if (digitalRead(POLL_BUTTON) == LOW)
    {
      delay(20); //Debounce
      if (digitalRead(POLL_BUTTON) == LOW) return true; //Button detected
    }
  }
  return false; //Button not detected
}

bool do_step(uint8_t index)
{
  digitalWrite(DirectionPin[Steps[index][0]], HIGH);
  bool res = poll_delay(Steps[index][1]);
  digitalWrite(DirectionPin[Steps[index][0]], LOW);
  return res;
}

void setup()
{
  pinMode(POLL_BUTTON, INPUT_PULLUP);
  ...
}

void loop()
{
  if (do_step(0)) return; //Exit loop, button press detected
  ...
}

When a button becomes pressed I want to stop the loop from running. I can then restart the program by pressing the reset button on the arduino correct?

If your code is in the main loop function there's a lot preventing you from stopping it, because of the program that's run in the background:

setup();

for (;;) {
    loop();
    if (serialEventRun) serialEventRun();
}

So it will run forever.
You can defeat this though by using a sentinel:

boolean running = TRUE;
void loop() {
    if (running) {
        //Do stuff
        ///Put all your loop code here
    }
    // otherwise this blank area runs forever
}

When the button is pressed, have the event handler set running to false.
Then your reset button will start it over.

Thank you!

I got it to work how you said. However, if I wanted to stop it randomly say in the middle of the loop code. Is there a way I can do that? As of now, I press the button and the loop finishes running and then stops. Can I get it to stop immediately somehow?

Yes, reuse the same if statement for each chunk.
Put each chunk of the loop in it's own copy of the same if (running) statement. That way it checks before it does each one.
There are better ways but that will work in about 5 minutes.

Also, consider adding an if(!running) in which you can put the Arduino to sleep. Should be easy enough to figure out.

I think you got this from here.
Happy coding!

Thank you!!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.