LennartHennigs / Button2

Arduino/ESP button library that provides callback functions to track single, double, triple and long clicks. It also takes care of debouncing.
MIT License
487 stars 81 forks source link

LongClickDetectedHandler triggered after boot? #46

Closed LennartHennigs closed 1 year ago

LennartHennigs commented 2 years ago

I tried to replace the setLongClickHandler(handler) ...which works fine (but you don't know if your press was long enough until you release the button), by setLongClickDetectedHandler(handler) and I noticed a side effect. Look at the log below and my comments in bold.

And this side effect is consistent. You might want to look into it...

--- Terminal on /dev/ttyACM0 | 115200 8-N-1
--- Available filters and text transformations: colorize, debug, default,
direct, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H

Starting MMT Power Supply Interface !!!

PG set to PG40
EEPROM Beginning : 0
EEPROM End : 16384
System Voltage Set Value : 10.000
Corresponding DAC Voltage Output : 1.65
Corresponding DAC Binary Voltage Output : 2047
System Current Set Value : 0.500
Corresponding DAC Current Output : 0.82
Corresponding DAC Binary Current Output : 1023
System Input Voltage        : 4.7820001
Output Voltage              : 7.4822955
System Output Current       : 0.0019200
Z Output                    : 3897.03
System Power W              : 0.0090394

(1)** <------------------------------------------------------------- this was a long click (not ok) ... it happens only once after boot-up, as if no case in the function (see function below) was satisfied.***
---long click (1)
**<------------------------------------------------------------- this was a long click  (ok)**
ENTERING SELECTION MODE NORMAL OPERATION

---long click (1)
**<------------------------------------------------------------- this was a long click  (ok)**
Getting out of the Parameter Selection function

ENTERING MODIFICATION MODE

---long click (1)
**<------------------------------------------------------------- this was a long click  (ok)**
System Voltage Set Value : 10.000
Corresponding DAC Voltage Output : 1.65
Corresponding DAC Binary Voltage Output : 2047
Getting out of the Parameter Modificaton function

---double click (2)
**<------------------------------------------------------------- this was a long click  (ok)**
ENTERING PRESET SELECTION MODE

----Set pointer to the selected window
Set Coordinates To Preset Window
SetCoordinatesToPresetWindow preset3V3
*****Highlight Preset Window
*****Initialize Preset Window
CW Direction -- Encoder Value : 1
*******1----Set pointer to the selected window
++++Give Preset Colors To Window : preset5V0
Set Coordinates To Preset Window
SetCoordinatesToPresetWindow preset5V0
*****Highlight Preset Window
*****Initialize Preset Window
---double click (1)
**<------------------------------------------------------------- this was a long click (not ok) ... it appens consistently.**
---long click (1)
**<------------------------------------------------------------- this was a long click  (ok)**
Preset Value Selected saved to EEPROM
System Voltage Set : 5.000
System Current Set : 0.500
System Input Voltage        : 4.7900000
Output Voltage              : 7.4725275
System Output Current       : 0.0019200
Z Output                    : 3891.94
System Power W              : 0.0095182
/*************************************************************************************************************************/
/* BUTTON SWITCH HANDLER SECTION */
/*************************************************************************************************************************/

void handler(Button2& btn) {
  switch (btn.getType()) {
    case long_click:
      myButtonState = ds.ButtonState::longClick;
      Serial.print("---long click ");
      //Serial.print(bf.buttonStatus.buttonState); Serial.print("\t");
    break;

    case double_click:
      myButtonState = ds.ButtonState::doubleclick;
      Serial.print("---double click ");
      //Serial.print(bf.buttonStatus.buttonState); Serial.print("\t");
    break;

    case triple_click:
      myButtonState = ds.ButtonState::tripleClick;
      Serial.print("---triple click");
      //Serial.print(bf.buttonStatus.buttonState); Serial.print("\t");
    break;

  case single_click:
    myButtonState = ds.ButtonState::click;
    Serial.print("---single click");
    //Serial.print(bf.buttonStatus.buttonState); Serial.print("\t");
  break;
  }

  Serial.print(" (");
  Serial.print(btn.getNumberOfClicks());
  Serial.println(")");
}
void FunctionProcessing::buttonSetup() {
  button.begin(ENCODER_SWITCH_PORT,INPUT_PULLUP,false,true); // byte
attachTo, byte buttonMode /* = INPUT_PULLUP */, boolean isCapacitive /* =
false */, boolean activeLow /* = true */

  button.setDebounceTime(50); //
  button.setLongClickTime(500);
  button.setDoubleClickTime(700);

  button.setClickHandler(handler);
  button.setLongClickDetectedHandler(handler); //setLongClickHandler(handler);
  button.setDoubleClickHandler(handler);
  button.setTripleClickHandler(handler);
}

Regards, Rene-Jean

Originally posted by @renejeanmercier in https://github.com/LennartHennigs/Button2/issues/43#issuecomment-1297846614

LennartHennigs commented 1 year ago

Hey @renejeanmercier,

I had a hard time replicating your issue but I did refactor the main loop() and fixed another bug with the LongPress handling.

Please check out 2.2.0 and let me know if your error still persists.

Cheers l.

renejeanmercier commented 1 year ago

Hi Lennart,

Unfortunately the problem persists with the LonngClickDetectedHandler in version 2.2.0.

With the same setup as before with the interrupt, that works great, and the commented behavior (see below). I notice that the first long press results in a single press and a long press after a double press results in a double press. With that information you might be able to pinpoint the problem.

Thank you Lennart for all your help and efforts to get it perfectly working.

I take the occasion to wish you and your family a Merry Christmas and a Great New Year 2023.

Regards,

Rene-Jean

#include "Hardware_Timer.h"

*/**************************************************************************************************************************/*

*/* TO USE STM32DUINO FRAMEWORK TIMER, SEE :*

*https://github.com/stm32duino/STM32Examples/blob/main/examples/Peripherals/HardwareTimer/Timebase_callback_with_parameter/Timebase_callback_with_parameter.ino
<https://github.com/stm32duino/STM32Examples/blob/main/examples/Peripherals/HardwareTimer/Timebase_callback_with_parameter/Timebase_callback_with_parameter.ino>
*/*

HardwareTimer Timer(TIM2);

*/**************************************************************************************************************************/*

void Hardware_Timer::initializeTimerInterrupt() {

Timer.pause(); *// Pause the timer during the configuration*

Timer.setOverflow(TIMER_INTERRUPT_FREQUENCY, HERTZ_FORMAT); *// Desired
period *

Timer.attachInterrupt(button2ServiceIsr); *// Point to the interrupt
routine to be called*

Timer.refresh(); *// Update the parameters*

Timer.resume(); *// Start the timer*

}

*/**************************************************************************************************************************/*

void button2ServiceIsr() { *// Timer interrupt routine (called every
millisecond)*

*// Serial.print("."); // For timer testing purpose*

*// digitalWrite(CLOCK_SAMPLE_PORT, !digitalRead(CLOCK_SAMPLE_PORT)); //
Alternative for timer testing purpose*

button.loop();

}

