user78346: So, I've just started programming Arduino (and also in general), so I'm doing basic things, like switching on and off LED's.
I've made them light in a sequence and then turning them off (in the same sequence), and now I wanted to use 2 buttons, one to make them do the same thing as before (light and turning LED's off in sequence) repeatedly, and the other to turn them off.
The problem is that curently they only light up once, and not repeatedly, I think I would've needed another loop, but i found out that you can't use 2 of them.
Can anyone help me? here's the code
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int buttonON = 7;
int buttonOFF = 8;

void setup()
{
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(buttonON, INPUT_PULLUP);
  pinMode(buttonOFF, INPUT_PULLUP);
}

void loop ()
{
  if (digitalRead(buttonON)== LOW)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
 if (digitalRead(buttonOFF)== LOW)
 {
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  digitalWrite(LED4, LOW);
  digitalWrite(LED5, LOW);
 }
}

P.S. if anyone has other general tips I would really apreciate them

user78339: You simply need to save the state of the LEDs in a new variable ...
void loop ()
{
  if (digitalRead(buttonON)== LOW)
      ledEffectON = true;

  if (digitalRead(buttonOFF)== LOW)
      ledEffectON = false;

  if(ledEffectON)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
}


user31668: You have written your question beautifully.
In your case, according to your logic, the button has to be kept pressed, so that the LEDs are lit in the order you desire. The single loop() function is part of the Arduino sketch but it is never a limitation.
One way to solve your problem is to make the LED drive logic independent of the button press state.

Once you detect the button press, store the event in one variable.
Let us call it ButtonStatus.
So, soon after the keypress is detected, update the ButtonStatus variable to TRUE.
Your LED drive logic can check this variable value to decide whether to drive the LEDs or not
Soon after you detect another press of the second button, you can update the variable value to FALSE.
Here is the Arduino simulation output for your code and the code suggested by @cat


below is after adapting the solution from cat

The simulation links are here:
Original problem
solution 1
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int buttonON = 7;
int buttonOFF = 8;
int ledEffectON;
void setup()
{
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(buttonON, INPUT_PULLUP);
  pinMode(buttonOFF, INPUT_PULLUP);
}

void loop ()
{
  if (digitalRead(buttonON)== LOW)
      ledEffectON = true;

  if (digitalRead(buttonOFF)== LOW)
      ledEffectON = false;

  if(ledEffectON)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
}

Link to docs on Pushbuttons. Wokwi Arduino simulator simulates debounce by default - just like real-world switched. Debounce is a very important technique that you should consider adding to the code. To disable the "bounce" option, use the below trick!
{ "bounce": "0" }


user68310: By using delay() it blocks the rest of the code. The programme needs to keep track of two buttons and update the lightshow at appropriate times, therefore a non-blocking style of coding is needed similar to the Blink Without Delay example where the delay() is replaced with a timer using millis() that is checked periodically. This allows other things to be checked periodically as well, e.g. the buttons.
Also the button contacts tend to bounce several times for several milliseconds when they change state sending a train of on/off pulses to the MCU, so they need to be debounced. You can find many debouncing algorithms online, but here's a simple debouncer that I put on GitHub.
void loop ()
{
  static bool doLightshow = false;

  static Debouncer buttonOn(buttonON);
  static Debouncer buttonOff(buttonOFF);

  buttonOn.Update();
  buttonOff.Update();

  if (buttonOn.Fall())
  {
    Serial.println("buttonOn falling edge.");
    doLightshow = true;
  }
  else if (buttonOff.Fall())
  {
    Serial.println("buttonOff falling edge.");
    doLightshow = false;
  }

  if (doLightshow)
  {
    // Do lightshow.
    . . .
  }
  else
  {
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
  }
}

Due to the way you've neatly written your code, you can probably pick out a pattern in the lightshow.




State
Delay time
LED pin
LED state




0
300
LED1
HIGH


1
50
LED2
HIGH


2
50
LED3
HIGH


3
50
LED4
HIGH


4
50
LED5
HIGH


5
300
LED1
LOW


6
100
LED2
LOW


7
100
LED3
LOW


8
100
LED4
LOW


9
100
LED5
LOW




This lends itself well to creating a Finite State Machine that can be stored in an array of structures:
typedef struct LightshowData
{
  unsigned int delayTime;
  byte ledPin;
  bool ledState;
};

const byte numStates = 10;

const LightshowData lightshowData[numStates] =
{
  { 300, LED1, HIGH },
  {  50, LED2, HIGH },
  {  50, LED3, HIGH },
  {  50, LED4, HIGH },
  {  50, LED5, HIGH },
  { 300, LED1, LOW },
  { 100, LED2, LOW },
  { 100, LED3, LOW },
  { 100, LED4, LOW },
  { 100, LED5, LOW }
};

