controlling leds with single pushbutton

I have written a program which is not working as i wanted it. I wanted it to run in this way
If button pin is press for the first time it would go on for 5 secs.
If the button pin is pressed twice led must go on for 10 secs.
But the program below runs the led1 for 5 secs first even if we press the push button twice.
Please help.

const int buttonPin = 0;
const int buttonPin1= 1;
const int led1 = 14;
const int led2 = 15;
int j=0;
int buttonState;
int lastButtonState = LOW;
long lastDebounceTime = 0;
long debounceDelay = 50;

void setup() {
pinMode(buttonPin, INPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
j=0;

}

void loop() {
int reading = digitalRead(buttonPin );

if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if(reading!=buttonState){
buttonState = reading;
if(buttonState==HIGH){
if (j==0)
{
j++;
}
else if (j==1)
{
j++;
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
delay(5000);
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);

}
else if (j==2)
{
j++;

delay(10000);
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
}
}
}
}
lastButtonState = reading;
}

Hello,

Your code cannot react to events such as button presses, when it is being delayed. I mean, the delay function does exactly what it says, it will delay the rest of the code, and meanwhile, it cannot do anything else.

I suppose this is your problem, or at least one of your problems. Look at the Blink Without Delay example, it should help :wink:

As well as the need to get rid of the delay() function (see the demo several things at a time which illustrates how to manage time with millis() ) your description is unclear.

Do you mean that the first press should cause the led to go on for 5 secs and a later press would cause it to go on for 10 secs?
OR, do you mean that a double press will make it go on for 10 secs without ever going on for 5 secs?
OR, do you mean that a second press within the 5 sec period would extend the period to 10 secs?

If you want to check for a double press the code will need to be a little more complex. It will need to wait long enough (in case there is a second press) before reacting to the first press.

...R

Shreyas_Bhavsar:
I have written a program which is not working as i wanted it. I wanted it to run in this way
If button pin is press for the first time it would go on for 5 secs.
If the button pin is pressed twice led must go on for 10 secs.
But the program below runs the led1 for 5 secs first even if we press the push button twice.
Please help.

As pointed out, a millis() timer will work for your sketch. I changed some variables, so review that before you test.

try something like this:

const int buttonPin = 2;  // you should not use 0 or 1, generally.  they are used for IO
const int led1 = 13;
int lastButtonState;
unsigned long lastDebounceTime  = 0; 
int pressed = 0;

void setup() 
{
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  digitalWrite(led1,HIGH);
  delay(1000);
}

void loop() 
{
  int reading  = digitalRead(buttonPin);
  if (reading == HIGH && reading != lastButtonState && (millis() - lastDebounceTime > 50)) // detect one side of the button press, and debounce it. 
  {
    if (pressed == 0) 
    {
      lastDebounceTime = millis();  // start the millis() timer
    }
    Serial.println("pressed");
    pressed++;  //
    if (pressed > 2) pressed = 2; // you could etend ths for more presses
  } 
  lastButtonState = reading;
  //
  if (pressed)
  {
    illuminate();
  }
}
//
void illuminate()
{
  unsigned long duration = pressed * 5000UL; // counts longer fro two presses
  if (millis() - lastDebounceTime < duration)
  {
    digitalWrite(led1, HIGH);
  }
  else
  {
    digitalWrite(led1, LOW);
    pressed = 0;
  }
}

Thnax for all your replies.
If we do doublepress it must delay for 10 secs.
Please suggest me .

Shreyas_Bhavsar:
Thnax for all your replies.
If we do doublepress it must delay for 10 secs.
Please suggest me .

Did you try above code?

Shreyas_Bhavsar:
Please suggest me .

I thought I did that in Reply #2 ?

...R

Thanx for all your suggestions
I tried this but didnt work please help.
const int buttonPin = 0;
const int buttonPin1= 1;
const int led1 = 9;
const int led2 = 10;
int j=0;
int buttonState;
int lastButtonState = LOW;
long lastDebounceTime = 0;
long debounceDelay = 50;
int ledState = LOW;
long previousMillis = 0;
long interval = 5000;
long interval1= 10000;

