2

I am trying to start an event after pressing and holding the FLASH built-in Nodemcu button for a specific time, I wrote two functions, one for debouncing and detecting the state, the other is to detect the pressing time, I'm not getting any result unless I decrease the input pressing time to less than 1s, which makes the button works as a single-push button, I think i have a problem with debouncing the button, I can't figure out where it is?

/**
* @brief debounces the button and returns the current level high or low
* 
* @return int the button state 0: low, 1: high, -1 indetermined
*/
int button_state(int btn)
{
    int const DEBOUNCE = 200;
    static int hi = DEBOUNCE;
    static int lo = 0;
    if (digitalRead(buttonPin[btn]))
    {
        if (hi < DEBOUNCE)
        {
            hi++;
        }
        if (lo > 0)
        {
            lo--;
        }
    }
    else
    {
        if (lo < DEBOUNCE)
        {
            lo++;
        }
        if (hi > 0)
        {
            hi--;
        }
    }

    if (hi == DEBOUNCE)
    {
        return 1;
    }
    else if (lo == DEBOUNCE)
    {
        return 0;
    }
    else
    {
        return -1;
    }
}
/**
 * @brief Detects the button state and starts a time to calculate pressing duration 
 * 
 * @param btn input button pin
 * @param PressTime Desired pressing duration to compare to
 * @return int returns 1 when PressTime is reached
 */
int PressNHold(int btn, int PressTime)
{
    int lastButtonState = 0, Startpressed = 0, endPressed = 0, holdTime = 0,
    buttonState = button_state(btn);
    if(buttonState != -1)
    {
        if (buttonState != lastButtonState)
        {
            if (buttonState == 1)
            {
                Startpressed = millis();
            }
            else
            {
                endPressed = millis();
                holdTime = endPressed - Startpressed;
                if (holdTime >= PressTime)
                {
                    Serial.printf("Button %d pressed for %ds or more\n", btn, holdTime);
                    holdTime = 0;
                    return 1;
                }
            }
        }
    }
    lastButtonState = buttonState;
}
.....

void loop {

if (PressNHold(buttonPin[1], 5 * 1000) == 1)
  {
   //launch your event 
  }
3
  • I don’t follow your debounce routine. It is very unorthodox. Perhaps it would do some good to study some other existing debounce code and write something that we know works.
    – Delta_G
    Commented Jun 24, 2020 at 13:53
  • the debounce code looks like it should work .... it would be easier to read if the if statements were one-liners .... replace the PressNHold code to just print a timestamp at button transitions ... that may help narrow down the area of failure
    – jsotola
    Commented Jun 24, 2020 at 14:40
  • Does your button have a pulldown resistor? Commented Jun 24, 2020 at 18:57

1 Answer 1

1

turns out that it is very simple, I shouldn't put buttonPin[1] a variable for PressNHold, I had to put just1, buttonPin was used already in button_state, also, PressnHold local variables should be declared static to not get a reset after function execution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.