bxparks / AceButton

An adjustable, compact, event-driven button library for Arduino that debounces and dispatches events to a user-defined event handler.
MIT License
385 stars 37 forks source link

Tri-state button example #68

Closed ptashek closed 3 years ago

ptashek commented 3 years ago

First of all, thanks for making and sharing this library 👍

I have a use case (car cruise control) where a single momentary push button serves three functions.

  1. when pressed and released (click) it bumps the current target speed by 1
  2. when pressed and held it commands an acceleration event until released
  3. when released after a long press it sets the current speed as the target speed

Detecting short press / long press on release is no issue. Just wondering if there's a minimal way to handle the "long press while held" event.

ptashek commented 3 years ago

Turns out I already had the code right, just initiated the button with the wrong default state. The library internally assumes HIGH to be the default, thus pre-configured for buttons wired to INPUT_PULLUP pins. Setting the default state to LOW started triggering the correct events in the correct sequence. Buttons in my case are configure as INPUT not INPUT_PULLUP.

AceButton button(BUTTON_PIN, LOW);

void handleButtonEvent(AceButton* /*button*/, uint8_t eventType, uint8_t /*buttonState*/) {
  switch (eventType) {
    case AceButton::kEventReleased:
      Serial.println("short pressed");
      break;

    case AceButton::kEventLongPressed:
      Serial.println("long pressed");
      break;

    case AceButton::kEventLongReleased:
      Serial.println("long released");
      break;
  }
}

void setup() {
    ButtonConfig* config = button.getButtonConfig();
    config->setFeature(ButtonConfig::kFeatureLongPress);
    config->setFeature(ButtonConfig::kFeatureSuppressAfterLongPress); 
    button.setEventHandler(handleButtonEvent);
}
bxparks commented 3 years ago

That's perfect! I added kEventLongReleased relatively recently, to handle exactly this usage.

The other event that might be useful to you is kEventRepeatPressed, which can be auto-triggered while the button is held down. But if your code is already handling the "acceleration" part, then you don't need kEventRepeatPressed.