Software based digital input debouncer

DigitalInDebounced.cpp

Committer:
Waldek
Date:
2014-06-04
Revision:
2:dabe90a0bdc1
Parent:
1:b59d305c4365

File content as of revision 2:dabe90a0bdc1:

#include "DigitalInDebounced.h"
/*-------------------------------------------------------------

(c) W.D. 2014

-------------------------------------------------------------*/

DigitalInDebounced::DigitalInDebounced(PinName pin_in, unsigned int inDebounceTime)
{
   Switch = new DigitalIn(pin_in);
   DigitalInDebounced_common(Switch, inDebounceTime);
}
    
DigitalInDebounced::DigitalInDebounced(PinName pin_in, PinMode mode, unsigned int inDebounceTime)
{
   Switch = new DigitalIn(pin_in, mode);
   DigitalInDebounced_common(Switch, inDebounceTime);
}

void DigitalInDebounced::DigitalInDebounced_common(DigitalIn *SwitchIn, unsigned int inDebounceTime)
{
    recent = !SwitchIn->read();
    stable = false;
    DebounceTime = inDebounceTime;
    long int DebounceCount = (inDebounceTime*1000l) / timer_user.TickerPeriod_rd();
    if (DebounceCount > SAMPLES_TO_DEBOUNCE)
    {
        PreDivider = DebounceCount / SAMPLES_TO_DEBOUNCE;
        Divider = DebounceCount / PreDivider;
        if ((DebounceCount - (PreDivider * PreDivider)) > 0) Divider++;
    }
    else
    {
        PreDivider = 1;
        Divider = DebounceCount;
    }
        
    DebounceCounter = Divider;
    timer_user.Subscribe (this, PreDivider);
}

bool DigitalInDebounced::read(void)
{
    if (this->stable) 
        return this->recent;
    else
        return false;
}

DigitalInDebounced::~DigitalInDebounced()
{
    timer_user.UnSubscribe(this);
}

void DigitalInDebounced::TimerEvent(void)
{
    bool temp = !Switch->read();
    if (temp == recent)
    {
        if (!stable)
            if (0 == (--DebounceCounter))
                stable = true;
    }
    else
    {
        stable = false;
        recent = temp;
        DebounceCounter = Divider;
    }
}