LED does not blink instantly [ solved ]

I am trying to get a blink for 5 seconds starting as soon as the button is pressed.

what I get is that blinking starts as soon as the button is released.

// variables
long  interval = 50;  // 50 ms as the blink rate
unsigned long  thenLED = 0;
unsigned long  then = 0;

int buttonState = 0;
int lastSwitch = 0;
int ledState = 0;


// physical pins
const int buttonPin = 7;
const int ledPin = 13;
const int ledPin2 = 8;


// = = = = = = =

void setup(){

  pinMode(buttonPin, INPUT);   
  pinMode(ledPin, OUTPUT);  
  pinMode(ledPin2, OUTPUT); 

} 
void loop(){

  buttonState = digitalRead(buttonPin);
  digitalWrite(ledPin2,buttonState);

//  to resolve , these two had to be changed - shown wrong here.
  if(buttonState == LOW ){
    if(lastSwitch == HIGH){  //tests if switch is pressed for the first time
      then = millis();
    }  
  }

  lastSwitch =buttonState; //  this is not inside of an IF statement, but is loaded on every scan.

  if(millis() - then < 5000 ){   // tests if less than 5 seconds
    if(millis() - thenLED > interval) {       // check if interval has been exceeded
      thenLED = millis();                        // save the last time you blinked the LED , resets to 0
      ledState = !ledState ;   // toggle LED state 
    }
  }
  else {
    digitalWrite(ledState,LOW);  // after 5 seconds the LED will be turned off
  }

  digitalWrite(ledPin,ledState);
}

How is the button wired? Is it active HIGH or active LOW?

5v - switch - resistor - led - gnd // button is after switch
this is not the LED that is blinking, just one to see that the switch is pressed.

If the switch is connecting the pin to 5V when pressed, then you’ve got the logic backwards.

if(buttonState == LOW ){
    if(lastSwitch == HIGH){  //tests if switch is pressed for the first time
      then = millis();
    }  
  }

Assuming the switch is active HIGH (connects pin to 5V when pressed) then this says when the switch is not pressed now but was pressed last time through.

not sure which is faster, how quickly the LED starts blinking after the button is pressed, or how fast you spotted and solved my problem !

Thanks !

part two:

it seems that the else is never reached.

I can put a separate IF statement to turn the light off after 5 seconds, but I would think that the else would do that.

I did change the logic, but no joy.

if(millis() - then < 5000 ){   // tests if less than 5 seconds
    if(millis() - thenLED > interval) {       // check if interval has been exceeded
      thenLED = millis();                        // save the last time you blinked the LED , resets to 0
      ledState = !ledState ;   // toggle LED state 
    }
  }
  else {
    digitalWrite(ledState,LOW);  // after 5 seconds the LED will be turned off
  }

  digitalWrite(ledPin,ledState);
}

tried :
digitalWrite(ledState,HIGH); // after 5 seconds the LED will be turned off

just to check the way I had it connected.

Well, you’ve got that other digitalWrite(ledPin, ledState) coming right behind that else. Are you sure it’s not just turning it right back on?

Instead of writing the pin LOW in the else block, set ledState to LOW and see if that helps.

if(millis() - then < 5000 ){   // tests if less than 5 seconds
    if(millis() - thenLED > interval) {       // check if interval has been exceeded
      thenLED = millis();                        // save the last time you blinked the LED , resets to 0
      ledState = !ledState ;   // toggle LED state 
    }
  }
  else {
    ledState = LOW;
  }

  digitalWrite(ledPin,ledState);
}

BTW, the line:

    digitalWrite(ledState,LOW);  // after 5 seconds the LED will be turned off

Will never do anything like what you want. Maybe you are thinking in:

    digitalWrite(ledPin,LOW);  // after 5 seconds the LED will be turned off

Good catch.

to me, it seems that I never get to the else ??
this line

if(millis() - then < 5000 ){   // tests if less than 5 seconds
   anything can be here )
else {
  digitalWrite (ledPin,LOW);      // wrong - was overwritten by the next line
  digitalWrite(ledState,LOW);     // wrong, you do not digitalWrite a state......
  ledState=LOW;    // this is correct
}
digitalWrite(ledPin,ledState);

that if the IF() failed the test, then nothing from the IF() would be executed.
but then the else would be executed ?

that the else would set the ledState and then the digitalWrite would set the LED.

gosh, I guess I was so focused on the first problem, I missed that I had two digitalWrite.
sorry it took a hammer to pound it into my head.

// variables
long  interval = 50;  // 50 ms as the blink rate
unsigned long  thenLED = 0;
unsigned long  then = 0;

int buttonState = 0;
int lastSwitch = 0;
int ledState = 0;


// physical pins
const int buttonPin = 7;
const int ledPin = 13;
const int ledPin2 = 8;


// = = = = = = =

void setup(){

  pinMode(buttonPin, INPUT);   
  pinMode(ledPin, OUTPUT);  
  pinMode(ledPin2, OUTPUT); 

} 
void loop(){

  buttonState = digitalRead(buttonPin);
  digitalWrite(ledPin2,buttonState);

  if(buttonState == HIGH ){
    if(lastSwitch == LOW){  //tests if switch is pressed for the first time
      then = millis();
    }  
  }

  lastSwitch =buttonState; //  this is not inside of an IF statement, but is loaded on every scan.

  if(millis() - then < 5000 ){   // tests if less than 5 seconds
    if(millis() - thenLED > interval) {       // check if interval has been exceeded
      thenLED = millis();                        // save the last time you blinked the LED , resets to 0
      ledState = !ledState ;   // toggle LED state 
    }
  }
  else {
    ledState=LOW;  // after 5 seconds the LED will be turned off
  }

  digitalWrite(ledPin,ledState);
}

follow-up

when I press the button, the blink starts immediately (first problem solved)
after 5 seconds, it stops blinking.

when I press and hold the button. 5 seconds after the press, it stops blinking. ( as desired)

in either case, press and release, or press and hold, after 5 seconds, the blink stops and the LED is turned off (second problem solved)

dave-in-nj:
5v - switch - resistor - led - gnd // button is after switch

Note that the required voltage levels on a digital input are 0.3 Vcc to 0.7 Vcc (1.5 to 3.5V).

dlloyd:
Note that the required voltage levels on a digital input are 0.3 Vcc to 0.7 Vcc (1.5 to 3.5V).

I had been plagued by that earlier.
I am using the diagram on the left. seems to work most of the time.

earlier, I was thinking I was not getting a signal, so added the LED.
now I will add the pull-down and eliminate that pot-hole.