mathertel/OneButton

In the special input example, is it correct that click is fired first?

pruge opened this issue · 6 comments

pruge commented

The click event is fired as soon as the system starts.
This is an unintentional click event. Is this correct behavior?

I'm using an ESP32 board.

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13232
load:0x40080400,len:3028
entry 0x400805e4
One Button Example with custom input.
Click:me // <-- ???

Same here.

Adding a 100ms delay and a counter to the example code shows that the click event occurs within 300ms, perhaps related to debounce state changes?

unsigned int counter = 0;
void loop() {
  // read your own source of input:
  bool isPressed = (digitalRead(PIN_INPUT) == LOW);

  // call tick frequently with current push-state of the input
  button->tick(isPressed);

  Serial.println(counter);
  counter++;
  delay(100);
}  
*  Executing task: platformio device monitor --environment megaatmega2560 

--- Terminal on /dev/ttyUSB0 | 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
0
1
2
Click:me
3
4

Thanks for your work :)

wltue commented

Same here, tried to force tick in high or low state before running loop. Always fires click.
Tried on UNO, Zero, Arduino ESP32 Nano.

wltue commented

Anyone has a (temp) fix for this?

I've investigate a little bit in this issue, and it seems to be related to the -1 initialized value of debouncedPinLevel. Set this value to 0 fix this issue (OneButton.h#L244, idk if there are any side effects):

int debouncedPinLevel = 0;

I think this is related to the debounce timer, when the timer reaches the debounce value the activityLevel goes from -1 to 0, which is deterministic in the first step of the _fsm():

case OneButton::OCS_INIT:
    ...
    if (activeLevel) { // -1 trigger this condition !!!!
      _newState(OneButton::OCS_DOWN);
      ...
    }
    break;

Here is my troubleshooting setup:

  • 50ms delay in loop()
  • Serial.print each states inside the _fsm()
  • Serial.print activeLevel inside tick(bool activeLevel)
log before the patch
--- Terminal on /dev/ttyUSB0 | 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
activeLevel: -1
OCS_INIT
activeLevel: -1
OCS_INIT
activeLevel: -1
OCS_INIT
activeLevel: -1
OCS_INIT
activeLevel: -1
OCS_INIT
activeLevel: -1
OCS_INIT
activeLevel: -1
OCS_INIT
activeLevel: -1
OCS_INIT
activeLevel: 0
OCS_DOWN
activeLevel: 0
OCS_DOWN
activeLevel: 0
OCS_DOWN
activeLevel: 0
OCS_DOWN
activeLevel: 0
OCS_DOWN
activeLevel: 0
OCS_DOWN
activeLevel: 0
OCS_DOWN
activeLevel: 0
OCS_DOWN
activeLevel: 0
OCS_UP
activeLevel: 0
OCS_UP
activeLevel: 0
OCS_UP
activeLevel: 0
OCS_UP
activeLevel: 0
OCS_UP
activeLevel: 0
OCS_UP
activeLevel: 0
OCS_UP
activeLevel: 0
OCS_UP
activeLevel: 0
OCS_COUNT
activeLevel: 0
OCS_COUNT
activeLevel: 0
OCS_COUNT
activeLevel: 0
OCS_COUNT
activeLevel: 0
OCS_COUNT
activeLevel: 0
OCS_COUNT
activeLevel: 0
OCS_COUNT
activeLevel: 0
OCS_COUNT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
log after the patch
--- Terminal on /dev/ttyUSB0 | 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
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
OCS_INIT
activeLevel: 0
wltue commented

My temp solution was:

`/* callbacks Button 1 */

void callback_Class_OneButton_BUTTON1_click()
{
// Bug in One Button library Version 2.5.0, first call is a dud
if (variable_Button1_firstclick == false)
{
variable_Button1_firstclick = true;
return;
}
`

But your solution @XavierBrassoud
int debouncedPinLevel = 0;

Seems to work fine.
Thank you.

Please retest with the current version.