Debouncing inputs and Rising Edge detection in Arduino

by MOAM Industries

Micro Controlers are amazing devices however their resources must be used sparingly. Whilst it is ideal to debounce many inputs at the hardware level with a combination of capacitors and schmitt triggers sometimes it is not practical so debouncing is performed by the Microcontroller and it’s internal timers. To debounce an input you need to register 3 things:

  1. The input has changed
  2. The input has remained changed for a set ammount of time
  3. Update the status of the input

This is typically done with a section of code similar to that below, this is for an “Up” navigation button.

int historicUP = 0;
int stateUP = 0;
long upTime;

int debounce(){
  int up_reading = digitalRead(1);  //read the digital input

  if(historicUp != up_reading){              //state has changed since last input scan
    upTime = millis();                                  // reset time count
    historicUp = up_reading;                  // Record the current state
  else if( millis() – upTime > 30){         // The state has not changed within the
time frame defined

  stateUp = up_reading;                      //  Store the debounced state
However sometimes it can be benefitial to detect just the rising edge of a button. With this it becomes easier to navigate menus and events which increment/decrement with each button push. This can be achieved with the addition of a few extra lines of code and is much less resource hungry than multiple delay timers and calls to the millis() function. So the code is similar to before but notice the few additons

if(historicUp != up_reading){          //State has changed since last input scan
   upTime = millis();                              // Reset time count
   historicUp = up_reading;              // Record the current state
else if( millis() – upTime > debounceT ){      // The state has not changed within the
time frame defined

   if(menuUp != up_reading){                         // If the previous debounced state is not the
same as the previous time it was called

     if(up_reading){                                                  // If the input is high, could just as easily
work for falling edge detection

       upRising = 1;                                                    // Toggle the rising edge bit high
else{                                                                        // Elsewise the bit has not changed therefore
no longer a rising edge since previous function call

   upRising = 0;                                                      // Toggle the rising edge bit low
menuUp = up_reading;                                //Store the new debounced state ready for refernce elsewhere
and for the next call of this routine.