Help...!!!Push button not working on delay larger than 200 millsec!!!

Hello I am new to the form. I am trying to get different led patterns when a push button is pressed.The below Sketch i used the switch case. when a button is pressed it change between different led patterns switch cases. It works for delay time lower than 200 mill sec.If my delay time is more than 200millsec ,push button is relay a hit or miss because its going in to the delay state.That means the sketch is not responsive as i thought.
This is what i am trying to accomplish ,As soon as i press the button it should change to next switch case irrespective of delay time...Can any one help me please.. any Help would be totally appreciated.Thanks

int led1 = 9;
int led2 = 8;
int buttonPin = 11;
int val = 0; 
int sequence = 1;


void setup() {                
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(buttonPin, INPUT);
    
}


void loop()                     
{

        val = digitalRead(buttonPin);
        if(val == LOW) 
        {
            if(sequence == 2) 
            {
               sequence = 1;
            } else
                {
                  sequence++; 
                }
                delay(50);  
        }
                             
         switch(sequence)
                 {
                     case 1:
                     Blink1();
                     break;
                     case 2:
                     Blink2();  
                     break;
                     
                 }
                             
                             
}

void Blink1() {
  int delayTime =200;
  digitalWrite(led1, HIGH);   
  button_delay(delayTime, buttonPin);              
  digitalWrite(led1, LOW);    
  button_delay(delayTime, buttonPin); 

  digitalWrite(led2, HIGH);   
  button_delay(delayTime, buttonPin);              
  digitalWrite(led2, LOW);    
  button_delay(delayTime, buttonPin);   
}

void Blink2() {
  int delayTime = 500;
  digitalWrite(led1, HIGH);   
  button_delay(delayTime, buttonPin);               
  digitalWrite(led1, LOW);    
  button_delay(delayTime, buttonPin);

  digitalWrite(led2, HIGH);   
  button_delay(delayTime, buttonPin);              
  digitalWrite(led2, LOW);    
  button_delay(delayTime, buttonPin);    
}


void button_delay(int msec, int btnpin)  
{
  int btnstate = 0;       
  btnstate = digitalRead(btnpin);
  if(btnstate == HIGH)
  {
    delay(msec);
  }
  
}

You didn't read the "how to use this forum" sticky did you. Read it and modify that post to use code tags.

Then look at the blink without delay in the Arduino's IDE examples.
Then read about state machines
This is one such link
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html

If you like visual explanations, this is quite good. Says much the same as Mike's myzen link above.

It's good that you came to realise the blocking nature of delay() yourself 8)

this It will do what you want... sort of.

it will flash one or the other with different intervals...

study it and see if you have questions...

untested

int led1 = 9;
int led2 = 8;
int buttonPin = 11;
int lastVal = 0; 
int state;
unsigned long startTime, dbTime;
int slow = 500;
int fast = 200;
unsigned long debounceDelay = 50UL;
//
void setup() 
{                
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}
//
void loop()                     
{
  int val = digitalRead(buttonPin);
  if (val == LOW) 
  {
    if ((lastVal == HIGH) && (millis() - dbTime > debounceDelay))
    {
      state = 1 - state; 
      startTime = millis();
      dbTime = millis();
    }
  }
  lastVal = val;
  switch(state)
  {
  case 0:
    Blink(led1, slow);
    digitalWrite(led2, LOW);
    break;
  case 1:
    Blink(led2, fast);
    digitalWrite(led1, LOW);
    break;
  }
}

void Blink( int led, unsigned long blinkSpeed) 
{
  if (millis() - startTime > blinkSpeed)
  {
    digitalWrite(led, !digitalRead(led));   
  } 
  startTime += blinkSpeed; 
}

Thank you guys for your speedy response..

BulldogLowell...Thanks for your code,but both leds are not blinking ,it stays ON,but when i press button it switches between led 1 and 2. adding to my question,i wish ti add one random blink speed and a potentiometer blink speed controls. i did that with my previous code like this but delay was a problem

potentiometer blink speed controls
pval is my potentiometer analog read.

 void Blink4(){
  int pval=analogRead(POT_PIN);
  int delayTime = 100;
  digitalWrite(led1, HIGH);  
  button_delay(pval, buttonPin);               
  digitalWrite(led1, LOW);  
  button_delay(200, buttonPin);
}

random blink speed

