Blink a set number of times With Button push & Millis

Hi :slight_smile:

I am trying to blink an led on and off a set number of times (4) by declaring
the: int counter;
and using: for(counter = 0; counter <4; ++counter){}

I cant get the code to work and I am unsure of exactly where to place the: for(counter = 0; counter <4; ++counter){}
:confused: or even if I am doing the right thing :o

const byte BUTTON = 2;
const byte LED = 13;

unsigned long buttonPushedMillis;
unsigned long ledTurnedOnAt;
unsigned long turnOnDelay = 500;
unsigned long turnOffDelay = 1000;
bool ledReady = false;
bool ledState = false;

void setup() {
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
}

void loop() {

  unsigned long currentMillis = millis();
  if (digitalRead(BUTTON) == LOW) {
    delay(50);
    buttonPushedMillis = currentMillis;
    ledReady = true;
  }
  if (ledReady) {
    if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
      digitalWrite(LED, HIGH);
      ledState = true;
      ledTurnedOnAt = currentMillis;
      ledReady = false;
    }
  }
  if (ledState) {
    if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
      ledState = false;
      digitalWrite(LED, LOW);
    }

  }
}

I'm unsure what you are trying to achieve with the whole milliseconds thing.

I also can't see the for loop in your code at all.

Basically put the for loop within the if loop of the button button being pressed.

if (button pressed)

for (counter=0, counter<4,counter++){
turn on
delay
turn off
delay
}

Trying to push you towards the solution without writing it for you here in hope that'll help you more.

splext:
I'm unsure what you are trying to achieve with the whole milliseconds thing.

Obviously OP's trying to make all the blinking delay()-less which is good practice even when sometimes it's not actually necessary

splext:
Trying to push you towards the solution

.... that blinks with delay() instead of millis() and uses a for loop when loop()'s looping already? Two bad practices for the price of one.

I'd start by looking at the state change detect tutorial to see how to determine when a button becomes pressed as distinct from is pressed.

Then don't use a for loop approach: when the button becomes pressed, set a counter to 0 and a flag weAreBlinking (initialised false) to true.

Then if weAreBlinking, do the normal millis() stuff for a blink and increment the counter each time. (Slight wrinkle here is that on and off times differ: no biggy, just have a 3rd time called actualInterval or something and each time you toggle the led, set interval to the on or off time as appropriate for the next half-cycle.)

When the counter gets to the right value, make weAreBlinking false. The counter would need to be checked to be double the number of blinks, since a blink is an on and an off.

Thank you evadne & splext for you thoughts and suggestions.

I shall toddle off and review the state change detect tutorial.

This is one rabbit hole of a learning curve but fun. :slight_smile:

Some pseudo code. Should get you started as you have reviewed the blink without delay example...

now = millis();
if (button pressed)
{
  blink_count = 4;
  time_last_blink = now;
  led_on = true;
}
if (blink count > 0 && now - time_last_blink > blink_delay)
{
  if (led_on)
  {
    led_on = false;
    blink_count--;
  }
  else
  {
    led_on = true;
  }
  time_last_blink = now;
}

i believe this is closer to what you're trying to do.
shorter variables names make the code easier to read

#if 0
const byte BUTTON = 2;
#else
const byte BUTTON = A1;
#endif
const byte LED = 13;

#define ON  LOW
#define OFF HIGH

const unsigned long OnDelay = 500;
const unsigned long OffDelay = 1000;

unsigned long period = 0;
int           count;
bool          state;

void setup() {
    pinMode(BUTTON, INPUT_PULLUP);

    digitalWrite(LED, OFF);
    pinMode(LED, OUTPUT);
}

void loop() {
    static unsigned long msecLst = 0;
           unsigned long msec    = millis();
   
    if (digitalRead(BUTTON) == LOW) {
        delay(50);
        msecLst = msec;
        period  = OnDelay;
        count   = 4;
        state   = ON;
        digitalWrite (LED, state);
    }

    if (count && msec - msecLst > period) {
        msecLst = msec;

        if (ON == state)  {
            period = OffDelay;
            count--;
        }
        else
            period = OnDelay;

        state = ! state;
        digitalWrite(LED, state);
    }
}