# Exit the infinity while loop by pressing the button and continue with the switch element.

#### NexaHn

How can I solve it so that 'rainbowEffect()' function runs smoothly and when I press the button, it exits the while loop and continues in the 'switch' element.

#include <TinyDebug.h>

// Pinek definiálása
#define BUTTON_PIN PB4

#define RED_PIN PB2
#define GREEN_PIN PB1
#define BLUE_PIN PB0

int buttonState = HIGH;
int lastButtonState = HIGH;
int counter = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);

pinMode(BUTTON_PIN, INPUT_PULLUP);
digitalWrite(RED_PIN, 0);
digitalWrite(GREEN_PIN, 0);
digitalWrite(BLUE_PIN, 0);
}

void loop() {

lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) {

if (buttonState == LOW) {
counter++;

if (counter == 6) {
counter = 1;
}

switch (counter) {
case 1:
setColor(255, 0, 0); // Piros
break;
case 2:
setColor(0, 255, 0); // Zöld
break;
case 3:
setColor(0, 0, 255); // Kék
break;
case 4:
rainbowEffect();
break;
case 5:
setColor(0, 0, 0);
break;
}
}
}
}

}

// Ez a függvény beállítja az RGB LED színét a megadott értékek alapján
void setColor(int red, int green, int blue) {
analogWrite(RED_PIN, red);
analogWrite(GREEN_PIN, green);
analogWrite(BLUE_PIN, blue);
}

// Ez a függvény létrehozza a szivárvány hatását
void rainbowEffect() {
int delayTime = 10; // Az átmenetek közötti késleltetési idő (milliszekundumban)
int increment = 1; // Színváltozás sebessége

while (digitalRead(BUTTON_PIN) == HIGH) { // Folyamatosan fut a szivárvány hatás
for (int hue = 0; hue < 360; hue += increment) {
int red = int(cos(radHue) * 127 + 128);

analogWrite(RED_PIN, red);
analogWrite(GREEN_PIN, green);
analogWrite(BLUE_PIN, blue);

delay(delayTime);

if (buttonState == LOW) {
Debug.begin();
}

}
}
}

#### Infinityhost

GPT

"To ensure that the rainbowEffect() function runs smoothly and exits when you press the button, you can modify the function to periodically check the button state and exit the loop if the button is pressed. Here's how you can modify the rainbowEffect() function:

Code:
``````void rainbowEffect() {
int delayTime = 10; // Transition delay time (in milliseconds)
int increment = 1; // Color change speed

while (true) { // Continuous rainbow effect loop
for (int hue = 0; hue < 360; hue += increment) {
int red = int(cos(radHue) * 127 + 128);

analogWrite(RED_PIN, red);
analogWrite(GREEN_PIN, green);
analogWrite(BLUE_PIN, blue);

delay(delayTime);

// Check button state and exit if pressed
setColor(0, 0, 0); // Turn off LED
return; // Exit the function
}
}
}
}``````

In this modified version, I replaced the condition digitalRead(BUTTON_PIN) == HIGH with true in the while loop to ensure the rainbow effect continuously runs. Inside the loop, after setting the LED colors, it checks if the button is pressed. If the button is pressed (digitalRead(BUTTON_PIN) == LOW), it turns off the LED colors using the setColor(0, 0, 0) function and exits the rainbowEffect() function using return. This way, pressing the button will exit the rainbow effect loop and continue executing the rest of the code.

#### VBService

I do not recommend using a delay because this function stops code execution, which makes clicking the button not work smoothly (maybe in this case it does not matter much because delayTime is only set to 10 milliseconds, but IMO it's good to know). Fortunately, a more advanced solution based on the millis function comes to our aid. Thanks to it, Arduino can perform several tasks "simultaneously".

[ Why You Shouldn’t Always Use the Arduino Delay Function ]

Try e.g. like this using millis
C++:
``````void rainbowEffect() {
int delayTime = 10; // Transition delay time (in milliseconds)
int increment = 1; // Color change speed

while (true) { // Continuous rainbow effect loop
for (int hue = 0; hue < 360; hue += increment) {
int red = int(cos(radHue) * 127 + 128);

analogWrite(RED_PIN, red);
analogWrite(GREEN_PIN, green);
analogWrite(BLUE_PIN, blue);

// delay(delayTime);
// Check button state and exit if pressed
if (delayLoop(delayTime)) {
setColor(0, 0, 0); // Turn off LED
return; // Exit the function
}
}
}
}

boolean delayLoop(unsigned int delayInterval) {
unsigned long startMillis = millis();

do {
if (digitalRead(BUTTON_PIN) == LOW) return true;
} while (millis() - startMillis < delayInterval);

return false;
}``````

Last edited:

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.