# New in Arduino - Using Bounce2 and an ISR to change leds light mode effects

**URL:** <https://forum.arduino.cc/t/new-in-arduino-using-bounce2-and-an-isr-to-change-leds-light-mode-effects/1159964>\
**Category:** Programming\
**Created:** [August 20, 2023, 1:18am UTC](https://forum.arduino.cc/t/new-in-arduino-using-bounce2-and-an-isr-to-change-leds-light-mode-effects/1159964 "2023-08-20T01:18:18Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![arluino](https://avatars.discourse-cdn.com/v4/letter/a/59ef9b/32.png) [@arluino](https://forum.arduino.cc/u/arluino)\
**Post date:** [August 20, 2023, 1:18am UTC](https://forum.arduino.cc/t/new-in-arduino-using-bounce2-and-an-isr-to-change-leds-light-mode-effects/1159964/1 "2023-08-20T01:18:18Z")

</div>

Im new with electronics so I started learning code with Arduino to learn, so start a code to switch between different led light modes just pressing a button so I tried the code without using an ISR and works fine, but when I want to change the light modes, need to hold the button pressed to change, so I used an ISR but doesn't work correctly because of the bounce soy I find on internet the Bounce2 library and works fine so I wanted to use it but when I use the ISR the program only execute the first instruction c = 1, and it doesn't do anything anymore if I press the button again, and I cant find how to fix it. I have quite a bit of knowledge about this and all I know comes from videos, the internet and just thinking and thinking about what's going on.

```arduino
#include <Bounce2.h>

Bounce2::Button button = Bounce2::Button();

#define BotonPin 2
int c = 0;

void setup() {

  pinMode(BotonPin, INPUT_PULLUP);
  button.attach(BotonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), suma, FALLING);
  button.interval(5);
  button.setPressedState(LOW);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  Serial.begin(9600);
  
}

void loop() {

    
 
  if (c == 0) {
    digitalWrite(8, LOW);
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    digitalWrite(11, LOW);
    digitalWrite(12, LOW);

  }
  
  else if (c == 1) {
    digitalWrite(8, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(11, HIGH);
    digitalWrite(12, HIGH);

  }

  else if (c == 2) {
    digitalWrite(8, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(11, HIGH);
    digitalWrite(12, HIGH);
    delay(400);
    digitalWrite(8, LOW);
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    digitalWrite(11, LOW);
    digitalWrite(12, LOW);
    delay(400);
  }

  else {
     c = 0;
    }

}

void suma() {
  
  button.update();
    if ( button.pressed() ) {
    c++; 
    Serial.println(c);
  }
}

```

---

<div class="post-metadata">

**Author:** ![MaximoEsfuerzo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/maximoesfuerzo/32/923798_2.png) [@MaximoEsfuerzo](https://forum.arduino.cc/u/MaximoEsfuerzo)\
**Post date:** [August 20, 2023, 2:04am UTC](https://forum.arduino.cc/t/new-in-arduino-using-bounce2-and-an-isr-to-change-leds-light-mode-effects/1159964/2 "2023-08-20T02:04:35Z")

</div>

**Warning:**...

- Don't attempt to delay, eg: `delay (100);`
- You can get the time from a call to millis, however it won't increment, so don't attempt to delay by waiting for it to increase.
- Don't do serial prints (eg. `Serial.println ("ISR entered");` )
- Don't try to do serial reading

Source:

> **[Gammon Forum : Electronics : Microprocessors : Interrupts](https://www.gammon.com.au/interrupts)**
>
> Gammon Forum : Electronics : Microprocessors : Interrupts

---

<div class="post-metadata">

**Author:** ![sterretje](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sterretje/32/391294_2.png) [@sterretje](https://forum.arduino.cc/u/sterretje)\
**Post date:** [August 20, 2023, 7:16am UTC](https://forum.arduino.cc/t/new-in-arduino-using-bounce2-and-an-isr-to-change-leds-light-mode-effects/1159964/3 "2023-08-20T07:16:17Z")

</div>

You don't need interrupts to react on a button. You will need to learn to write non-blocking code (so not using delay).

There are plenty articles on the web to achieve the above; e.g.

> [@Using millis() for timing. A beginners guide](https://forum.arduino.cc/t/using-millis-for-timing-a-beginners-guide/483573):
>
> Part 1 It is not usually long before new Arduino users discover that although the delay() function is easy to use it has side effects, the main one of which is that its stops all activity on the Arduino until the delay is finished (not quite true, I know, but that is usually how the problem presents itself). When this occurs the new user is usually directed to the BlinkWithoutDelay example sketch (BWoD) and/or the excellent thread entitled Several things at the same time. [Several things at the…](http://forum.arduino.cc/index.php?topic=223286.0)

And some more reading

> [@Explaining how to write NON-blocking all time responsive code](https://forum.arduino.cc/t/explaining-how-to-write-non-blocking-all-time-responsive-code/1126414):
>
> Hi Everybody, from time to time I enjoy writing tutorials in my kind and style. My intention is to make it easy to understand. Though I'm aware: of the fact that one way of explaining things is not the best way for everybody. that the best experts about easyness-to-understand are: beginners . I want to encourage especially beginners to ask whatever question comes to their mind. I will use these questions as suggestion to improve the tutorial to become even more easy to understand. The u…

> [@Demonstration code for several things at the same time](https://forum.arduino.cc/t/demonstration-code-for-several-things-at-the-same-time/217158):
>
> NOTE for newcomers. The demo is entirely contained in this Post and Reply #1. There is no need to read further unless you are interested. ...added 25Sep2014 There have been a few occasions recently where newcomers seemed to have difficulty applying the "blink without delay" and "state" concepts to a sketch that is intended to manage a number of concurrent actions. Its very time consuming to respond with suitable code examples - particularly as every case is a little different. I have prepared…

> **[Multi-tasking the Arduino - Part 1](https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview)**
>
> Once you have mastered the basic blinking leds, simple sensors and buzzing motors, it’s time to move on to bigger and better projects. That usually involves combining bits and pieces of simpler sketches and trying to make them work together. The...

You will also need to learn not to use magic numbers (your pin numbers); you do it correctly for the button pin but not for the LED pins.

---

<div class="post-metadata">

**Author:** ![paulpaulson](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/paulpaulson/32/363643_2.png) [@paulpaulson](https://forum.arduino.cc/u/paulpaulson)\
**Post date:** [August 20, 2023, 7:20am UTC](https://forum.arduino.cc/t/new-in-arduino-using-bounce2-and-an-isr-to-change-leds-light-mode-effects/1159964/4 "2023-08-20T07:20:40Z")

</div>

Hello [arluino](https://forum.arduino.cc/u/arluino)

Welcome to the worldbest Arduino forum ever.

In general, you should not use magic numbers. The I/O pins love to have a functional name.

Have a nice day and enjoy coding in C++.

---

<div class="post-metadata">

**Author:** ![gcjr](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gcjr/32/314015_2.png) [@gcjr](https://forum.arduino.cc/u/gcjr)\
**Post date:** [August 21, 2023, 10:53am UTC](https://forum.arduino.cc/t/new-in-arduino-using-bounce2-and-an-isr-to-change-leds-light-mode-effects/1159964/5 "2023-08-21T10:53:39Z")

</div>

> [@arluino](#):
>
> and it doesn't do anything anymore if I press the button again, and I cant find how to fix it.

looks like you're trying to use both Bounce2 and an ISR. debouncing typically just requires a ~20msec delay after recognizing a button state change.

i'm not familiar with Bonuce2, but i'll bet that the Bounce2 `update()` needs to monitor the button continuously, not just when the button state changes to LOW in the ISR triggered on the FALLING edge.

> [@arluino](#):
>
> but when I want to change the light modes, need to hold the button pressed to change

because the delays under each of your if conditions prevent checking the button state

> [@arluino](#):
>
> Im new with electronics

not about electronics, about coding

look this over

```arduino

const byte BotonPin = 2;
const byte LedPins [] = { 8, 9, 10, 11, 12 };

const int Nled = sizeof(LedPins);

byte butState;

unsigned long msecLast;
const int MaxC = 3;
bool cState;
int c;

enum { Off = HIGH, On = LOW };

// -----------------------------------------------------------------------------
void loop ()
{
    unsigned long msec = millis ();

    switch (c) {
    case 0:
        for (int n = 0; n < Nled; n++)
            digitalWrite (LedPins [n], Off);
        break;

    case 1:
        for (int n = 0; n < Nled; n++)
            digitalWrite (LedPins [n], On);
        break;

    case 2:
        if (msec - msecLast >= 400) {
            msecLast = msec;

            if (cState) {
                for (int n = 0; n < Nled; n++)
                    digitalWrite (LedPins [n], On);
            }
            else {
                for (int n = 0; n < Nled; n++)
                    digitalWrite (LedPins [n], Off);
            }
            cState = !cState;
        }
    }

    // check for button presses
    byte but = digitalRead (BotonPin);
    if (butState != but) { // state change
        butState = but;
        delay (20); // debounce

        if (LOW == but) { // pressed
            if (MaxC <= ++c)
                c = 0;
            Serial.println (c);
        }
    }
}

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

    pinMode (BotonPin, INPUT_PULLUP);
    butState = digitalRead (BotonPin);

    for (int n = 0; n < Nled; n++) {
        pinMode (LedPins [n], OUTPUT);
        digitalWrite (LedPins [n], Off);
    }
}

```

---

<div class="post-metadata">

**Author:** ![StefanL38](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/stefanl38/32/713548_2.png) [@StefanL38](https://forum.arduino.cc/u/StefanL38)\
**Post date:** [August 21, 2023, 4:29pm UTC](https://forum.arduino.cc/t/new-in-arduino-using-bounce2-and-an-isr-to-change-leds-light-mode-effects/1159964/6 "2023-08-21T16:29:36Z")

</div>

Your code can be structured into parts where each parts is one senseful **sub** -unit

You have

- switching LEDs off
- switching LEDs ON
- blink LEDs which does repeat switching LEDs off´/switching LEDs ON

You increment a value from 0 until 2 and then set it back to 0  
0,1,2,0,1,2,0,1,2,0,1,2...  
if the button is pressed. Which shall change the LED-mode  
beeing OFF or On or Blinking

So here are the parts of your code

```arduino
void switchLEDsOff() {
  for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
    digitalWrite(myLEDPin[Idx], LOW);
  }
}

```

.

```arduino
void switchLEDsOn() {
  for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
    digitalWrite(myLEDPin[Idx], HIGH);
  }
}

```

.

```arduino
void blinkLEDs() {
  // check if more time than specified in "myIntervall has passed by
  if (TimePeriodIsOver(myBlinkTimer, myIntervall) ) {
    // when REALLY more time has passed by
    // check if LEDs are OFF by reading IO-state first LED
    if (digitalRead(myLEDPin[0]) == LOW) {
      switchLEDsOn();
    }
    else {
      switchLEDsOff();
    }
  }
}

```

.

```arduino
// function that gives back values starting from Min
// incrementing to Max and if Max is reached set back to Min
// example IncrementCircular(myVar,0,2)
// results 0,1,2 0,1,2 0,1,2
byte IncrementCircular(byte actualValue, byte Min, byte Max) {
  byte Value = actualValue;

  if (Value < Min) {
    Value = Min;
  }
  Value = actualValue + 1;

  if (Value > Max) {
    Value = Min;
  }
  return Value;
}

```

.

```arduino
byte readButton(byte IO_PinNr) {
  byte firstButtonRead = digitalRead(IO_PinNr);
  delay(50);
  byte secondButtonRead = digitalRead(IO_PinNr);

  // both readings are the same the bouncing is over
  if (firstButtonRead == secondButtonRead) {
    return buttonPressed;
  }
  else {
    return buttonReleased;
  }
}

```

here is the complete code

```arduino
const byte ButtonPin = 2;

const byte myLEDPin[] = {8, 9, 10, 11, 12};
// myLEDPin[0] gives a "8"
// myLEDPin[1] gives a "9"
// myLEDPin[2] gives a "10"
// myLEDPin[3] gives a "11"
// myLEDPin[4] gives a "12"

// calculate No of bytes of complete array / number of bytes of one array-element
const byte NumberOfLEDs = sizeof(myLEDPin) / sizeof(myLEDPin[0]);
const byte buttonPressed = LOW;
const byte buttonReleased = HIGH;

byte buttonState;
byte lastButtonState;

byte mode = 0;

unsigned long myBlinkTimer;
const unsigned long myIntervall = 400;

void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  pinMode(ButtonPin, INPUT_PULLUP);

  for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
    pinMode(myLEDPin[Idx], OUTPUT);
    Serial.print("configure myLEDPin[");
    Serial.print(Idx);
    Serial.println("] as OUTPUT");

    Serial.print("in fact pinMode(");
    Serial.print(myLEDPin[Idx]);
    Serial.println(",OUTPUT);");
  }
}

void loop() {

  buttonState = readButton(ButtonPin);
  // check if there is a stateCHANGE
  if (lastButtonState != buttonState) {
    // when there is REALLY a statechange
    lastButtonState = buttonState;
    if (buttonState == buttonPressed) {
      mode = IncrementCircular(mode, 0, 2);
    }
  }

  switch (mode) {
    case 0:
      switchLEDsOff();
      break; // IMMIDIATEALY jump down to END-OF-SWITCH

    case 1:
      switchLEDsOn();
      break; // IMMIDIATEALY jump down to END-OF-SWITCH

    case 2:
      blinkLEDs();
      break; // IMMIDIATEALY jump down to END-OF-SWITCH
  } // END-OF-SWITCH
  lastButtonState = buttonState;
}

byte readButton(byte IO_PinNr) {
  byte firstButtonRead = digitalRead(IO_PinNr);
  delay(50);
  byte secondButtonRead = digitalRead(IO_PinNr);

  // both readings are the same the bouncing is over
  if (firstButtonRead == secondButtonRead) {
    return buttonPressed;
  }
  else {
    return buttonReleased;
  }
}

// function that gives back values starting from Min
// incrementing to Max and if Max is reached set back to Min
// example IncrementCircular(myVar,0,2)
// results 0,1,2 0,1,2 0,1,2
byte IncrementCircular(byte actualValue, byte Min, byte Max) {
  byte Value = actualValue;

  if (Value < Min) {
    Value = Min;
  }
  Value = actualValue + 1;

  if (Value > Max) {
    Value = Min;
  }
  return Value;
}

void switchLEDsOff() {
  for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
    digitalWrite(myLEDPin[Idx], LOW);
  }
}

void switchLEDsOn() {
  for (int Idx = 0; Idx < NumberOfLEDs; Idx++) {
    digitalWrite(myLEDPin[Idx], HIGH);
  }
}

void blinkLEDs() {
  // check if more time than specified in "myIntervall has passed by
  if (TimePeriodIsOver(myBlinkTimer, myIntervall) ) {
    // when REALLY more time has passed by
    // check if LEDs are OFF by reading IO-state first LED
    if (digitalRead(myLEDPin[0]) == LOW) {
      switchLEDsOn();
    }
    else {
      switchLEDsOff();
    }
  }
}

// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false; // actual TimePeriod is NOT yet over
}
```

best regards Stefan

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [February 17, 2024, 4:29pm UTC](https://forum.arduino.cc/t/new-in-arduino-using-bounce2-and-an-isr-to-change-leds-light-mode-effects/1159964/7 "2024-02-17T16:29:47Z")

</div>

Closed on February 17, 2024, 4:29pm UTC

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