*/***************************************************************************************************************/*

void Hardware_Timer::buttonSetup() {

button.begin(ENCODER_SWITCH_PORT,INPUT_PULLUP,true); *// byte attachTo,
byte buttonMode /* = INPUT_PULLUP */, boolean activeLow /* = true */*

button.setDebounceTime(50);

button.setLongClickTime(200);

button.setDoubleClickTime(300);

button.setClickHandler(handler);

button.setLongClickDetectedHandler(handler);

*//button.setLongClickHandler(handler);*

button.setDoubleClickHandler(handler);

button.setTripleClickHandler(handler);

}

*/***************************************************************************************************************/*

void handler(Button2& btn) {

int buttonType = btn.getType();

switch(buttonType) {

case single_click:

myButtonState = ds.ButtonState::click;

Serial.print("---single ");

break;

case double_click:

myButtonState = ds.ButtonState::doubleclick;

Serial.print("---double ");

break;

case triple_click:

myButtonState = ds.ButtonState::tripleClick;

Serial.print("---triple ");

break;

case long_click:

myButtonState = ds.ButtonState::longClick;

Serial.print("---long ");

break;

}

Serial.print("click");

Serial.print(" (");

Serial.print(btn.getNumberOfClicks());

Serial.println(")");

}

=====================

Reconnecting to /dev/ttyACM0 . Connected!

Starting MMT Power Supply Interface !!!

EEPROM Beginning : 0

EEPROM End : 16384

Address of eeprom Voltage Output Set : 0

address of eeprom Current Output SET : 4

Address of Shunt Voltage Compensation : 8

Last Voltage Set Value Restored : 3.300

