Problem with push button and led momentary ON/off function

Greetings everyone !

i have this sketch that demonstrates a push button blinking an led . these are my features and all of them were successfully implemented through the sketch. i use arduino uno

-if i push the button, (and then release it immediately), the led will light up for 3seconds and then off .
-as long as i am pushing the button within the 3s lighting operation of the led, the timer is reset and the led will not turn off.
-if i hold down the button, and not releasing it, the led will still lit up for 3s the moment i start holding it and be off after 3s, but will not be re-triggered because the button is still held

EXCEPT for this one:

  • i can't add another code that will do the same thing as i release the button . code that will turn on the led again for 3 seconds and then off , the moment that i release the button press.

this code that must be added will be good if i press and hold the button until the led finishes lighting up for 3seconds .
but if i press the button and then release it immediately before the lighting process ends, the process will surely fail, so i think that there must be a delay before arduino reads the button release, so that the lighting process will be finished properly before doing another one when i release it .

i'm really poor at mixing codes due to lack of experience with arduino ,,, :smiley:
your help will be appreciated well , thanks !

const int ledPin =  13;      // the number of the LED pin
unsigned long startTime;        // will store last time LED was updated
const int DisplayButton = 2; 
int lastButtonState = 0; 
int ledState;
unsigned long interval = 3000UL;           // interval at which to blink (milliseconds)

void setup() 
{
  pinMode(ledPin, OUTPUT);  
  pinMode(DisplayButton, INPUT);  
}

void loop()
{ 
  int buttonState = digitalRead(DisplayButton);
  if (buttonState == HIGH) 
  {
    if (lastButtonState == LOW)
    {
      ledState = 1;
      startTime = millis();
    }
  }
  lastButtonState = buttonState;
  if (ledState)
  {
    if (millis() - startTime <= interval)
    {
      digitalWrite(ledPin, HIGH);
    }
    else
    {
      digitalWrite(ledPin, LOW);
      ledState = 0;
    }
  }  
}

did you try to reset the timer on a simple state change?

also, you don't need to use ledState with your timer set up like this:

const int ledPin =  13;      // the number of the LED pin
unsigned long startTime;        // will store last time LED was updated
const int DisplayButton = 2; 
int lastButtonState = 0; 
int ledState;
unsigned long interval = 3000UL;           // interval at which to blink (milliseconds)

void setup() 
{
  pinMode(ledPin, OUTPUT);  
  pinMode(DisplayButton, INPUT);  
}

void loop()
{ 
  int buttonState = digitalRead(DisplayButton);
  if (buttonState != lastButtonState) // on any state change...
  {
    startTime = millis();// .... reset the timer
  }
  lastButtonState = buttonState;
  
  if (millis() - startTime <= interval)
  {
    digitalWrite(ledPin, HIGH);
  }
  else
  {
    digitalWrite(ledPin, LOW);
  } 
}

the sketch you sent me works fine , thanks !

however , can i add up another code that will operate 2 more lights ,however, the operation will not be the same as i mentioned from the start, it will not be momentarily on and then off,

as i start holding the button, the 1st led (the one that we assigned a momentary on/off operation) will operate , and then the two additional lights will be ON one by one as long as i am holding the button, and when i release the button, the 1st led will (momentary again) operate, and then the two additional lamps will be OFF one by one ,,,

i did the sketch below, using delay, to operate the two additional lamps one by one, but the delay time is being added to the 3s interval that we set for the 1st led, how can the 3s for the 1st led stay not affected and independent from the delay that i used for the 2 additional lamps ?

const int ledPin1 = 13;      // the number of the LED pin
const int ledPin2 = 12;
const int ledPin3 = 11;
const int DisplayButton = 2;
unsigned long startTime;        // will store last time LED was updated

int lastButtonState = 0; 
unsigned long interval = 3000UL;           // interval at which to blink (milliseconds)
int ledState;

void setup() 
{
  pinMode(ledPin1, OUTPUT);  
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(DisplayButton, INPUT);  
}

void loop() {
  set1();
  set2();
}

void set1()
    { 
    int buttonState = digitalRead(DisplayButton);
    if (buttonState != lastButtonState) // on any state change...
    {
      startTime = millis();// .... reset the timer
    }
    lastButtonState = buttonState;
  
    if (millis() - startTime <= interval)
    {
      digitalWrite(ledPin1, HIGH);
    }
    else
    {
    digitalWrite(ledPin1, LOW);
    } 
    }
    
    
void set2()
  {
      int buttonState = digitalRead(DisplayButton);
      
      if (buttonState == HIGH){
        digitalWrite(ledPin2, HIGH);
        delay(500);
        digitalWrite(ledPin3, HIGH);
        delay(500);
      }
      else
      {
        digitalWrite(ledPin2, LOW);
        delay(500);
        digitalWrite(ledPin3, LOW);
        delay(500);
      }
    }
i did the sketch below, using delay,

and you were doing so well... :blush:

you want to use no delays that will block the progress of the code...

think like this:

if buttonState changes
start your first led and start a timer (you did that) and then add to your timer a couple of other events.....

something like this but I cannot test it:

{
    if (mconst int ledPin1 = 13;      // the number of the LED pin
const int ledPin2 = 12;
const int ledPin3 = 11;
const int DisplayButton = 2;
unsigned long startTime;        // will store last time LED was updated

int lastButtonState = 0; 
unsigned long interval = 3000UL;           // interval at which to blink (milliseconds)
int ledState;

void setup() 
{
  pinMode(ledPin1, OUTPUT);  
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(DisplayButton, INPUT);  
}

void loop() 
{
  int buttonState = digitalRead(DisplayButton);
  if (buttonState != lastButtonState) // on any state change...
  {
    startTime = millis();// .... reset the timer
    ledState = !ledState;
  }
  lastButtonState = buttonState;
  if (ledState)
  {
    if (millis() - startTime <= interval)
    {
      digitalWrite(ledPin1, HIGH);
    }
    else if (millis() - startTime <= interval * 2)
    {
      digitalWrite(ledPin2, HIGH);
    }
    else if (millis() - startTime <= interval * 3)
    {
      digitalWrite(ledPin3, HIGH);
    }
    else 
    {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, LOW);
    } 
  }
  else 
  {
    if (millis() - startTime <= interval)
    {
      digitalWrite(ledPin1, LOW);
    }
    else if (millis() - startTime <= interval * 2)
    {
      digitalWrite(ledPin2, LOW);
    }
    else if (millis() - startTime <= interval * 3)
    {
      digitalWrite(ledPin3, LOW);
    }
  }
}

Hi , this is what the sketch did:

  1. turn on led1
  2. interval
  3. turn on led2
  4. interval
  5. turn on led3
  6. interval
  7. turn off led1 ,led2, and led3

whereas it must be like this :
at button hold:

  1. turn on led1
  2. 3s interval, then turn off led1
  3. after 3s interval for led1( or led1 being OFF), turn on led2
  4. interval 3s
  5. turn on led3
    *led2 and led3 mus be hold to ON state as long as the button is being held

at button release:

  1. turn on led1
  2. 3s interval, then turn off led1
  3. after 3s interval for led1( or led1 being OFF), turn off led2
  4. interval 3s
  5. turn off led3
    *led2 and led3 must stay OFF as long as the button is not pushed ,

thanks for the ideas , i think i'm going to try also starting a for loop after the led1 finishes its operation

yes... just to give you ideas