Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cant disable AutoRepeatPress #17

Closed
steiraa opened this issue Nov 20, 2023 · 15 comments
Closed

Cant disable AutoRepeatPress #17

steiraa opened this issue Nov 20, 2023 · 15 comments

Comments

@steiraa
Copy link

steiraa commented Nov 20, 2023

Hello, I have the following code:

prevButton.disableEvent(Event_AutoRepeatPress);
prevButton.disableEvent(Event_DoubleClick);
prevButton.disableEvent(Event_KeyDown);
prevButton.disableEvent(Event_KeyUp);

prevButton.bind(Event_KeyPress, 0, &prevEventHandler);
prevButton.bind(Event_LongKeyPress, 0, &longPrevEventHandler);


void prevEventHandler(void)
{

  Serial.println("prev pressed");
}

void longPrevEventHandler(void)
{

  Serial.println("long prev pressed");
}

But whenever I longpress a button, the Autorepeatpress also triggers(When i set the Autorepeatpress Interval to a high value, it "works")

This is the response from my ESP32, when i only press and hold the button for a few seconds:

long prev pressed
prev pressed
prev pressed
prev pressed
prev pressed
prev pressed
prev pressed
@rwmingis
Copy link
Owner

Hi steiraa,

I'm at work atm and not able to go through the code at the moment, but the following should sort it out in the near term.

// Try one or both of the below 2 lines
prevButton.disableEvent(Event_All);                                // This disable all events associated with that button
prevButton.bind(Event_AutoRepeatPress, nullptr);         //  Inside the library, if the function is undefined, then it doesn't even try to call it

// Then carry on as before.
prevButton.bind(Event_KeyPress, 0, &prevEventHandler);                 // Event automatically enabled when binding an action
prevButton.bind(Event_LongKeyPress, 0, &longPrevEventHandler);  // Event automatically enabled when binding an action

Worth trying this and letting me know how you go. If the event is 'undefined' by binding a nullptr instead of a function pointer, then the library should never call it. If it continues, then something else is probably happening elsewhere in the main code?

Cheers.

@rwmingis
Copy link
Owner

Actually, can you send me the minimal code to reproduce the issue? I just had another look, and the bit I suggested about disableEvent(Event_All) doesn't flush the mask like my memory said it did so that won't fix it.

Also, if the Event_AutoRepeatPress event is enabled, but you don't bind a function to the AutoRepeatPress event, it just uses the function alreayd bound to Event_KeyPress event as default.

@steiraa
Copy link
Author

steiraa commented Nov 21, 2023

Hello, thanks for the quick replay!

Sadly all of your fixes didnt work for me. I attached the full code to reproduce the issue and a video showcasing it.

The prevButton.disableEvent(Event_All); command disables any event with the Button, I dont even get normal Event_KeyPress anymore.

#include "InterruptButton.h"
#include <Arduino.h>
#define PREV_PIN 2

InterruptButton prevButton(PREV_PIN, LOW);

void prevEventHandler(void);
void longPrevEventHandler(void);

void setup()
{
  Serial.begin(115200);
  while (!Serial)
    ;

  InterruptButton::setMode(Mode_Asynchronous);

  // prevButton.disableEvent(Event_All);
  prevButton.disableEvent(Event_DoubleClick);
  prevButton.disableEvent(Event_KeyDown);
  prevButton.disableEvent(Event_KeyUp);
  prevButton.disableEvent(Event_KeyPress);
  prevButton.disableEvent(Event_LongKeyPress);
  prevButton.disableEvent(Event_AutoRepeatPress);

  prevButton.bind(Event_KeyPress, 0, &prevEventHandler);
  prevButton.bind(Event_LongKeyPress, 0, &longPrevEventHandler);
  prevButton.bind(Event_AutoRepeatPress, nullptr);
};

void loop()
{
}

void prevEventHandler(void)
{

  Serial.println("prev pressed");
}

void longPrevEventHandler(void)
{

  Serial.println("long prev pressed");
}

20231121_164451.-.Trim.1.mp4

I am using Platformio and an AZ-Delivery ESP-32 Dev Kit C V4

@rwmingis
Copy link
Owner

rwmingis commented Nov 22, 2023 via email

@rwmingis
Copy link
Owner

OK, I sat down tonight and figured it out.

I originally thought it must have been a bug in the library, but I think the library is sound. It's just the implementation. Almost an undocumented feature. 😁

Soooooo, when you bind an action (a function) to an event (a key press, double click, etc.) that is associated with a button, the library thinks you want to of course enable that event/action by default, so it enables it. If you want to disable it, then you need to disable it AFTER you bind the actiont to the button's specific event.

