Debouncing inputs and Rising Edge detection in Arduino

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(yourPin);      //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{                             // 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.
  }

Leave a Reply

Your email address will not be published. Required fields are marked *