Debouncing Multiple buttons

Hi,
I am trying to build an alarm clock that will essentially brew coffee for you. I have a couple of questions. Firstly, I have three buttons, one which changes the menu UI on the LCD, and two which are used as selection buttons. I have been able to debounce the menu button, but when I try to debounce the two selection buttons it says “redefinition of ‘boolean debounce(boolean)’”. Secondly, I am using a DS1307 with the RTClib library from adafruit. I can print the current time, but I don’t know how to make an alarm clock function using now.unixtime. I would appreciate any help. I know my code is extremely messy and unorganised Hahaha. Thanks a lot to anyone who can help. :slight_smile: :slight_smile: :slight_smile:

LCD_Coffee_Settings_Menu.ino (3.85 KB)

Sorry for the inconvenience. I have figured out the problem. Simple typos and forgot the name the function a different name :P

I still am confused on how to go about using unixtime to create an alarm. Please help. Thanks

This is the TimeAlarms library : https://www.pjrc.com/teensy/td_libs_TimeAlarms.html

Thank you so much!! Exactly what I needed.

Wait but in order to use that library I have to use the "Time" library. I would like to use the RTClib library with my DS1307

Yes, it works with the Time library. https://www.pjrc.com/teensy/td_libs_Time.html That is a system time on the Arduino. The DS1307 will only be used to update the system time now and then.

I don't know how to do that with the RTClib. You could write your own code, request the time and compare it.

Take a look at the example ds1307 included in the RTClib library. It shows the use of now.unixtime, and DateTime future (now.unixtime() + some added time).

Once you get the menu and selection buttons working to get the correct incremental alarmHour and alarmMinute, you can compute a future.unixtime, and compare the value of now.unixtime to it. When they match, execute the alarm.

Ok that makes a lot of sense! Thanks so much! @cattledog

Useful little code structure for debouncing multiple buttons:

// Button toggle with extreme reliability!

const int led1Pin =  13;    // LED pin number
const int button1 =  10;
int led1State = LOW;        // initialise the LED
char bstate1 = 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
// Routines by Paul__B of Arduino Forum
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.
// Routines by Paul__B of Arduino Forum
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(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);
  } 
}

For debouncing buttons, why just don't use capacitor ?

1st. Because why use expensive (in multiple ways) external components if you can do the same thing with some good programming techniques.

2nd. Using this blink without delay-style delays is good practice. Real life doesn't stop either while you are waiting for an elevator or the bus to arrive.

moxys: For debouncing buttons, why just don't use capacitor ?

Because it does a very poor job. You actually need a capacitor (electrolytic, a few µF) plus two resistors to control the charge and discharge and a Schmidt input buffer such as a 74HC14.

The proper software algorithm - as I illustrated - does a superior job with no extra components. It specifically requires the button state to change consistently for all of the debounce interval - any faltering is rejected - the capacitor version cannot do this.