void setup() {
pinMode(buttonPin, INPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
j=0;

}

void loop() {
int reading = digitalRead(buttonPin );
unsigned long currentMillis = millis();
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if(reading!=buttonState){
buttonState = reading;
if(buttonState==HIGH){
if (j==0)
{
j++;
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
}
else if (j==1)
{
j++;
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
digitalWrite(led1,HIGH);
digitalWrite(led2,LOW);

}
}
else if (j==2)
{
j=0;
if(currentMillis - previousMillis > interval1) {
previousMillis = currentMillis;

digitalWrite(led1,LOW);
digitalWrite(led2,HIGH);
}
}

}
}
}
lastButtonState = reading;
}

I gave you working code...

did you even try it?

thnx bro it is working. But my project which i am making is using Debounce how can i use this in that.
can you please suggest.

Shreyas_Bhavsar:
thnx bro it is working. But my project which i am making is using Debounce how can i use this in that.
can you please suggest.

Debounce is in the logic here:

if (reading == HIGH && reading != lastButtonState && (millis() - lastDebounceTime > 50)) // detect one side of the button press, and debounce it.

50 milliseconds of debounce....

so what am I missing?

Sry, bro its working awesome..... 8)
THANKS A LOT.. :slight_smile:

Hie BulldogLowell the programm given by you worked good but i want the led to be low unles an until i dont press the pushbutton. But in the programm given by you the serial monitor does reads pressed and the led goes high for 5/10 secs. Please suggest me what changes should i make in order to get it fixed. THANYOU IN ADVANCE.

Shreyas_Bhavsar:
Hie BulldogLowell the programm given by you worked good but i want the led to be low unles an until i dont press the pushbutton. But in the programm given by you the serial monitor does reads pressed and the led goes high for 5/10 secs. Please suggest me what changes should i make in order to get it fixed. THANYOU IN ADVANCE.

not at all clear what you want here...

what have you tried?

Yes i have Surely tried but it is working but the first press the arduino is taking by itself.

yes i have tried but i am not able to get the 1st press off. What i have tried:-
const int buttonPin = 0; // you should not use 0 or 1, generally. they are used for IO
const int led1 = 13;
unsigned long lastDebounceTime = 0;
long debounceDelay = 50;
int lastButtonState = LOW;
int buttonState;
int pressed=0;

const int buttonPin = 0; // you should not use 0 or 1, generally. they are used for IO
const int led1 = 13;
unsigned long lastDebounceTime = 0;
int pressed = 0;
int buttonState;
int lastButtonState = LOW;
long debounceDelay = 50;

void setup()
{
Serial.begin(9600);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(led1, OUTPUT);
digitalWrite(led1,LOW);
delay(1000);
pressed=0;
}

void loop()
{
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
if (pressed == 0)
{
lastDebounceTime = millis(); // start the millis() timer
}
}
}
Serial.println("pressed");
pressed++; //
if (pressed > 2) pressed = 2; // you could etend ths for more presses

}

lastButtonState = reading;
//
if (pressed)
{
illuminate();
}
}
//
void illuminate()
{
unsigned long duration = pressed * 5000UL; // counts longer fro two presses
if (millis() - lastDebounceTime < duration)
{
digitalWrite(led1, HIGH);
}
else
{
digitalWrite(led1, LOW);
pressed = 0;
}
}
PLEASE HELP ME. I am a newbie. THANX IN ADVANCE

OK, more loudly this time:

you should not use 0 or 1, generally. they are used for IO

and here you did it:

const int buttonPin = 0;  // you should not use 0 or 1, generally.  they are used for IO

right next to the note!!!

there may be other problems, but you should consider reading the notes :o

Hie i tried pin 10 but yet it Serial monitor is reading pressed.

Shreyas_Bhavsar:
Hie i tried pin 10 but yet it Serial monitor is reading pressed.

do you have a resistor on your switch button?

if so try changing this:

pinMode(buttonPin, INPUT_PULLUP);

to this:

pinMode(buttonPin, INPUT);

Yet the serial monitor is showing pressed even after it(pushbutton) not being pressed.
Can you please try it on your arduino and let me know if it works. if t works please inform me.
THANKYOU IN ADVANCE.

Shreyas_Bhavsar:
Can you please try it on your arduino and let me know if it works. if t works please inform me.

If you post the latest version of your code AND put it in code tags I will certainly try it.

...R