How to make the led blink 3x when pressing button using a while loop?

uwuxxx:
Yes but that was for the leds, wasnt it? Now I have to make it for the button which seems way more difficult

It was a for-loop. Whether you are using a for-loop for leds or buttons, it is just the same.

For a while-loop to wait for the button to be pressed, you can say:

while (digitalRead(BUTTON1) == HIGH);

Notice that I put ";" at the end of the line. This means the loop is empty, there is no code inside it. But that empty loop will continue to repeat until the button is pressed, because digitalRead() will be called on each repeat.

As the others have been explaining, this style of writing code is called "blocking code" because it blocks the Arduino from doing other tasks at the same time. Until the button is pressed, the Arduino cannot escape from that while-loop. Remember, the Arduino has only one cpu core and no operating system to allow multiple tasks to run concurrently. One day, maybe quite soon, you will need to learn how to write code in a non-blocking style. But it is more difficult, so so for now, use the blocking style. It is not wasted effort because you are learning other things, like writing loops and debouncing buttons.

uwuxxx:
To be honest the most effective way of learning for me is to see an example code and then figure out myself what it all means and does and then try it myself. So I'd really appreciate it if you shared it :slight_smile:

Here it is....

Note my button wiring: my standard, and recommended by most, practice is always to wire the button from the pin to ground and look for it to go low when pressed. pinMode(pin, INPUT_PULLUP) turns on the internal resistor which keeps the pin high until button goes low on being pressed to ground. The state change detection approach continuously compares the pin's state "now" (that is, this time thru loop()) to what it was "before" (that is, last time thru) so it can see if the pin goes low, at which time the counter increments. That means you can keep the button pressed as long as you like without incrementing the counter, but the code continues and doesn't block any other stuff that may be required to run.

A nice-to-do but not compulsory of course, is to put the code that does the heavy lifting in functions, not all in loop() as one huge blob, and then call those functions from loop(): keeps things tidy. So I basically copied the code from loop() of the state change detect example into a function called readTheButtons(), made a few changes which I'm sure you will fathom out, and then call that function from loop().

Run it with the serial monitor open and watch the messages.

// https://forum.arduino.cc/index.php?topic=733370
// toggles led every 3 button presses

/*
  BASED ON State change detection (edge detection) changed for INPUT PULLUP
               (button wired from pin to ground)
  https://www.arduino.cc/en/Tutorial/StateChangeDetection
*/

// this constant won't change:
const byte  button = 4;

// variables
byte counter = 0;
boolean ledState = false;

// Variables will change:
bool buttonState;         // current state of the button
bool lastButtonState;     // previous state of the button

void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("forum 733370");
  Serial.println("Toggles led every 3 button presses");
  pinMode(button, INPUT_PULLUP); //NB... wire button from pin to ground

  //initialize button states
  buttonState = digitalRead(button);
  lastButtonState = buttonState;

  //turn bulitin led off to start
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, ledState);

  Serial.println(" ");
  Serial.println("setup() done... press the button");
  Serial.println(" ");
}

void loop()
{
  readTheButton(); //it's good practice to keep loop() nice and tidy and do the work in functions
} //loop

void readTheButton()
{
  // read the button:
  buttonState = digitalRead(button);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) // != means not equal, so it changed one way or the other
  {
    if (buttonState == LOW) //... and if it's now low, that's a press
    {
      counter++;
      Serial.print("New press ");
      Serial.println(counter);
      if (counter % 3 == 0)
      {
        ledState = !ledState; //! means not, so this just sets the ledState to the opposite of what it is
        Serial.print("  toggling to ");
        Serial.println(ledState);
        digitalWrite(LED_BUILTIN, ledState);
      }
    }// change to low
    // Delay a little bit to avoid bouncing
    delay(50); //this works for my buttons, adjust if necessary
  }//change
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;
}//readTheButton

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