The state machine can now cycle through the array in a non-blocking manner:
    // Do lightshow.
    static byte state = 0;
    unsigned long currentTimestamp = millis();
    static unsigned long previousTimestamp = currentTimestamp;

    if (currentTimestamp - previousTimestamp >= lightshowData[state].delayTime)
    {
      previousTimestamp += lightshowData[state].delayTime;
      digitalWrite(lightshowData[state].ledPin, lightshowData[state].ledState);
      state = ++state % numStates;
      Serial.print("state = ");
      Serial.println(state);
    }

You may want to reset state to 0 after a negative edge on buttonOff, otherwise the lightshow will continue where it left off after being stopped and restarted.
Here's the Wokwi simulation of the lightshow with 250 Ω protection resistors for the LEDs.

Wokwi simulates button bounce by default to more accurately model the real world, so it's advisable to have some form of button debouncing.

78346: <p><em>So, I've just started programming Arduino (and also in general), so I'm doing basic things, like switching on and off LED's.</em></p>
<p>I've made them light in a sequence and then turning them off (in the same sequence), and now I wanted to use 2 buttons, one to make them do the same thing as before (light and turning LED's off in sequence) repeatedly, and the other to turn them off.</p>
<p>The problem is that curently they only light up once, and not repeatedly, I think I would've needed another loop, but i found out that you can't use 2 of them.</p>
<p>Can anyone help me? here's the code</p>
<pre><code>int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int buttonON = 7;
int buttonOFF = 8;

void setup()
{
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(buttonON, INPUT_PULLUP);
  pinMode(buttonOFF, INPUT_PULLUP);
}

void loop ()
{
  if (digitalRead(buttonON)== LOW)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
 if (digitalRead(buttonOFF)== LOW)
 {
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  digitalWrite(LED4, LOW);
  digitalWrite(LED5, LOW);
 }
}
</code></pre>
<p>P.S. if anyone has other general tips I would really apreciate them</p>
 78339: <p>You simply need to save the state of the LEDs in a new variable ...</p>
<pre><code>void loop ()
{
  if (digitalRead(buttonON)== LOW)
      ledEffectON = true;

  if (digitalRead(buttonOFF)== LOW)
      ledEffectON = false;

  if(ledEffectON)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
}
</code></pre>
 31668: <p>You have written your question beautifully.
In your case, according to your logic, the button has to be kept pressed, so that the LEDs are lit in the order you desire. The single loop() function is part of the Arduino sketch but it is never a limitation.</p>
<p>One way to solve your problem is to make the LED drive logic independent of the button press state.</p>
<ul>
<li>Once you detect the button press, store the event in one variable.</li>
<li>Let us call it <code>ButtonStatus</code>.</li>
<li>So, soon after the keypress is detected, update the <code>ButtonStatus</code> variable to TRUE.</li>
<li>Your LED drive logic can check this variable value to decide whether to drive the LEDs or not</li>
<li>Soon after you detect another press of the second button, you can update the variable value to FALSE.<br />
Here is the Arduino simulation output for your code and the code suggested by @cat</li>
</ul>
<p><a href="https://i.stack.imgur.com/DOZms.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/DOZms.gif" alt="enter image description here" /></a></p>
<p>below is after adapting the solution from cat
<a href="https://i.stack.imgur.com/XvLyY.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/XvLyY.gif" alt="enter image description here" /></a></p>
<p>The simulation links are here:
<a href="https://wokwi.com/arduino/projects/304627808095699521" rel="nofollow noreferrer">Original problem</a>
<a href="https://wokwi.com/arduino/projects/304626706673566272" rel="nofollow noreferrer">solution 1</a></p>
<pre><code>int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int buttonON = 7;
int buttonOFF = 8;
int ledEffectON;
void setup()
{
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(buttonON, INPUT_PULLUP);
  pinMode(buttonOFF, INPUT_PULLUP);
}

void loop ()
{
  if (digitalRead(buttonON)== LOW)
      ledEffectON = true;

  if (digitalRead(buttonOFF)== LOW)
      ledEffectON = false;

  if(ledEffectON)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
}
</code></pre>
<p>Link to docs on <a href="https://docs.wokwi.com/parts/wokwi-pushbutton" rel="nofollow noreferrer">Pushbuttons</a>. Wokwi Arduino simulator simulates debounce by default - just like real-world switched. Debounce is a very important technique that you should consider adding to the code. To disable the &quot;bounce&quot; option, use the below trick!</p>
<pre><code>{ &quot;bounce&quot;: &quot;0&quot; }
</code></pre>
 68310: <p>By using <code>delay()</code> it blocks the rest of the code. The programme needs to keep track of two buttons and update the lightshow at appropriate times, therefore a non-blocking style of coding is needed similar to the <a href="https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay/" rel="nofollow noreferrer">Blink Without Delay example</a> where the <code>delay()</code> is replaced with a timer using <code>millis()</code> that is checked periodically. This allows other things to be checked periodically as well, e.g. the buttons.</p>
