Press button and have LED1 come on after 5s delay, and LED2 simply turn on

I want to press a button and have two LEDs turn on but one comes on after a 5s (5000 milliseconds) delay and stays on. I have to modify the examples online that has two LEDs blinking at the same time and with different intervals but I can't figure this out.

unsigned long ms_from_start=0;         //just my attempt to use millis to achieve this goal somehow
unsigned long LED1_interval=5000;   //just my attempt to use millis to achieve this goal somehow


#define button 3                      //Push button on D3
#define LED1 4                         //LED 1
#define LED2 5                        //LED 2

int LED1_state=0
int LED2_state=0
//-----------------------------------------------------------------------
int state = 0;                      //integer to hold current state
int old = 0;                        //integer to hold last state
int buttonPoll = 0;                 //integer to hold button state
//------------------------------------------------------------------------

void setup() {
  pinMode(button, INPUT); //button as input
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT);

}
//----------------------------------------------------------------------------------
void loop() {

                                  //debouncing routine to read the button
    buttonPoll = digitalRead(button);
  if(buttonPoll == 1){
    delay(50);
    buttonPoll = digitalRead(button);
    if(buttonPoll == 0){
      state = old + 1;
    }}
    else{
      delay(100);
    }
      switch(state){
        case 1:  ////LED1 turns on after 5s delay, and LED2 simply turns on
        digitalWrite(LED1, HIGH); // on after a 5s delay
        digitalWrite(LED2, HIGH); // on without delay
        old = state;
        break;

        case 2: ////LED1 simply turns on, and LED2 turns on after a 5s delay
        digitalWrite(LED1, HIGH); // on without delay
        digitalWrite(LED2, HIGH); // on after 5s delay
        old = state;
        break;

        default: //// both LED1 and LED2 simply turn on without delay
        digitalWrite(LED1, HIGH); //on without delay (achieved)
        digitalWrite(LED2, HIGH); //on without delay (achieved)
        old = 0;
        break;      

      }
    }

Is this some sort of homework or an assignment you have to do?
If so we can help but actually doing it for you would be cheating.

The answer to doing this is to use the millis timer.

When one thing happens that you want to undo later, you make a note of the value of the millis timer in a variable, and then every loop iteration check that if the current value of millis minus the time you want to do it has been reached, if so u do the operation.

Look at the blink without delay example in the IDE.

This is not homework and I'm not an engineering student. I'm trying to teach myself arduino programing this summer with a kit I bought. It's summer break now so classes are out. I'v been learning by copying and studying code from videos.

I found a video on YouTube that goes over everything I'm trying to do. Thanks for pointing me in the right direction

Hi @geissler123 ,

Welcome to the forum..

nice job on the post..

your button de-bouncing is a bit confusing..
here look this over..
i switched to input pull up, so the button just needs to be wired to ground..
changed some var names..

Serial print is your friend..

unsigned long lastPress = 0;       //just my attempt to use millis to achieve this goal somehow
unsigned long intervalDebounce = 50; //just my attempt to use millis to achieve this goal somehow
byte lastBtn = 1;//start high with input pullup

unsigned long lastWait;
unsigned long intervalWait = 5000;


#define BTN_PIN 3 //Push button on D3
#define LED1_PIN 4 //LED 1
#define LED2_PIN 5 //LED 2

int LED1_state = 0;
int LED2_state = 0;
//-----------------------------------------------------------------------
int state = 0;                      //integer to hold current state
int old = 0;                        //integer to hold last state
int buttonPoll = 0;                 //integer to hold button state
//------------------------------------------------------------------------

