user-1: Table of contents:

What I want to achieve
Problem I'm facing
What I've tried
Possible Hypotheses

What I want to achieve
Hi guys, I’m working on a DIY LED Light project to install on my bicycle, where I want to re-create how the actual LED bicycle lights work:
[Stage 1] Press button once: LED lights up forever until button is pressed again
[Stage 2] Press button twice: LED blinks forever until button is pressed again
[Stage 3] Press button thrice: LED turns off (goes back to original state)
Problem I’m facing
After a bit of research, I know how to work out the code for [Stage 1] (by tracking the current and previous button states.) But I’m unable to make [Stage 2] happen.
What I’ve tried
I’ve tried to instead of tracking the previous and current button states, why not use a counter, i.e:
Counter = 0 (initial)
When button is pressed once,
Counter = 1 (LED lights up forever until button is pressed again)
When button is pressed one more time,
Counter = 2 (LED blinks forever until button is pressed again)
When button is pressed one more time,
Counter = 3 (LED switches off, goes back to original LOW state)
Counter resets to = 0 again
This is my code below:
const int ledPin = 8;
const int buttonPin = 7;

int buttonState;
int ledState;
int counter = 0;
int newcounter;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  digitalWrite(ledPin, HIGH);
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    newcounter = counter + 1;
    delay(500);
    if (newcounter != counter) {
      switch (newcounter) {
        case 1: 
            digitalWrite(ledPin, LOW);
            counter = newcounter;
            break;
        case 2: 
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            break;
        case 3: 
            digitalWrite(ledPin, HIGH);
            counter = 0;
            break;
        default: 
            digitalWrite(ledPin, HIGH);
            counter = 0;
            break;       
      }
    }
  }   
}