void Blink3(){
   randOn = random (200, 500);   
   randOff = random (200, 500);    
    digitalWrite(led1, HIGH);   
    button_delay(randOn, buttonPin);       
    digitalWrite(led1, LOW);    
    button_delay(randOff, buttonPin);   

    digitalWrite(led2, HIGH);   
    button_delay(randOn, buttonPin);       
    digitalWrite(led2, LOW);    
    button_delay(randOff, buttonPin);   

}

whoops, made a mistake here is fixed.

void Blink( int led, unsigned long blinkSpeed) 
{
  if (millis() - startTime > blinkSpeed)
  {
    digitalWrite(led, !digitalRead(led));   
    startTime += blinkSpeed; 
  } 
}

``

dimen200:
Thank you guys for your speedy response..

BulldogLowell...Thanks for your code,but both leds are not blinking ,it stays ON,but when i press button it switches between led 1 and 2. adding to my question,i wish ti add one random blink speed and a potentiometer blink speed controls. i did that with my previous code like this but delay was a problem

potentiometer blink speed controls
pval is my potentiometer analog read.

 void Blink4(){

int pval=analogRead(POT_PIN);
  int delayTime = 100;
  digitalWrite(led1, HIGH); 
  button_delay(pval, buttonPin);               
  digitalWrite(led1, LOW); 
  button_delay(200, buttonPin);
}




random blink speed



void Blink3(){
   randOn = random (200, 500);   
   randOff = random (200, 500);   
    digitalWrite(led1, HIGH);   
    button_delay(randOn, buttonPin);       
    digitalWrite(led1, LOW);   
    button_delay(randOff, buttonPin);

digitalWrite(led2, HIGH);   
    button_delay(randOn, buttonPin);       
    digitalWrite(led2, LOW);   
    button_delay(randOff, buttonPin);

}

look at this:

int potPin = A0;
int potVal = 1000;
int myRandom;
int led1 = 9;
int led2 = 8;
int buttonPin = 11;
int lastVal = 0; 
int state;
unsigned long startTime, dbTime;
int slow = 500;
int fast = 200;
unsigned long debounceDelay = 50UL;
//
void setup() 
{                
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}
//
void loop()                     
{
  potVal = analogRead(potPin);
  potVal = map(potPin, 0, 1023 , 50 , 500);
  int val = digitalRead(buttonPin);
  if (val == LOW) 
  {
    if ((lastVal == HIGH) && (millis() - dbTime > debounceDelay))
    {
      state = 1 - state; 
      myRandom = random(200,500);
      startTime = millis();
      dbTime = millis();
    }
  }
  lastVal = val;
  switch(state)
  {
  case 0:
    Blink(led1, potVal);
    digitalWrite(led2, LOW);
    break;
  case 1:
    Blink(led2, myRandom);
    digitalWrite(led1, LOW);
    break;
  }
}

void Blink( int led, unsigned long blinkSpeed) 
{
  if (millis() - startTime > blinkSpeed)
  {
    digitalWrite(led, !digitalRead(led)); 
    startTime += blinkSpeed;   
  } 
}

This demo several things at a time illustrates how to manae timing using millis() and how to organize the code into short functions to keep different parts separate for easy debugging.

...R

Thanks guys for your help.I totally appreciate it.I am trying to understand each of your code, :astonished:

@BulldogLowell
Thank you so much for your time and i appreciate your help. The code is working.How can we combine the first code and second code ,something like this..

switch

case1
             led 1 blink random
             led 2 blink random
both are independent of each other

case2
             led 1 blink pot val
             led 2 blink potval
both are independent of each other

case3
             led 1 blink random
             led 2 blink random
both are independent of each other
the randomness can be controlled by pot val?like potval+randon/potval+randoff

case4
             led 1 blink some sequence/random
             led 2 blink some sequence/random
both are independent of each other
.
.
.
.
.

caseX

             led 1 blink some sequence/random
             led 2 blink some sequence/random
both are independent of each other

the key would be to do it in the blink() function, so you would have to pass the individual startTimes for each LED you want to blink independently.

so the function may look something like this:

void Blink( int led, unsigned long ledStartTime, unsigned long blinkSpeed) //<<<<<<<<< Note function required three variables sent
{
  if (millis() - ledStartTime > blinkSpeed)
  {
    digitalWrite(led, !digitalRead(led)); 
    ledStartTime += blinkSpeed;   
  } 
}

and you are calling the functions something like this:

  switch(state)
  {
  case 0:
    Blink(led1, led1start, potVal);//<<<<<<<<<< Note that three variables are passed to the function
    digitalWrite(led2, LOW);
    break;
  case 1:
    Blink(led2, led2start, myRandom);
    digitalWrite(led1, LOW);
    break;
  }