void setup() {
  Serial.begin(115200);
  pinMode(BTN_PIN, INPUT_PULLUP); //button as input activate internal pull up
  pinMode(LED1_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);

}
//----------------------------------------------------------------------------------
void loop() {


  unsigned long now = millis();

  if (now - lastPress >= intervalDebounce) {
    byte b = digitalRead(BTN_PIN);
    if (b != lastBtn) {
      lastBtn = b;
      lastPress = now;//start debounce
      if (b) {
        //button press and released..
        lastWait = now;
        state++;
        if (state > 2) state = 1;
        Serial.print("Button Press state: ");
        Serial.println(state);
      }
    }
  }



  switch (state) {
    case 1:  ////LED1 turns on after 5s delay, and LED2 simply turns on
      if (now - lastWait >= intervalWait) {
        digitalWrite(LED1_PIN, HIGH); // on after a 5s delay
      } else digitalWrite(LED1_PIN, LOW);
      digitalWrite(LED2_PIN, HIGH); // on without delay
      break;

    case 2: ////LED1 simply turns on, and LED2 turns on after a 5s delay
      digitalWrite(LED1_PIN, HIGH); // on without delay
      if (now - lastWait >= intervalWait) {
        digitalWrite(LED2_PIN, HIGH); // on after 5s delay
      } else digitalWrite(LED2_PIN, LOW);
      break;

    default: //// both LED1 and LED2 simply turn on without delay
      digitalWrite(LED1_PIN, HIGH); //on without delay (achieved)
      digitalWrite(LED2_PIN, HIGH); //on without delay (achieved)
      break;

  }
}

simmed up..

have fun.. ~q

Thanks for the help. I'll study this carefully this week and get back to you if I get stuck again. Thanks again

1 Like

I managed to change the code around to do everything I wanted from it and was more or less able to wrap my head around the millis-if-then, statements.

Now I'm trying to control the brightness of the LEDs with a potentiometer. I tried a few different things but my results kept getting further from my goal.

How can I control the LEDs with a potentiometer?

/*

https://forum.arduino.cc/t/press-button-and-have-led1-come-on-after-5s-delay-and-led2-simply-turn-on/1261609

*/



unsigned long lastPress = 0;      
unsigned long intervalDebounce = 50; 
byte lastBtn = 1; //start high with input pullup

unsigned long lastWait;
unsigned long intervalWait1 = 1000; // 1s delay
unsigned long intervalWait2 = 500; // .5s delay
unsigned long intervalWait3 = 750; // .75s delay


#define BTN_PIN 3 //Push button on D3
#define LED1_PIN 4 //LED 1
#define LED2_PIN 5 //LED 2

int LED1_state = 0;
int LED2_state = 0;
//-----------------------------------------------------------------------
int state = 0;                      //integer to hold current state
int old = 0;                        //integer to hold last state
int buttonPoll = 0;                 //integer to hold button state
//------------------------------------------------------------------------

void setup() {
  Serial.begin(115200);
  pinMode(BTN_PIN, INPUT_PULLUP); //button as input activate internal pull up
  pinMode(LED1_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);

}
//----------------------------------------------------------------------------------
void loop() {
//potentiometer code

//button code
  unsigned long now = millis();

  if (now - lastPress >= intervalDebounce) {
    byte b = digitalRead(BTN_PIN);
    if (b != lastBtn) {
      lastBtn = b;
      lastPress = now;//start debounce
      if (b) {
        //button press and released..
        lastWait = now;
        state++;
        if (state > 3) state = 1;
        Serial.print("Button Press state: ");
        Serial.println(state);
      }
    }
  }


//switch states
  switch (state) {
    case 1:  ////LED1 turns on after .5s delay, and LED2 simply turns on
      if (now - lastWait >= intervalWait1) {
        digitalWrite(LED1_PIN, HIGH); // on after 1s delay
      } else digitalWrite(LED1_PIN, LOW);

      if (now - lastWait >= intervalWait3) {
        digitalWrite(LED2_PIN, HIGH); // on after .75s delay
      } else digitalWrite(LED2_PIN, LOW);
      
      
      // potentiometer code
        int sensorValue = analogRead(A5);
        float voltage = sensorValue * (5.0 / 1023.0);
        int brightness = sensorValue / 4;
        analogWrite(11, brightness);
        Serial.println(voltage);
        Serial.print("Voltage: ");

      break;

    case 2: ////LED1 turns on afer .5s, and LED2 turns on after a 1s delay
      if (now - lastWait >= intervalWait3) {
        digitalWrite(LED1_PIN, HIGH); // on after .75s delay
      } else digitalWrite(LED1_PIN, LOW);

      if (now - lastWait >= intervalWait1) {
        digitalWrite(LED2_PIN, HIGH); // on after 1s delay
      } else digitalWrite(LED2_PIN, LOW);
      break;

    case 3: //// both LED1 and LED2 turn on with .5s delay
      if (now - lastWait >= intervalWait2) {
        digitalWrite(LED1_PIN, HIGH); // on after .5s delay
      } else digitalWrite(LED1_PIN, LOW);

      if (now - lastWait >= intervalWait2) {
        digitalWrite(LED2_PIN, HIGH);
      } else digitalWrite(LED2_PIN, LOW);
      break;


    default: //// both LED1 and LED2 simply turn on without delay
    
       if (now - lastWait >= intervalWait1) {
        digitalWrite(LED1_PIN, HIGH); // on after 1s delay
      } else digitalWrite(LED1_PIN, LOW);

      if (now - lastWait >= intervalWait1) {
        digitalWrite(LED2_PIN, HIGH); // on after 1s delay
      } else digitalWrite(LED2_PIN, LOW);
      break;

  }
}

