Timer/debounce Issue

I’m having an issue with a debounce timer. I’ve stripped away all the logic except for the timer section and I can’t get it to work. I hate posting this since it’s so simple but I’m stuck. Here’s what the logic should do:

Button Press (signal low) --> Wait 100ms --> Turn on LED (drive signal low)

I can never get the second if statement below to evaluate as true. I must be missing something simple…


unsigned long startTimeDebounce = 0;        // Start time for debounce timer
unsigned long debounceTimeInterval = 100;   // 100 ms


void setup()
{
    pinMode(D0, INPUT_PULLUP);  //Button Input
    pinMode(D2, OUTPUT);        //LED, LOW =ON
}

void loop() 
{
    int button = digitalRead(D0);
    startTimeDebounce = millis();
    if (button == 0)
    {
        if ((millis() - startTimeDebounce) > debounceTimeInterval)
        {
            digitalWrite(D2, LOW);  //ON
        }
   }
    else
    {
        digitalWrite(D2, HIGH);     //OFF
    }

}

Think about it.

Every time through the loop that button == 0, you will do the following:

Read millis()
Read millis() again after the if (button == 0) test.
See if the difference was > debounce time

Rinse lather repeat. The difference will never accumulate because you get new values of millis() every time loop() is called.

1 Like

Thank you and yes, I agree and wish I caught that before I posted. I moved read millis() into the first button test if statement and I still have the issue. Or, am I missing something obvious again. Here’s the code?

unsigned long startTimeDebounce = 0;        // Start time for debounce timer
unsigned long debounceTimeInterval = 100;   // 100 ms


void setup()
{
    pinMode(D0, INPUT_PULLUP);   //Button Input
    pinMode(D2, OUTPUT);              //LED, LOW =ON
}

void loop() 
{
    int button = digitalRead(D0);
    if (button == 0)
    {
        startTimeDebounce = millis();
        if ((millis() - startTimeDebounce) > debounceTimeInterval)
        {
            digitalWrite(D1, LOW);  //ON
        }
    }
    else
    {
        digitalWrite(D2, HIGH);     //OFF
    }

}

Think about it again - what will the delay be between the two calls to millis() and under what circumstances can it be anything other than a very small, invariant number ?

It looks like you want to measure the time that has elapsed since button transitioned from 1 to 0. You need to identify that event and timestamp it.

1 Like

I did find one of my problems I’m trying to write to the wrong output.
This:

To the correct output section to the correct pin:

        if ((millis() - startTimeDebounce) > debounceTimeInterval)
        {
            digitalWrite(D2, LOW);  //ON
        }

Still doesn’t work correctly for me.

OK, the solution was way too simple. You answer was spot on but I was thinking about it the wrong way for too long. Thank you for your insight.

2 Likes

No prob. Glad you figured it out.

Post your working code, so others can benefit.

Good idea. Working code here:

unsigned long startTimeDebounce = 0;        // Start time for debounce timer
unsigned long debounceTimeInterval = 100;   // 100 ms


void setup()
{
    pinMode(D0, INPUT_PULLUP);  //Button Input
    pinMode(D2, OUTPUT);        //LED, LOW =ON
}

void loop() 
{
    int button = digitalRead(D0);
    if (button == 0)
    {
    
        if ((millis() - startTimeDebounce) > debounceTimeInterval)
        {
            digitalWrite(D2, LOW);  //ON
        }
    }
    else
    {
         startTimeDebounce = millis();
         digitalWrite(D2, HIGH);

    }
}

@fozebaire, @AndyW is ridiculously smart! As a note, you can also check out the clickButton library on the Web IDE :smile:

Earn extra credit by initializing the debounce timestamp from millis() in setup(), so that the code does the same thing if the button is pressed (or bouncing) at startup.

I’m still not sure this does exactly what you want. This code will keep resetting the delay until the debounce stops. It’ll work well enough, but that’s what it will do.

@peekay123, I thought about using that but I wanted to make sure I know what’s happening with timing since I will be adding some non-button related timing events. I’ve changed the program to reflect @AndyW inputs as well as add comments in case anyone wants to refer to this in the future.

unsigned long startTimeDebounce = 0;        // Start time for debounce timer
unsigned long debounceTimeInterval = 500;   // 100 ms


void setup()
{
    pinMode(D0, INPUT_PULLUP);  //Button Input
    pinMode(D2, OUTPUT);        //LED, LOW =ON

    //Initialize debounce timer
    startTimeDebounce = millis();
    
}

void loop() 
{
    int button = digitalRead(D0);
    if (button != LOW)                      //Keep reseting timer until button pressed
    {
        startTimeDebounce = millis();       //Reset debounce timer
    }

    if ((millis() - startTimeDebounce) > debounceTimeInterval)  //Wait for debounce interval to pass
    {
        digitalWrite(D2, LOW);              //ON
    }
    else
    {
        digitalWrite(D2, HIGH);             //OFF
    }
    
}
2 Likes