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

Suggestion for implementing 'setLongReleasedDelay' #117

Closed georgevbsantiago closed 1 year ago

georgevbsantiago commented 1 year ago

Hello, @bxparks

Thank you so much for this GREAT library!

I started using the Acebutton library in my projects and I'm really enjoying it.

I used the EasyButton library in my projects. With EasyButton it was possible to use the function to identify how long a button was released [ex: button.releasedFor(releasedForTime) ]; . However, I haven't found a way to do this with Acebutton. See here: https://easybtn.earias.me/docs/released-for-api/

This function is especially important when we want to identify the state of a water float . The problem is that water waves/ripples can change the float state from HIGHT to LOW quickly (see image below).

I'm trying the following approach:

ButtonConfig* config_buoy = buoy.getButtonConfig();
config_buoy ->setEventHandler(handleEvent_boia_superior);
config_buoy ->setDebounceDelay(50);
config_buoy ->setFeature(ButtonConfig::kFeatureLongPress);
config_buoy ->setLongPressDelay(5000);
config_buoy ->setFeature(ButtonConfig::kFeatureSuppressAfterLongPress);

The problem is that kEventLongReleased is quickly triggered when water waves/ripples change the float state from HIGHT to LOW.

Therefore, it would be important to assign a delay to kEventLongReleased, something like a setLongReleasedDelay method:

ButtonConfig* config_buoy = buoy.getButtonConfig();
config_buoy ->setEventHandler(handleEvent_boia_superior);
config_buoy ->setDebounceDelay(50);
config_buoy ->setFeature(ButtonConfig::kFeatureLongPress);
config_buoy ->setLongPressDelay(5000);
config_buoy ->setFeature(ButtonConfig::kFeatureSuppressAfterLongPress);
config_buoy ->setLongReleasedDelay(10000);

With setLongReleasedDelay(10000); the kEventLongReleased event would not be triggered on the ripples of the water, but only when it stabilizes for a period of 10 seconds (in the example above).

Would this implementation in Acebutton be viable? This was the only EasyButton functionality that I didn't find in Acebutton.

image image

bxparks commented 1 year ago

I've been mulling over this for a few days, and I think I understand what you are trying to do. The problem is that the current kEventLongReleased is not intended to mean to what you want it to mean.

The current kEventLongReleased event was a solution to a very specific problem, as described in Distinguishing Pressed and LongPressed: When the kEventReleased is suppressed to allow the differentiation between Pressed and LongPressed, we lose the kEventReleased from the LongPressed, so the kEventLongReleased was added to compensate.

Your version of kEventLongReleased is different. It is the symmetric equivalent of the kEventLongPressed, triggered when a button is released for a long duration. I never considered this to be an event, because by default, the buttons are considered to be in the Released state, and it did not seem that an event should be triggered without a specific human action.

If we were to implement your version of kEventLongReleased, then by symmetry, it would imply that we should implement a kEventRepeatReleased which triggers every 200 milliseconds in the Released state, in the same way that kEventRepeatPressed is triggered. I'm not sure that makes sense.

So I have a counter-suggestion: You are essentially using the LongPressed event to perform debouncing of your water level switch at a much larger timescale than the usual 20-50 milliseconds. You want to a debouncing at the level of 5-10 seconds. So instead of using LongPressed, is it possible to achieve your goals by using the normal kEventPressed and kEventReleased, but increase your setDebounceDelay(5000) instead?