Possible Hypotheses (Please criticise/correct me if I’m wrong)
A) There is a problem with my code (my programming logic etc)
B) Maybe its not a code/program problem? It could be due to the design of the electric circuit (because I’ve seen videos on YouTube where LEDs can be made to blink using capacitors and transistors. But how does the sequence from Stages 1 to 3 happen in a bicycle LED light? (https://www.youtube.com/watch?v=cXCExzIBNsA)
I’ll be eternally grateful if anyone will be able to help! Thank you!!

user83070: you are not stating what results you are getting.
I do see you are not presetting your state variables.
This is always good practice to avoid random startup conditions.
you have logic that will only run when the button is held
your if (newcounter != counter) and switch statement only run while the button is pressed.
move them outside of the button state check and look to change things ONLY if the button changed.
try this;
it will only act on button change not continiously so changes only happen on each press
i will leave you to play with the switch conditions
const int ledPin = 8;
const int buttonPin = 7;

int buttonState, chngButtonState = 0;
int ledState;
int counter = 0;
int newcounter;

void setup() {
  chngButtonState = buttonState; 
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  digitalWrite(ledPin, HIGH);
}

void loop() {
      buttonState = digitalRead(buttonPin);
      if (buttonState == HIGH && !buttonState == chngButtonState ) {     // read once only if changed button state changed not on every loop
        newcounter = counter + 1;
        delay(500);
        chngButtonState = buttonState;      // mae them equal again
        }                // NOTE I moved 1 of the } from the bottom
        
        if (newcounter != counter) {
          switch (newcounter) {
            case 1: 
                digitalWrite(ledPin, LOW);
                counter = newcounter;
                break;
            case 2: 
                digitalWrite(ledPin, HIGH);
                delay(500);
                digitalWrite(ledPin, LOW);
                delay(500);
                digitalWrite(ledPin, HIGH);
                delay(500);
                digitalWrite(ledPin, LOW);
                delay(500);
                digitalWrite(ledPin, HIGH);
                delay(500);
                digitalWrite(ledPin, LOW);
                delay(500);
                digitalWrite(ledPin, HIGH);
                delay(500);
                break;
            case 3: 
                digitalWrite(ledPin, HIGH);
                counter = 0;
                break;
            default: 
                digitalWrite(ledPin, HIGH);
                counter = 0;
                break;       
          }
        }
    }

now just play with the Switch statements to get your results.
pinMode(buttonPin, INPUT);
your button wiring is not clear.
Likely, you have the button connected to VCC and pin 7.  You still should have a pulldown resistor from the arduino pin7 to GND to get reliable states.
However; if the button is from a pin7 to GND and no pullup the state will also not change.
If so;
change pinMode(buttonPin, INPUT); to pinMode(buttonPin, INPUT_PULLUP);   and no external pullup resistor is needed.

-1: <p>Table of contents:</p>
<ol>
<li>What I want to achieve</li>
<li>Problem I'm facing</li>
<li>What I've tried</li>
<li>Possible Hypotheses</li>
</ol>
<p>What I want to achieve</p>
<p>Hi guys, I’m working on a DIY LED Light project to install on my bicycle, where I want to re-create how the actual LED bicycle lights work:</p>
<p>[Stage 1] Press button once: LED lights up forever until button is pressed again
[Stage 2] Press button twice: LED blinks forever until button is pressed again
[Stage 3] Press button thrice: LED turns off (goes back to original state)</p>
<p>Problem I’m facing</p>
<p>After a bit of research, I know how to work out the code for [Stage 1] (by tracking the current and previous button states.) But I’m unable to make [Stage 2] happen.</p>
<p>What I’ve tried</p>
<p>I’ve tried to instead of tracking the previous and current button states, why not use a counter, i.e:</p>
<p>Counter = 0 (initial)
When button is pressed once,
Counter = 1 (LED lights up forever until button is pressed again)</p>
<p>When button is pressed one more time,
Counter = 2 (LED blinks forever until button is pressed again)</p>
<p>When button is pressed one more time,
Counter = 3 (LED switches off, goes back to original LOW state)
Counter resets to = 0 again</p>
<p>This is my code below:</p>
<pre><code>const int ledPin = 8;
const int buttonPin = 7;

int buttonState;
int ledState;
int counter = 0;
int newcounter;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  digitalWrite(ledPin, HIGH);
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    newcounter = counter + 1;
    delay(500);
    if (newcounter != counter) {
      switch (newcounter) {
        case 1: 
            digitalWrite(ledPin, LOW);
            counter = newcounter;
            break;
        case 2: 
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            break;
        case 3: 
            digitalWrite(ledPin, HIGH);
            counter = 0;
            break;
        default: 
            digitalWrite(ledPin, HIGH);
            counter = 0;
            break;       
      }
    }
  }   
}
</code></pre>
<p>Possible Hypotheses (Please criticise/correct me if I’m wrong)</p>
<p>A) There is a problem with my code (my programming logic etc)</p>
<p>B) Maybe its not a code/program problem? It could be due to the design of the electric circuit (because I’ve seen videos on YouTube where LEDs can be made to blink using capacitors and transistors. But how does the sequence from Stages 1 to 3 happen in a bicycle LED light? (<a href="https://www.youtube.com/watch?v=cXCExzIBNsA" rel="nofollow noreferrer">https://www.youtube.com/watch?v=cXCExzIBNsA</a>)</p>
<p>I’ll be eternally grateful if anyone will be able to help! Thank you!!</p>
 83070: <p>you are not stating what results you are getting.</p>
<p>I do see you are not presetting your state variables.<br />
This is always good practice to avoid random startup conditions.</p>
<p>you have logic that will only run when the button is held
your if (newcounter != counter) and switch statement only run while the button is pressed.
move them outside of the button state check and look to change things ONLY if the button changed.</p>
<p>try this;
it will only act on button change not continiously so changes only happen on each press</p>
<p>i will leave you to play with the switch conditions</p>
<pre><code>const int ledPin = 8;
const int buttonPin = 7;

int buttonState, chngButtonState = 0;
int ledState;
int counter = 0;
int newcounter;

void setup() {
  chngButtonState = buttonState; 
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  digitalWrite(ledPin, HIGH);
}

void loop() {
      buttonState = digitalRead(buttonPin);
      if (buttonState == HIGH &amp;&amp; !buttonState == chngButtonState ) {     // read once only if changed button state changed not on every loop
        newcounter = counter + 1;
        delay(500);
        chngButtonState = buttonState;      // mae them equal again
        }                // NOTE I moved 1 of the } from the bottom
        
        if (newcounter != counter) {
          switch (newcounter) {
            case 1: 
                digitalWrite(ledPin, LOW);
                counter = newcounter;
                break;
            case 2: 
                digitalWrite(ledPin, HIGH);
                delay(500);
                digitalWrite(ledPin, LOW);
                delay(500);
                digitalWrite(ledPin, HIGH);
                delay(500);
                digitalWrite(ledPin, LOW);
                delay(500);
                digitalWrite(ledPin, HIGH);
                delay(500);
                digitalWrite(ledPin, LOW);
                delay(500);
                digitalWrite(ledPin, HIGH);
                delay(500);
                break;
            case 3: 
                digitalWrite(ledPin, HIGH);
                counter = 0;
                break;
            default: 
                digitalWrite(ledPin, HIGH);
                counter = 0;
                break;       
          }
        }
    }
</code></pre>
<p>now just play with the Switch statements to get your results.</p>
<p><strong>pinMode(buttonPin, INPUT);</strong></p>
<p>your button wiring is not clear.</p>
<p>Likely, you have the button connected to VCC and pin 7.  You still should have a pulldown resistor from the arduino pin7 to GND to get reliable states.</p>
<p>However; if the button is from a pin7 to GND and no pullup the state will also not change.</p>
<p>If so;
change <strong>pinMode(buttonPin, INPUT);</strong> to <strong>pinMode(buttonPin, INPUT_PULLUP);</strong>   and no external pullup resistor is needed.</p>