System Voltage Set Value : 3.300

Corresponding DAC Voltage Output : 0.544

Corresponding DAC Binary Voltage Output : 675

Last Current Set Value Restored : 0.500

System Current Set Value : 0.500

Corresponding DAC Current Output : 0.825

Corresponding DAC Binary Current Output : 1023

INA219 Shunt Offset Voltage Value : 0.885

Correction to INA219 Shunt Voltage of : 0.885 mV applied to the calculation

PG set to PG40

---single click (1) ←-------NOT OK--*First** press after power-up and was a
long click*

---long click (1) ←--------OK------*Second press after power-up and was a
long click*

ENTERING SELECTION MODE NORMAL OPERATION

---long click (1) ←--------OK------*Third press after power-up and was a
long click*

Getting out of the Parameter Selection function

ENTERING MODIFICATION MODE

---long click (1) ←--------OK------*Fourth press after power-up and was a
long click*

Preset Value was already the selected value. Value not stored in EEPROM

System Voltage Set : 3.300

Corresponding DAC Voltage Output : 0.54

Corresponding DAC Binary Voltage Output : 675

System Current Set : 0.500

Corresponding DAC Current Output : 0.82

Corresponding DAC Binary Current Output : 1023

Getting out of the Parameter Modificaton function

---double click (2) ←------OK------*Fifth press after power-up and was a
double click*

ENTERING PRESET SELECTION MODE

----Set pointer to the selected window

Set Coordinates To Preset Window

SetCoordinatesToPresetWindow preset3V3

*****Highlight Preset Window

*****Initialize Preset Window

---double click (1) ←-------NOT OK--*Sixth press after power-up and was a
long click*

---long click (1) ←--------OK------*Seventh press after power-up and was a
long click*

Preset Value was already the selected value. Value not stored in EEPROM

System Voltage Set : 3.300

Corresponding DAC Voltage Output : 0.54

Corresponding DAC Binary Voltage Output : 675

System Current Set : 0.500

Corresponding DAC Current Output : 0.82

Corresponding DAC Binary Current Output : 1023
LennartHennigs commented 1 year ago

Hey @renejeanmercier, now I think I understood the problem and was able to reproduce it. Please try out 2.2.1.

I no longer (wrongly) dectect the second or third click of a multi click event as a long click. And I always reset the long click detection, after any other click type is reported.

And also all the best to you and your family and very happy holidays. And: happy tinkering! Cheers l.

renejeanmercier commented 1 year ago

Hi Lennard,

Unfortunately, the LongClickDetected function is completely silent. No action and no message out of the function. The click, doubleClick, tripleClick and longClick are still working fine.

I used your SingleButton.ino model to make sure that I have the same conditions, as you will see below. I also tried longer and shorter setLongClickTime() than the setDoubleClickTime(), ...in case it would have an effect, but none was noticed.

Thank you for your tenacity, perseverance and will !

Best wishes for the New Year coming, and I wish for you and me to have a longClickDetected function working fine in 2023 :-) !!!

Rene-Jean

include "Hardware_Timer.h"

/**/ / TO USE STM32DUINO FRAMEWORK TIMER, SEE : https://github.com/stm32duino/STM32Examples/blob/main/examples/Peripherals/HardwareTimer/Timebase_callback_with_parameter/Timebase_callback_with_parameter.ino / HardwareTimer Timer(TIM2);