<p>Also the button contacts tend to bounce several times for several milliseconds when they change state sending a train of on/off pulses to the MCU, so they need to be debounced. You can find many debouncing algorithms online, but here's a <a href="https://github.com/TimMathias/Arduino-Debouncer" rel="nofollow noreferrer">simple debouncer</a> that I put on GitHub.</p>
<pre class="lang-cpp prettyprint-override"><code>void loop ()
{
  static bool doLightshow = false;

  static Debouncer buttonOn(buttonON);
  static Debouncer buttonOff(buttonOFF);

  buttonOn.Update();
  buttonOff.Update();

  if (buttonOn.Fall())
  {
    Serial.println(&quot;buttonOn falling edge.&quot;);
    doLightshow = true;
  }
  else if (buttonOff.Fall())
  {
    Serial.println(&quot;buttonOff falling edge.&quot;);
    doLightshow = false;
  }

  if (doLightshow)
  {
    // Do lightshow.
    . . .
  }
  else
  {
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
  }
}
</code></pre>
<p>Due to the way you've neatly written your code, you can probably pick out a pattern in the lightshow.</p>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th style="text-align: center;">State</th>
<th style="text-align: center;">Delay time</th>
<th style="text-align: center;">LED pin</th>
<th style="text-align: center;">LED state</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">0</td>
<td style="text-align: center;">300</td>
<td style="text-align: center;">LED1</td>
<td style="text-align: center;">HIGH</td>
</tr>
<tr>
<td style="text-align: center;">1</td>
<td style="text-align: center;">50</td>
<td style="text-align: center;">LED2</td>
<td style="text-align: center;">HIGH</td>
</tr>
<tr>
<td style="text-align: center;">2</td>
<td style="text-align: center;">50</td>
<td style="text-align: center;">LED3</td>
<td style="text-align: center;">HIGH</td>
</tr>
<tr>
<td style="text-align: center;">3</td>
<td style="text-align: center;">50</td>
<td style="text-align: center;">LED4</td>
<td style="text-align: center;">HIGH</td>
</tr>
<tr>
<td style="text-align: center;">4</td>
<td style="text-align: center;">50</td>
<td style="text-align: center;">LED5</td>
<td style="text-align: center;">HIGH</td>
</tr>
<tr>
<td style="text-align: center;">5</td>
<td style="text-align: center;">300</td>
<td style="text-align: center;">LED1</td>
<td style="text-align: center;">LOW</td>
</tr>
<tr>
<td style="text-align: center;">6</td>
<td style="text-align: center;">100</td>
<td style="text-align: center;">LED2</td>
<td style="text-align: center;">LOW</td>
</tr>
<tr>
<td style="text-align: center;">7</td>
<td style="text-align: center;">100</td>
<td style="text-align: center;">LED3</td>
<td style="text-align: center;">LOW</td>
</tr>
<tr>
<td style="text-align: center;">8</td>
<td style="text-align: center;">100</td>
<td style="text-align: center;">LED4</td>
<td style="text-align: center;">LOW</td>
</tr>
<tr>
<td style="text-align: center;">9</td>
<td style="text-align: center;">100</td>
<td style="text-align: center;">LED5</td>
<td style="text-align: center;">LOW</td>
</tr>
</tbody>
</table>
</div>
<p>This lends itself well to creating a Finite State Machine that can be stored in an array of structures:</p>
<pre class="lang-cpp prettyprint-override"><code>typedef struct LightshowData
{
  unsigned int delayTime;
  byte ledPin;
  bool ledState;
};

const byte numStates = 10;

const LightshowData lightshowData[numStates] =
{
  { 300, LED1, HIGH },
  {  50, LED2, HIGH },
  {  50, LED3, HIGH },
  {  50, LED4, HIGH },
  {  50, LED5, HIGH },
  { 300, LED1, LOW },
  { 100, LED2, LOW },
  { 100, LED3, LOW },
  { 100, LED4, LOW },
  { 100, LED5, LOW }
};
</code></pre>
<p>The state machine can now cycle through the array in a non-blocking manner:</p>
<pre class="lang-cpp prettyprint-override"><code>    // Do lightshow.
    static byte state = 0;
    unsigned long currentTimestamp = millis();
    static unsigned long previousTimestamp = currentTimestamp;

    if (currentTimestamp - previousTimestamp &gt;= lightshowData[state].delayTime)
    {
      previousTimestamp += lightshowData[state].delayTime;
      digitalWrite(lightshowData[state].ledPin, lightshowData[state].ledState);
      state = ++state % numStates;
      Serial.print(&quot;state = &quot;);
      Serial.println(state);
    }
</code></pre>
<p>You may want to reset <code>state</code> to 0 after a negative edge on <code>buttonOff</code>, otherwise the lightshow will continue where it left off after being stopped and restarted.</p>
<p>Here's the Wokwi simulation of the lightshow with 250 Ω protection resistors for the LEDs.</p>
<p><a href="https://wokwi.com/arduino/projects/304635951262466626" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/04yan.gif" title="Click to simulate lightshow in Wokwi simulator"></a></p>
<p><a href="https://docs.wokwi.com/parts/wokwi-pushbutton#bouncing" rel="nofollow noreferrer">Wokwi simulates button bounce by default</a> to more accurately model the real world, so it's advisable to have some form of button debouncing.</p>