So, I modified your code accordingly below. Let me know if this solves your issue and I will close out the issue.

Cheers!

#include <Arduino.h>
#include "InterruptButton.h"

#define PREV_PIN 2

InterruptButton prevButton(PREV_PIN, LOW);

void prevEventHandler(void);
void longPrevEventHandler(void);


//== MAIN SETUP FUNCTION ===========================================================================
//==================================================================================================

void setup() {
  Serial.begin(115200);                           // Remember to match platformio.ini setting here
  while(!Serial);                                 // Wait for serial port to start up

  InterruptButton::setMode(Mode_Asynchronous);

  prevButton.bind(Event_KeyPress, 0, &prevEventHandler);
  prevButton.bind(Event_LongKeyPress, 0, &longPrevEventHandler);
  prevButton.bind(Event_AutoRepeatPress, nullptr);    // This does clear the auto repeat press binding, but still enables the feature. 
                                                      // Because it has been enabled, but no special autoRepeat press function is bound to it,
                                                      // it defaults to using the action for regular keyPress because the function is similar.
                                                      // YOu can just delete this line unless you want to bind an autoREpeatePress action specific
                                                      // function that is different from a regular keypress.

  prevButton.disableEvent(Event_AutoRepeatPress);     // So you need to disable the autoRepeatPress event AFTER you define it if
                                                      // that is your intention to prevent it
}


//== MAIN LOOP FUNCTION =====================================================================================
//===========================================================================================================

void loop() { 
  if(InterruptButton::getMode() != Mode_Asynchronous) InterruptButton::processSyncEvents();

  // Normally main program will run here and cause various inconsistant loop timing in syncronous events.

  delay(2000);
}

void prevEventHandler(void)
{

  Serial.println("prev pressed");
}

void longPrevEventHandler(void)
{

  Serial.println("long prev pressed");
}

@steiraa
Copy link
Author

steiraa commented Nov 23, 2023

Hey, sadly this code doesnt solve my issue. It behaves the same as before :(

I circumvented the problem by binding an empty function to Event_AutoRepeatPress at the moment

@rwmingis
Copy link
Owner

Did you copy and paste the code exactly from my last post? Because when I tried it, it did what you were saying (which is planned behaviour) until I called

prevButton.disableEvent(Event_AutoRepeatPress)

Immediately after binding the Event_AutoRepeatPress. Even binding a nullptr instead of a function will turn it back on. Because it's a nullptr, it just defaults to actioning whatever you bound to the regular keypress. Ie rapidfire of the regular keypress after a brief pause.

So there is no benefit to the line below unless clearing out a special rapidfire so you can go back to regular keypress rapid fire.

prevButton.bind(Event_AutoRepeatPress, nullptr)

If you haven't copied the code in my previous post exactly, then try that, upload it, and see if it still happens.

Cheers

@rwmingis
Copy link
Owner

Did you have any success with the code above?

@steiraa
Copy link
Author

steiraa commented Nov 25, 2023 via email

@steiraa
Copy link
Author

steiraa commented Nov 26, 2023

Hey, yes i copied the code exactly from your post, the issue still exixts.

@rwmingis
Copy link
Owner

rwmingis commented Nov 27, 2023 via email

@steiraa
Copy link
Author

steiraa commented Nov 28, 2023

Hey, it works now! The new file from ur repo fixed it! The difference maker was this change, I tested it.

Thanks for your fast and compentent help, kinda saved my project or at least helped a lot!

@rwmingis
Copy link
Owner

Ah, good, glad to see it's fixed. Was eating at me abit. That change that you mentioned was something I added out of Issue 18, not 100% that's it. Feel like it's more like where I forgot to put a mask in to check if the autoRepeatPress event was enabled before calling it. which i added in July of 2022. When did you download the original code? Bet that was it.

if(btn->eventEnabled(Event_AutoRepeatPress) && gpio_get_level(btn->m_pin) == btn->m_pressedState) { // Sanity check to stop autorepeats in case we somehow missed button release

if(btn->eventEnabled(Event_AutoRepeatPress) && gpio_get_level(btn->m_pin) == btn->m_pressedState) { // Sanity check to stop autorepeats in case we somehow missed button release

@steiraa
Copy link
Author

steiraa commented Nov 29, 2023

I downloaded this release on the 20th Nov

@rwmingis
Copy link
Owner

Ok, I can see that bug fix didn't make it into that release apparenty if only by a day. Will do a new release today to save others strife. Thanks for your feedback! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants