Go Down

Topic: How to debounce two buttons and LED? (Read 2254 times) previous topic - next topic

sntx_error

Jun 03, 2014, 05:55 pm Last Edit: Jun 03, 2014, 05:59 pm by sntx_error Reason: 1
Hello, this is my first question here.

I have one LED on pin 13, and two buttons on pins 2 and 3 with 10k resistors on the ground.

I`m trying to toggle LED by pressing any of this two buttons.

Example:

LED is HIGH
button A pressed
LED is LOW
button B pressed
LED is HIGH
button A pressed
LED is LOW
etc.

I`ve changed http://arduino.cc/en/Tutorial/Debounce example in many ways but it still works only for one button or works with huge lags.

I`m sure it`s very simple logic. Can any body explain me how to do this?


 
Thank you very much.


P.S. Sorry for my English. It`s not my native.

BulldogLowell

#1
Jun 03, 2014, 06:19 pm Last Edit: Jun 03, 2014, 06:39 pm by BulldogLowell Reason: 1
you want to change the LED's state if either button is pressed, that is straightforward.

you should post the sketch you used and confirm the schematic of how you wired the pushbuttons

Did you get it to work as in the example with a single button?

sntx_error

#2
Jun 03, 2014, 07:11 pm Last Edit: Jun 03, 2014, 07:19 pm by sntx_error Reason: 1
Thank you for your attention!

With one button i put it to work fine.

I used so many sketches and i didn`t save any of them because they was not working.

I was digital reading each button to variable and was trying to divide two readings in two conditions same as in debounce example...

Here is sketch reproduction:

Code: [Select]


const int buttonPin_1 = 2;  
const int buttonPin_2 = 3;
const int ledPin = 13;  

int ledState = HIGH;
int buttonState;
int lastButtonState = LOW;

long lastDebounceTime = 0;
long debounceDelay = 50;

void setup() {
 pinMode(buttonPin, INPUT);
 pinMode(ledPin, OUTPUT);

 digitalWrite(ledPin, ledState);
}

void loop() {
 int read_1 = digitalRead(buttonPin_1);
 int read_2 = digitalRead(buttonPin_2);

 if ((read_1 || read_2) != lastButtonState) {
   lastDebounceTime = millis();
 }

 if (read_1 == HIGH) {  
   if ((millis() - lastDebounceTime) > debounceDelay) {
       if (read_1 != buttonState) {
         buttonState = read_1;
         if (buttonState == HIGH) {
           ledState = !ledState;
         }
       }
     }
  digitalWrite(ledPin, ledState);
  lastButtonState = read_1;
  } else  if (read_2 == HIGH) {  
   if ((millis() - lastDebounceTime) > debounceDelay) {
       if (read_2 != buttonState) {
         buttonState = read_2;
         if (buttonState == HIGH) {
           ledState = !ledState;
         }
       }
     }
  digitalWrite(ledPin, ledState);
  lastButtonState = read_2;
 }
}


There is scheme





BulldogLowell

#3
Jun 03, 2014, 07:41 pm Last Edit: Jun 03, 2014, 07:47 pm by BulldogLowell Reason: 1
Start here:

Code: [Select]

const int buttonPin_1 = 2;  
const int buttonPin_2 = 3;
const int ledPin = 13;  

int ledState = HIGH;
int buttonState;
int lastButtonState = LOW;

long lastDebounceTime = 0;
long debounceDelay = 50;

void setup() {
 pinMode(buttonPin, INPUT);
 pinMode(ledPin, OUTPUT);

 digitalWrite(ledPin, ledState);
}


in the setup() you have set neither button_Pin_1 nor button_Pin_2 for INPUT.

added: you should have noticed something was wrong when you couldn't successfully compile this, btw.

racemaniac

btw, why are you debouncing?
debouncing is to prevent registering the button press multiple times, but in this case that doesn't make any difference. If you turn the led on 50 times it's still just as much on as if you turn it on 1 time.

Paul__B


btw, why are you debouncing?
debouncing is to prevent registering the button press multiple times, but in this case that doesn't make any difference. If you turn the led on 50 times it's still just as much on as if you turn it on 1 time.


He said "toggle".  :smiley-eek:

See what you can do with this code:

Code: [Select]
// Blink without "delay()" - multi!

const int led1Pin =  13;    // LED pin number
const int led2Pin =  10;
const int led3Pin =  11;
const int button1 =  4;
int led1State = LOW;        // initialise the LED
int led2State = LOW;
int led3State = LOW;
char bstate1 = 0;
unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;       
  }
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far,
    if (button == HIGH) return false; // Nothing happening!
    else {
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far,
    if (button == LOW) return false; // Nothing happening!
    else {
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else {
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    { 
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);     
  pinMode(led2Pin, OUTPUT);     
  pinMode(led3Pin, OUTPUT);     
  pinMode(button1, INPUT);     
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (led1State == LOW) {
      led1State = HIGH;
    }
    else {
      led1State = LOW;
    }
    digitalWrite(led1Pin, led1State);
  }

  // Act if the latter time (ms) has now passed on this particular counter,
  if (timeout(&count2, 300UL )) {
    if (led2State == LOW) {
      led2State = HIGH;
    }
    else {
      led2State = LOW;
    }
    digitalWrite(led2Pin, led2State);
  }

  if (timeout(&count3, 77UL )) {
    if (led3State == LOW) {
      led3State = HIGH;
    }
    else {
      led3State = LOW;
    }
    digitalWrite(led3Pin, led3State);
  }
}


Contains extra LED stuff and only one button, but when you get to know it, you can replicate the button code for two buttons (you just need extra count and state markers) and do whatever you want with them.

Note that you should have the buttons pulling the inputs to ground and I include code for internal pull-ups, but if you do not enable internal pull-ups and use your circuit "as-is"  (adjusting the pin definitions to suit), it will function as you release the button rather than pressing it - which generally works just as well.

CarlW

There is a bounce library.

With three total inputs and outputs, one could use interrupt pins and either rising or falling; they only happen for one cycle.

Go Up