Push button.... wait some seconds and do an action

Hi, I´m crazy trying to do this....

I have a project than consist in do a sequence when a push button is pushed during 30 seconds....

That I want to do is:
If push button is released nothing happens
If push button but release before 30 seconds, nothing happens
If push button 30 seconds or more start a secuence like this:

digitalWrite(out1, HIGH);
delay(14000);
digitalWrite(out1, LOW);
delay(100);
digitalWrite(out2, HIGH);
delay(23000);
digitalWrite(out2, LOW);
.......

And when finish cicle.... Arduino wait again for 30 seconds push button order....

I do the out cicle but I can do that Arduino recognize the 30 seconds order... try with millis(); , try with delays but no lock.

Thanks!!

Post your code so we might be able to point out what you might be doing wrong.

Just in case, read the stickies at the top of this forum section and look for something “how to post code”.

Ah, found it

When you post your code put it between [code] ... [/code] tags. You can do that by hitting the </> button above the posting area.

Hi, this is one of thousands test that I tried… With this last config, don´t do nothing. Thanks for your reply

   const int output1 = 2;      
   const int output2 = 3;     
   const int output3 = 4;   
   const int output4 = 5;
   const int output5 = 6;     
   const int output6 = 7;
   const int output7 = 8;
   const int output8 = 9; 
   const int buttonPin = 10;
   

int time;
int time2;
int time3;
int buttonstate1;

   void setup() {
      pinMode(output1, OUTPUT);      
      pinMode(output2, OUTPUT);    
      pinMode(output3, OUTPUT);      
      pinMode(output4, OUTPUT);       
      pinMode(output5, OUTPUT);           
      pinMode(output6, OUTPUT);
      pinMode(output7, OUTPUT);
      pinMode(output8, OUTPUT);

      pinMode(buttonPin, INPUT_PULLUP);     
   }

   void loop() {

      buttonstate1 = digitalRead(buttonPin);
      if(buttonstate1 == HIGH) {
        time=millis();
            while(buttonstate1 == HIGH) {
        time2=millis();
        
            }
            time3=time2-time;
            if(time3>30000 ){

      }
     

      
         // turn LED 1 on:    
         digitalWrite(output1, HIGH); 
         delay(10000);       
         digitalWrite(output1, LOW);
         // turn LED 2 on:    
         digitalWrite(output2, HIGH); 
         delay(20000);
         digitalWrite(output2, LOW);
         // turn LED 3 on:    
         digitalWrite(output3, HIGH); 
         delay(15000);
         digitalWrite(output3, LOW);
         // turn LED 4 on:    
         digitalWrite(output4, HIGH); 
         delay(10000);
         digitalWrite(output4, LOW);
         // turn LED 5 on:    
         digitalWrite(output5, HIGH);
         delay(12000);
         digitalWrite(output5, LOW);
         // turn LED 6 on:    
         digitalWrite(output6, HIGH);
         delay(18000);
         digitalWrite(output6, LOW);
         // turn LED 7 on:    
         digitalWrite(output7, HIGH);
         delay(9000);
         digitalWrite(output7, LOW);
         // turn LED 8 on:    
         digitalWrite(output8, HIGH);
         delay(5000);
         digitalWrite(output8, LOW);
         delay(100);


      } 
   }

I have a project than consist in do a sequence when a push button is pushed during 30 seconds....

That I want to do is:
If push button is released nothing happens
If push button but release before 30 seconds, nothing happens
If push button 30 seconds or more start a secuence like this:

I can't even begin to figure out what you want to do.

Are you wanting the user to have to press the switch for 30 seconds or more to trigger some action?

30 seconds is a really long time to have to hold a switch pressed.

At any given time, your sketch can be in one of these states:

0 - nothing happening
1 - the button is pressed, but it has not yet been pressed for 30 seconds
2 - the "sequence" is currently running

Your sketch can change from state to state as a consequence of these events

State 0: if the button is down, move to state 1

State 1: if the button is up, move to state 0. Otherwise, if 30 seconds have elapsed since entering state 1, move to state 2.

State 2: if the sequence has finished running, move back to state 0.

Yes, this is that I need.... with my code can I do this?? Or all code is wrong?? Thx!!

lots there to clean up, but these changes I made here will let you detect a button press and time how long its pressed, then executes your LED code only if the button press is greater than 30 seconds.

   const int output1 = 2;      
   const int output2 = 3;     
   const int output3 = 4;   
   const int output4 = 5;
   const int output5 = 6;     
   const int output6 = 7;
   const int output7 = 8;
   const int output8 = 9; 
   const int buttonPin = 10;