Thank you for introducing me to this simulator.

wokwi sim

All of them or just that new undefined one tied to 11??
If it's all of them you have to move 4, they have to be on ~ marked pins..
4 could goto 6..
oh, that's the only time you should ever use a goto by the way.. :slight_smile:
never in code only in layman's terms..

You're welcome,love it too, a bit addictive..

I'll take a look at your sim..

~q

need to use the map function here..

        int sensorValue = analogRead(POT_PIN);
        int brightness = map(sensorValue, 0, 1023, 0, 255);
        float voltage = sensorValue * (5.0 / 1023.0);
        //int brightness = sensorValue / 4;

then just analogWrite the brightness..

~q

oops..
i just noticed this inside a case??
don't declare local vars inside of case statements, causes the switch to fall apart..

read the pot always outside of the switch and change all the digitalwrites high with analogwrites brightness and your done..

~q

like this..
updated simulation..

still have to move pin 4 and change the digital writes..

let me know if you get stuck..

good luck.. ~q

Thank you, pin4 is now on pin6.
^^that's simple

the reason i put the pot code in the first switch case was because:
the switch states broke altogether when I added the pot and tried to control them with it.

so then I added the 3rd led to see if I couldn't get it to work outside of the switch cases, in case that was the issue. a few other solutions were attempted... etc...
then I gave up and consulted the forum.

did I do something wrong with my analogWrite somehow?? did I miss defining something the void setup maybe? it seems simple, but only the outside led on pin11 is fading...

at least the switch cases arent broken anymore

 static int lastSensorVal = 0;
        static int brightness = 0;
        int sensorValue = analogRead(POT_PIN);
        if (lastSensorVal != sensorValue){
          lastSensorVal = sensorValue;
        brightness = map(sensorValue, 0, 1023, 0, 255);
        float voltage = sensorValue * (5.0 / 1023.0);
        //int brightness = sensorValue / 4;
        analogWrite(11, brightness);
        analogWrite(5, brightness);
        analogWrite(6, brightness);
        Serial.println(voltage);
        Serial.print("Voltage: ");
        }

wokwi sim

yes and it will, due to the vars declared and init'd inside the case..
you could wrap the entire case with {} but really it's better not to declare anything inside the cases, remember not all of them run each loop so sometimes the vars are there and sometime there not..
so declare outside and above the switch to be safe..

oh and really, you should replace all the digitalwrites high inside of the cases with analogwrites brightness, you don't want to do this in the sensor reading code only the cases, i'm thinking you can leave the digital writes low alone..

not the analogWrite just the math on brightness, i replaced it with the map function..
you were calculating the voltage 5 and then dividing it by 4, so always a really small value got written..
analogWrite 0 = off 255 is full bright..

have fun.. ~q

i could've figured out that analogWrite brightness myself without any help. idk how I didn't notice that.

i'll have to figure out and understand this map function business tho

thanks for all the help

1 Like

i linked you to the doc.. :slight_smile:

~q

ah, i found it
thanks again

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.