How to pause and continue a loop with a button press?

Here is my current code ( I am a beginner) -
(I want to make it switch between each mode every second, for example:
if ( lastButton == LOW && currentButton == LOW)
{
delay (1000);
ledMode++;
}

But, I want the mode to switch to ledMode=0; once I pressed the button. However, what happened was it only worked when I held it, not when I pressed it. :frowning:

const int BLED=9;              //Blue LED Anode on Pin 9
const int GLED=10;             //Green LED Anode on Pin 10
const int RLED=11;             //Red LED Anode on Pin 11
const int BUTTON=2;            //The button is connected on pin 2

boolean lastButton = LOW;      //Last Button State
boolean currentButton = LOW;   //Current Button State
int ledMode = 0;               //Cycle between LED states

void setup()
{
  pinMode (BLED, OUTPUT);      //Set Blue LED as output
  pinMode (GLED, OUTPUT);      //Set Green LED as output
  pinMode (RLED, OUTPUT);      //Set Red LED as output
  pinMode (BUTTON, INPUT);     //(**Not required**)
}

boolean debounce(boolean last)
{
  boolean current= digitalRead(BUTTON);         //Read the button state
  if (last != current);                         //If it defers
  {
    delay(5);                                   //Wait 5ms
    current = digitalRead(BUTTON);              //Read the button state again
  }
  return  current;                              //Return the current button value
}

void setMode(int mode) 
{
  //Red
  if (mode == 1)
  {
    digitalWrite(RLED, HIGH);
    digitalWrite(GLED, LOW);
    digitalWrite(BLED, LOW);
   
  }

  //Green
  else if (mode == 2)
  {
    digitalWrite (RLED,LOW);
    digitalWrite (GLED, HIGH);
    digitalWrite (BLED, LOW);
  }

  //Blue
  else if (mode == 3 )
  {
    digitalWrite (RLED, LOW);
    digitalWrite (GLED, LOW);
    digitalWrite (BLED, HIGH);
  }

  //Purple (BLUE+RED)
  else if (mode == 4)
  {
    digitalWrite (RLED, HIGH);
    digitalWrite (GLED, LOW);
    digitalWrite (BLED, HIGH);
  }

  //Teal (BLUE+GREEN
  else if (mode ==5)
  {
    digitalWrite (RLED, LOW);
    digitalWrite (GLED, HIGH);
    digitalWrite (BLED, HIGH);
  }

  //Orange (GREEN+RED)
  else if (mode ==6)
  {
    digitalWrite (RLED, HIGH);
    digitalWrite (BLED, LOW);
    digitalWrite (GLED, HIGH);
  }

  //White (ALL)
  else if (mode == 7)
  {
    digitalWrite (RLED, HIGH);
    digitalWrite (BLED, HIGH);
    digitalWrite (GLED, HIGH );
  }
  //OFF (mode =  0)

  else
  {
    digitalWrite(RLED, LOW);
    digitalWrite(GLED, LOW);
    digitalWrite(BLED, LOW);
  }
}

void loop()
  {
    currentButton = debounce (lastButton);
   
  lastButton = currentButton;

  if (ledMode == 8) ledMode=0;
  setMode(ledMode);
}

Welcome to the forum. First, please edit your post to add code tags, as described in the how to use the forum post.

You probably want to know when the button becomes pushed, rather than IF it is pushed. See the "state machine" Arduino example.

I believe I did add code tags, is that not "Using Arduino & Programming Questions?"

In the post editor, select the code and apply the "</>" button, so that your code

looks like this

1 Like

I believe it has been done...

Much better! Now, in the Arduino IDE, chose FILE > Examples > 02.Digital > StateChangeDetection

Which will show you how to change code state when a button becomes pressed. Hint: you usually no longer need to debounce.

1 Like

Your help is much appreciated, thank you!

If I have any further questions should I reply or make a new thread?

Reply. Starting new threads is frowned upon, unless it really is a new topic.

Sounds good, thanks again!

don't think you want the semi-colon

is there a need for the if statement if you just return the button state

how about, which pauses the LED processing

#undef MyHW
#ifdef MyHW
const int BLED=12;              //Blue LED Anode on Pin 9
const int GLED=10;             //Green LED Anode on Pin 10
const int RLED=11;             //Red LED Anode on Pin 11
const int BUTTON=A1;            //The button is connected on pin 2
#else
const int BLED=9;              //Blue LED Anode on Pin 9
const int GLED=10;             //Green LED Anode on Pin 10
const int RLED=11;             //Red LED Anode on Pin 11
const int BUTTON=2;            //The button is connected on pin 2
#endif

int  ledMode = 0;               //Cycle between LED states
bool butLst;

char s[80];

void setup()
{
    Serial.begin (9600);

    pinMode (BLED, OUTPUT);      //Set Blue LED as output
    pinMode (GLED, OUTPUT);      //Set Green LED as output
    pinMode (RLED, OUTPUT);      //Set Red LED as output

    pinMode (BUTTON, INPUT_PULLUP);     //(**Not required**)
    butLst = digitalRead (BUTTON);
}

boolean
butPress (void)
{
    bool but = digitalRead(BUTTON);
    if (butLst != but) {
        butLst = but;
        delay(5);           // debounce

        if (LOW == but)
            return true;
    }
    return  false;
}

void setMode(int mode)
{
    sprintf (s, "%s: %d", __func__, mode);
    Serial.println (s);

    //Red
    if (mode == 1)
    {
        digitalWrite(RLED, HIGH);
        digitalWrite(GLED, LOW);
        digitalWrite(BLED, LOW);
    }
    //Green
    else if (mode == 2)
    {
        digitalWrite (RLED,LOW);
        digitalWrite (GLED, HIGH);
        digitalWrite (BLED, LOW);
    }
    //Blue
    else if (mode == 3 )
    {
        digitalWrite (RLED, LOW);
        digitalWrite (GLED, LOW);
        digitalWrite (BLED, HIGH);
    }
    //Purple (BLUE+RED)
    else if (mode == 4)
    {
        digitalWrite (RLED, HIGH);
        digitalWrite (GLED, LOW);
        digitalWrite (BLED, HIGH);
    }
    //Teal (BLUE+GREEN
    else if (mode ==5)
    {
        digitalWrite (RLED, LOW);
        digitalWrite (GLED, HIGH);
        digitalWrite (BLED, HIGH);
    }
    //Orange (GREEN+RED)
    else if (mode ==6)
    {
        digitalWrite (RLED, HIGH);
        digitalWrite (BLED, LOW);
        digitalWrite (GLED, HIGH);
    }
    //White (ALL)
    else if (mode == 7)
    {
        digitalWrite (RLED, HIGH);
        digitalWrite (BLED, HIGH);
        digitalWrite (GLED, HIGH );
    }
    //OFF (mode =  0)
    else
    {
        digitalWrite(RLED, LOW);
        digitalWrite(GLED, LOW);
        digitalWrite(BLED, LOW);
    }

    delay (200);
}

void loop()
{
    static bool run = false;

    // toggle state when button pressed
    if (butPress ())  {
        run = !run;
    }

    // process LEDs
    if (run)  {
        setMode(ledMode);

        if (8 <= ++ledMode)
            ledMode=0;
    }
}

Hello
I have made a sketch with respect object oriented programing. Class defintions aren´t used, but I have made a RGBPattern object by using the struct and array instruction.
This approach minimize the line of codes and makes the modifications of the RPBPattern more easy, if you like.
Check the sketch and study how the commented sketch works.
Don´t hesitate to contact me in case of questions.

//BLOCK COMMENT
//https://forum.arduino.cc/t/how-to-pause-and-continue-a-loop-with-a-button-press/896241
#define ProjectName "How to pause and continue a loop with a button press?"
// CONSTANT DEFINITION
// you may need to change these constants to your hardware
const byte Button {A0};
const byte RGBled[] {2, 3, 4};
// specify names for a.m. array. 
enum {Red,Green,Blue};
// the byte array RGBled[RED] contains the address of the red pin of the RGBLed, and so on. 
// VARIABLE DECLARATION
// we build a data structure containing the different pattern for the RGBLed
struct RGBPATTERN { // declaration of used names and data types
  bool red;
  bool green;
  bool blue;
} rgbPattern[] { // specify the RGBpattern per stage
  {LOW,LOW,LOW}, // red=off, green=off, blue = off, and so on.
  {HIGH,LOW,LOW},
  {LOW,HIGH,LOW},
  {LOW,LOW,HIGH},
  {HIGH,LOW,HIGH},
  {LOW,HIGH,HIGH},
  {HIGH,HIGH,HIGH},
// the bool array contains the following information: 
// rgbPattern[0].red = LOW 
// rgbPattern[0].green = LOW 
// rgbPattern[0].blue = LOW and so on. 
};
// FUNCTIONS

void setup() {
  Serial.begin(9600);
  Serial.println(F("."));
  Serial.print(F("File   : ")), Serial.println(__FILE__);
  Serial.print(F("Date   : ")), Serial.println(__DATE__);
  Serial.print(F("Project: ")), Serial.println(ProjectName);
  pinMode (LED_BUILTIN, OUTPUT);
  pinMode(Button, INPUT_PULLUP);
  for (auto RGBledPin : RGBled) pinMode(RGBledPin, OUTPUT);
}
void loop () {
  unsigned long currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  // make an one [1] second timer to read the button state
  static unsigned long buttonMillis; 
  const unsigned long buttonDuration=1000; 
  if (currentTime-buttonMillis>=buttonDuration) {
    buttonMillis=currentTime; // reload timer. 
    if (!digitalRead(Button)) { // button pressed ? 
      static int stage; // make a local stage counter 
      digitalWrite(RGBled[Red],rgbPattern[stage].red); // write RGBLed with related pattern.
      digitalWrite(RGBled[Green],rgbPattern[stage].green); // write RGBLed with related pattern.
      digitalWrite(RGBled[Blue],rgbPattern[stage].blue); // write RGBLed with related pattern.
      stage++; 
      stage= stage % (sizeof(rgbPattern)/sizeof(RGBPATTERN)); // check limits of stage counter.
    }
  }
}

Have a nice day and enjoy coding.

1 Like

Thanks jremington, this was exactly what I needed. I'm new too, so let me know if it's bad form to just say thanks.

Thank you very much, this code works great!

But, some areas are more advanced or new to me entirely...

Could you possibly explain how/why your void loop() section works?
I was also confused about -

if (LOW == but)
            return true;
    }
    return  false;
}

Given your experience and knowledge, I would also love to know your opinion/advice on how you recommend I learn to code and improve my Arduino skills!

Thank you for the help!
This looks much more efficient, but as a beginner, it seems a little too advanced...
I don't think I am ready for data structures until I gain a solid understanding of basic functions, variables, etc.

Your help is much appreciated though; motivates me further to achieve this level of understanding. :pray:

As you have seen withhin this thread many different solutions are provided. Take some time and study and learn how each sketch works. That is the best way to have proper ideas for your next project.
Have a nice day and enjoy coding.

you want to recognize when the button is pressed (not that it is being pressed). so recognize when it changes state and to which state (HIGH/LOW) did it change to

the run state variable is toggled when the button is pressed.

understand well written code and the mistakes in other.
i thought Elements of Programming Style was very insightful. (it's a thin book)

Ah, I think I'm starting to grasp it now.
Thanks again! - I'll definitely check the book out!