int buttonstate1;

   void setup() {
      pinMode(output1, OUTPUT);      
      pinMode(output2, OUTPUT);    
      pinMode(output3, OUTPUT);      
      pinMode(output4, OUTPUT);       
      pinMode(output5, OUTPUT);           
      pinMode(output6, OUTPUT);
      pinMode(output7, OUTPUT);
      pinMode(output8, OUTPUT);

      pinMode(buttonPin, INPUT_PULLUP);     
   }

   void loop() {

      buttonstate1 = digitalRead(buttonPin);
      
      if(buttonstate1) {
        unsigned long tic = millis();
        while(buttonstate1 == HIGH) {
          unsigned long toc  = millis() - tic;
        }
      
      if(toc > 30000){      
         // turn LED 1 on:    
         digitalWrite(output1, HIGH); 
         delay(10000);       
         digitalWrite(output1, LOW);
         // turn LED 2 on:    
         digitalWrite(output2, HIGH); 
         delay(20000);
         digitalWrite(output2, LOW);
         // turn LED 3 on:    
         digitalWrite(output3, HIGH); 
         delay(15000);
         digitalWrite(output3, LOW);
         // turn LED 4 on:    
         digitalWrite(output4, HIGH); 
         delay(10000);
         digitalWrite(output4, LOW);
         // turn LED 5 on:    
         digitalWrite(output5, HIGH);
         delay(12000);
         digitalWrite(output5, LOW);
         // turn LED 6 on:    
         digitalWrite(output6, HIGH);
         delay(18000);
         digitalWrite(output6, LOW);
         // turn LED 7 on:    
         digitalWrite(output7, HIGH);
         delay(9000);
         digitalWrite(output7, LOW);
         // turn LED 8 on:    
         digitalWrite(output8, HIGH);
         delay(5000);
         digitalWrite(output8, LOW);
         delay(100);
      } 
   }

here I went ahead and put everything into an array for you. that greatly reduces the lines of code and makes it easier to read. this still isn’t optimal as it relies on extensive use of delay. But I made a 2-dimensional array where column one contains the pin-assignments, and column 2 contains the delay values. see if it makes sense to you.

const int buttonPin = 10, rows = 8, cols = 2;

const int output[rows][cols] =
{
  {2, 10000},
  {3, 20000},
  {4, 15000},
  {5, 10000},
  {6, 12000},
  {7, 18000},
  {8, 9000},
  {9, 5000}
};

int buttonstate1;

void setup() {

  for (int i=0; i<rows; i++){
    pinMode(output[i][0], OUTPUT);
  }

  pinMode(buttonPin, INPUT_PULLUP);     
}

void loop() {

  buttonstate1 = digitalRead(buttonPin);
      
  if(buttonstate1) {
    unsigned long tic = millis();
    unsigned long toc;
    while(buttonstate1 == HIGH) {
      toc  = millis() - tic;
    }
      
    if(toc > 30000){      
      for (int i=0; i<rows; i++){
        digitalWrite(output[i][0], HIGH);
        delay(output[i][1]);
        digitalWrite(output[i][0], LOW);
      }
      delay(100);
    } 
  }
}

Hi, nothing two codes do nothing.... I tried with the "more easy" for me.... need to correct somethings.... such as "int toc;" and at end of code need a "}" more..... It´s strange....

   const int output1 = 2;      
   const int output2 = 3;     
   const int output3 = 4;   
   const int output4 = 5;
   const int output5 = 6;     
   const int output6 = 7;
   const int output7 = 8;
   const int output8 = 9; 
   const int buttonPin = 10;

int buttonstate1;
int toc;

   void setup() {
      pinMode(output1, OUTPUT);      
      pinMode(output2, OUTPUT);    
      pinMode(output3, OUTPUT);      
      pinMode(output4, OUTPUT);       
      pinMode(output5, OUTPUT);           
      pinMode(output6, OUTPUT);
      pinMode(output7, OUTPUT);
      pinMode(output8, OUTPUT);

      pinMode(buttonPin, INPUT_PULLUP);     
   }

   void loop() {

      buttonstate1 = digitalRead(buttonPin);
      
      if(buttonstate1) {
        unsigned long tic = millis();
        while(buttonstate1 == HIGH) {
          unsigned long toc  = millis() - tic;
        }
      
      if(toc > 30000){      
         // turn LED 1 on:    
         digitalWrite(output1, HIGH); 
         delay(10000);       
         digitalWrite(output1, LOW);
         // turn LED 2 on:    
         digitalWrite(output2, HIGH); 
         delay(20000);
         digitalWrite(output2, LOW);
         // turn LED 3 on:    
         digitalWrite(output3, HIGH); 
         delay(15000);
         digitalWrite(output3, LOW);
         // turn LED 4 on:    
         digitalWrite(output4, HIGH); 
         delay(10000);
         digitalWrite(output4, LOW);
         // turn LED 5 on:    
         digitalWrite(output5, HIGH);
         delay(12000);
         digitalWrite(output5, LOW);
         // turn LED 6 on:    
         digitalWrite(output6, HIGH);
         delay(18000);
         digitalWrite(output6, LOW);
         // turn LED 7 on:    
         digitalWrite(output7, HIGH);
         delay(9000);
         digitalWrite(output7, LOW);
         // turn LED 8 on:    
         digitalWrite(output8, HIGH);
         delay(5000);
         digitalWrite(output8, LOW);
         delay(100);
      } 
   }
   }

I think I see the problem. The button pin was set to INPUT_PULLUP which means it always reads HIGH. So the code was going straight into the while-loop and getting stuck there.

When you set a button pin to INPUT_PULLUP, you actually need to look for the button going LOW to indicate a press. I fixed that in the code below. It listens for the button being pulled low, then starts a timer that increments while the button is being held down. When the button is released, it checks how long it was pressed, and if longer than the given threshold, it goes into the LED portion of the code.

const int buttonPin = 10, rows = 8, cols = 2;

const int output[rows][cols] =
{
  {2, 10000},
  {3, 20000},
  {4, 15000},
  {5, 10000},
  {6, 12000},
  {7, 18000},
  {8, 9000},
  {9, 5000}
};

int buttonstate1;

void setup() {

  for (int i=0; i<rows; i++){
    pinMode(output[i][0], OUTPUT);
  }

  pinMode(buttonPin, INPUT_PULLUP);     
}

void loop() {
      
  if(digitalRead(buttonPin)==0) {
    unsigned long tic = millis();
    unsigned long toc;
    while(digitalRead(buttonPin)==0) {
      toc  = millis() - tic;
    }
      
    if(toc > 30000){      
      for (int i=0; i<rows; i++){
        digitalWrite(output[i][0], HIGH);
        delay(output[i][1]);
        digitalWrite(output[i][0], LOW);
      }
      delay(100);
    } 
  }
}

Hi, yes, this works but… that I need, is the sequence starts without release button… in your example need to release button and I need at 30 seconds of pushed button start sequence, until push button still pushed.

silly_cone:
I think I see the problem. The button pin was set to INPUT_PULLUP which means it always reads HIGH. So the code was going straight into the while-loop and getting stuck there.

When you set a button pin to INPUT_PULLUP, you actually need to look for the button going LOW to indicate a press. I fixed that in the code below. It listens for the button being pulled low, then starts a timer that increments while the button is being held down. When the button is released, it checks how long it was pressed, and if longer than the given threshold, it goes into the LED portion of the code.

const int buttonPin = 10, rows = 8, cols = 2;

const int output[rows][cols] =
{
  {2, 10000},
  {3, 20000},
  {4, 15000},
  {5, 10000},
  {6, 12000},
  {7, 18000},
  {8, 9000},
  {9, 5000}
};

int buttonstate1;

void setup() {

for (int i=0; i<rows; i++){
    pinMode(output[i][0], OUTPUT);
  }

pinMode(buttonPin, INPUT_PULLUP);   
}

void loop() {
     
  if(digitalRead(buttonPin)==0) {
    unsigned long tic = millis();
    unsigned long toc;
    while(digitalRead(buttonPin)==0) {
      toc  = millis() - tic;
    }
     
    if(toc > 30000){     
      for (int i=0; i<rows; i++){
        digitalWrite(output[i][0], HIGH);
        delay(output[i][1]);
        digitalWrite(output[i][0], LOW);
      }
      delay(100);
    }
  }
}

Okay, so modify it. I've given you more than enough here to get you going. Its time for YOU to start making improvements and trying things, then I'll be happy to give you additional feedback if its warranted.