/**/ void Hardware_Timer::initializeTimerInterrupt() { Timer.pause(); // Pause the timer during the configuration Timer.setOverflow(TIMER_INTERRUPT_FREQUENCY, HERTZ_FORMAT); // Desired period Timer.attachInterrupt(button2ServiceIsr); // Point to the interrupt routine to be called Timer.refresh(); // Update the parameters Timer.resume(); // Start the timer }

/**/ void button2ServiceIsr() { // Timer interrupt routine (called every millisecond)

// Serial.print("."); // For timer testing purpose // digitalWrite(CLOCK_SAMPLE_PORT, !digitalRead(CLOCK_SAMPLE_PORT)); // Alternative for timer testing purpose button.loop(); }

/***/ void Hardware_Timer::buttonSetup() { button.begin(ENCODER_SWITCH_PORT,INPUT_PULLUP,true); // byte attachTo, byte buttonMode / = INPUT_PULLUP /, boolean activeLow / = true /

button.setDebounceTime(50); button.setLongClickTime(600); button.setDoubleClickTime(500);

button.setClickHandler(click); button.setDoubleClickHandler(doubleClick); button.setTripleClickHandler(tripleClick); //button.setLongClickHandler(longClick); button.setLongClickDetectedHandler(longClickDetected); }

/***/ void click(Button2& btn) { myButtonState = ds.ButtonState::click; Serial.println("---click(1)\n"); }

void doubleClick(Button2& btn) { myButtonState = ds.ButtonState::doubleclick; Serial.println("---double click(2)\n"); }

void tripleClick(Button2& btn) { myButtonState = ds.ButtonState::tripleClick; Serial.println("---triple click(3)\n"); }

void longClickDetected(Button2& btn) { myButtonState = ds.ButtonState::longClick; Serial.println("---long click detected"); }

void longClick(Button2& btn) { myButtonState = ds.ButtonState::longClick; Serial.println("---long click\n"); } ===================================End of text

Le ven. 16 déc. 2022, à 02 h 35, Lennart Hennigs @.***> a écrit :

Hey Rene-Jean, now I think I understood the problem and was able to reproduce it. Please try out 2.2.1.

I no longer (wrongly) dectect the second or third click of a multi click event as a long click. And I always reset the long click detection, after any other click type is reported.

And also all the best to you and your family and very happy holidays. And: happy tinkering!

— Reply to this email directly, view it on GitHub https://github.com/LennartHennigs/Button2/issues/46#issuecomment-1354332104, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGFVP3YT25CPERDN5VANHILWNQLSVANCNFSM6AAAAAART2TZ24 . You are receiving this because you were mentioned.Message ID: @.***>

LennartHennigs commented 1 year ago

Hey, I gave it another shot. Fingers crossed, now, @renejeanmercier!

renejeanmercier commented 1 year ago

Hi Lennart,

Call it SUCCESS !!!!!!!

All functions click, doubleClick, tripleClick, longClick, longClickDetected are WORKING FINE !!!

Thank you so much for your efforts.

Mon amitié vous accompagne !

Joyeuses Fêtes !

René-Jean

Le ven. 16 déc. 2022, à 17 h 57, Lennart Hennigs @.***> a écrit :

Hey, I gave it another shot. Fingers crossed, now, @renejeanmercier https://github.com/renejeanmercier!

— Reply to this email directly, view it on GitHub https://github.com/LennartHennigs/Button2/issues/46#issuecomment-1355753517, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGFVP32UARPNQZBLN5LJP2TWNTXT7ANCNFSM6AAAAAART2TZ24 . You are receiving this because you were mentioned.Message ID: @.***>

LennartHennigs commented 1 year ago

Hey @renejeanmercier,

thank you! You are very welcome. It helped a lot that I refactored the loop code last week.
It was now "merely" a matter of reading the code and looking for the proper place to change things. And in 2.2.1 I had my counts off – thinking helps in many instances ;-).

And thank you again for pointing out the bug and your persistence as well. I will gladly close this bug for good. Have happy holidays and feel free to let me know how your project is going. All the best!

renejeanmercier commented 1 year ago

Hi Lennart,

It was selfish on my part ! LOL. I wanted that function because you don't have to extrapolate thinking that you have pressed the switch long enough.

You did a great job on cleaning your code. Much more modular, much more readable. At first I did not recognize it.

It was a great pleasure exchanging with you and I really enjoyed your feedback each time.

Yes, once finished I will let you know about my project. Lennart, do you have a gmail email ?.

Once more, Merry Christmas.

Regards,

René-Jean

Le sam. 17 déc. 2022, à 03 h 06, Lennart Hennigs @.***> a écrit :

Hey @renejeanmercier https://github.com/renejeanmercier,

thank you! You are very welcome. It helped a lot that I refactored the loop code last week. It was now "merely" a matter of reading the code and looking for the proper place to change things. And in 2.2.1 I had my counts off – thinking helps in my many instances ;-).

And thank you again for pointing out the bug and your persistence as well. I will gladly close this bug for good. Have happy holidays and feel free to let me know how your project is going. All the best!

— Reply to this email directly, view it on GitHub https://github.com/LennartHennigs/Button2/issues/46#issuecomment-1356111927, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGFVP3572HU42O27SRF2FLLWNVX7XANCNFSM6AAAAAART2TZ24 . You are receiving this because you were mentioned.Message ID: @.***>