you just need to pick point in the program to start your timers (e.g. pushbutton or time interval)

@BulldogLowell

Thank you for your replay..i am having hard time understanding what you mean by adding to the existing code :astonished: =(.If you dint mind converting your code in to simple switch case with out the functions it would be great..somting like below...Also in your code only any one of the led is working at a time,my idea is to get both working at the same time independently .Thankyou for your Help. :slight_smile:

switch

case1
             led 1 blink random
             led 2 blink random
both are independent of each other

case2
             led 1 blink pot val
             led 2 blink potval
both are independent of each other

case3
             led 1 blink random
             led 2 blink random
both are independent of each other
the randomness can be controlled by pot val?like potval+randon/potval+randoff

case4
             led 1 blink some sequence/random
             led 2 blink some sequence/random
both are independent of each other
.
.
.
.
.

caseX

             led 1 blink some sequence/random
             led 2 blink some sequence/random
both are independent of each other

what do you meant here:

case2
             led 1 blink pot val
             led 2 blink potval
both are independent of each other

as far as blinking independently as they both rely on the same value...

Sorry what is meant by thiss is something like this

case2
             led 1 blink pot val+60mill sec // or a random value like rand ON  // to completely randomize the rate
             led 2 blink pot val+10mill sec  //or a random value like rand ON  //
both blink at different rate, at the same time pot val can be used to control the blink rate.

Now in the same switch case both led s are depend up on potval,at the same time they blink at different rates compared to each other.please let me know if you have any questions.. :slight_smile:

The whole idea is When i press a button the program needs to go to one switch case after another until max switch case then repet. In each switch case i have two leds and one blink pattern. Some example blink patterns are below

So when i press button

switch case1
led1  blink random
led2 blink random

switch case2
led1  blink potval
led2 blink potval

switch case3
led1  blink fast
led2 blink slow
 
switch case4
led1  blink slow
led2 blink fast

switch case5
led1  blink potval+random
led2 blink potval+random


switch caseX=Max Switch case

The code below(Only using two switch cases here but i need to user more) will do what i want if my delays are less than 200 mill sec..

int led1 = 9;
int led2 = 8;
int buttonPin = 11;
int val = 0; 
int sequence = 1;


void setup() {                
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(buttonPin, INPUT);
    
}


void loop()                     
{

        val = digitalRead(buttonPin);
        if(val == LOW) 
        {
            if(sequence == 5) 
            {
               sequence = 1;
            } else
                {
                  sequence++; 
                }
                delay(50);  
        }
                             
         switch(sequence)
                 {
                     case 1:
                     Blink1();
                     break;
                     case 2:
                     Blink2();  
                     break;
                     
                 }
                             
                             
}

void Blink1() {
  int delayTime =200;
  digitalWrite(led1, HIGH);   
  button_delay(delayTime, buttonPin);              
  digitalWrite(led1, LOW);    
  button_delay(delayTime, buttonPin); 

  digitalWrite(led2, HIGH);   
  button_delay(delayTime, buttonPin);              
  digitalWrite(led2, LOW);    
  button_delay(delayTime, buttonPin);   
}

void Blink2() {
  int delayTime = 500;
  digitalWrite(led1, HIGH);   
  button_delay(delayTime, buttonPin);               
  digitalWrite(led1, LOW);    
  button_delay(delayTime, buttonPin);

  digitalWrite(led2, HIGH);   
  button_delay(delayTime, buttonPin);              
  digitalWrite(led2, LOW);    
  button_delay(delayTime, buttonPin);    
}


void button_delay(int msec, int btnpin)  
{
  int btnstate = 0;       
  btnstate = digitalRead(btnpin);
  if(btnstate == HIGH)
  {
    delay(msec);
  }
  
}

I appreciate anybody give me a work around with out using delays..

@BulldogLowell

Thanks for your help..please give me further help on solving this as i am trying to help someone else on their small project.
I like your ideas but its too complicated for me and i found these when i was testing your code

1.Only works One led at a time, how can i get both working on the same switch case?
2.Is there an option to go to at least 8 switch cases? That is 8 led patterns ?

I like your ideas but its too complicated for me

Then perhaps the whole project is too complicated for you until you get more programming skills.

It seems to me that you have not worked out exactly how you want it to behave, or if you have, you are having difficult communicating that.

I appreciate anybody give me a work around with out using delays..

You've got that backwards: without delay is the right way, delay is the workaround.