Debounced Input Class

Debouncing of inputs is something that I find a pain to program much of the time. Fitting it around your existing code schema can be a challenge. That's why I most often do my debouncing in hardware.

Hardware debouncing isn't always convenient though - maybe it takes up precious board realestate, or your budget doesn't stretch to the few pence required per button - maybe you have too many buttons. So, I wrote this little simple class to help me out when I need it.

class DebouncedInput
{
  private:
    byte pin;
    int value;
    unsigned long lastChange;
    unsigned long debounceTime;
    int lrt;
    boolean pullup;
    
  public:
    DebouncedInput(byte pin_, unsigned long dbt_, boolean pullup_ = true) : 
      pin(pin_), debounceTime(dbt_), pullup(pullup_) {};

    int read() 
    {
      int r;
      unsigned long now = millis();
      if (this->pullup) {
        pinMode(this->pin, INPUT_PULLUP);
      } else {
        pinMode(this->pin, INPUT);
      }
      r = digitalRead(this->pin);
      if (r != this->lrt) {
        this->lrt = r;
        this->lastChange = now;
      }
      if (now - this->lastChange > this->debounceTime) {
        if (this->value != this->lrt) {
          this->value = this->lrt;
        }
      }
      return this->value;
    };
};

It's very simple to use: Drop that code in at the top of your Arduino sketch, then create yourself a new instance of the class for each button you want:

DebouncedInput button1(2, 10, true);

The first parameter is the input pin number, the second is the number of milliseconds to debounce the input by, and the third is whether or not to use the internal pull-up resistor of the input pin.

You can then use it in place of your normal digitalRead() calls by calling the .read() method of the class instance:

int value = button1.read();

The operation is quite simple. It measures how long the input has been in any one state, and when it has been in one state long enough (the debounce time) then it registers that state as the current value for the input. So, say you set the debounce to 10, then the input has to be in a steady state (high or low) for at least 10 milliseconds for the value of the input to change.