Git Product home page Git Product logo

evert-arias / easybutton Goto Github PK

View Code? Open in Web Editor NEW
438.0 15.0 61.0 364 KB

Arduino library for debouncing momentary contact switches, detect press, release, long press and sequences with event definitions and callbacks.

Home Page: https://easybtn.earias.me

License: MIT License

C++ 100.00%
arduino button pushbutton debounce-button debounce switch touch touch-button arduino-library esp32-arduino

easybutton's Introduction

EasyButton

License

Arduino library for debouncing momentary contact switches, detect press, release, long press and sequences with event definitions and callbacks.

Full documentation available at: https://easybtn.earias.me/docs/introduction

Description

EasyButton is an small Arduino library for debouncing momentary contact switches like tactile buttons. It uses events and callbacks to trigger actions when a button is pressed once or held for a given duration. It also provides a sequence counter to be able to rise an event when a given pattern of presses has been matched.

Installation

https://easybtn.earias.me/docs/installation

How to use

https://easybtn.earias.me/docs/fundamentals

Examples

Single Press

Pressed For Duration

Detecting Sequence

Copyright

MIT © Evert Arias

easybutton's People

Contributors

elc0mpa avatar eppfel avatar evert-arias avatar gutierrezps avatar ingoha avatar kekyo avatar lexelby avatar marcelstoer avatar ncmreynolds avatar offa avatar ssk8 avatar umeshwalkar avatar webmonkey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easybutton's Issues

imput Variable instead of imput Pin

Hi Evert Arias,

Thank you for your nice Lib!

I want to ask if its possible to use the library with a normal Bool Variable
instead of a Hardware Pin? or what kind of modifications are need to be make this work?

like instead of "EasyButton button(BUTTON_PIN);"

for example "EasyButton button(BOOL_VARIABLE);"

Unexpected behavior

I am surprised by the results I am getting when defining multiple duration and sequence calls. Is this really the intended behavior of this lib?

This is the preogram, modified from your example:

    /*
     * MODIFIED from:
      Name:    MultipleSequence.ino
      Created:  03/23/2020 12:45:23 AM
      Author: José Gabriel Companioni Benítez (https://github.com/elC0mpa)
      Description: Example to demostrate how to work with multiple sequences 
    */
    
    #include <Arduino.h>
    #include <EasyButton.h>
    
    // Arduino pin where the button is connected to.
    #define BUTTON_PIN 0
    
    #define BAUDRATE 115200
    
    void onPressed()        {  Serial.println("Button pressed");}
    void onPressedFor2000() {  Serial.println("Button pressed for duration 2000"); }
    void onPressedFor5000() {  Serial.println("Button pressed for duration 5000"); }
    void DuoClick()         {  Serial.println("Double click"); }
    void TripleClick()      {  Serial.println("Triple click"); }
    void QuattroClick()     {  Serial.println("Quattro click");}
    
    // Instance of the button.
    EasyButton button(BUTTON_PIN);
    
    void setup()
    {
      // Initialize Serial for debuging purposes.
      Serial.begin(BAUDRATE);
    
      Serial.println();
      Serial.println(">>> EasyButton multiple onSequence example <<<");
    
      // Initialize the button.
      button.begin();
    
      button.onPressed(onPressed);
      button.onPressedFor(2000, onPressedFor2000);
      button.onPressedFor(5000, onPressedFor5000);
      button.onSequence(2, 1500, DuoClick);
      button.onSequence(3, 2500, TripleClick);
      button.onSequence(4, 3500, QuattroClick);
    }
    
    void loop()
    {
      // Continuously read the status of the button.
      button.read();
    }

The result is the following:

Pressing the button for 10 sec. After 5sec this is printed:

    Button pressed for duration 5000

I'd expect the print would occur only after 10 sec, but so far ok. Now I press the button for 3 sec:

    Button pressed

I'd expect the callback for duration 2000 to fire, but this actually never shows up.

Now I am pushing the button 4 times within 1 sec. This is the result:

    Button pressed
    Button pressed
    Double click
    Button pressed
    Triple click
    Button pressed
    Double click
    Quattro click

So, I am getting 4 single button presses, 2 double presses, 1 triple press and 1 quattro press, while all I was wanting was 1 quattro press.

Effectively I have only two options: one single press, plus one long press. Everything else cannot be distinguished. Am I doing something wrong, or is that really intended?

Multiple buttons with Callback per button

I need some help and are not sure if I am doing this correctly.

I am trying to use 2 buttons with different callbacks for the onPressed defined for each button.
When any of the buttons are pressed both callback's are invoked.

See code below:

int timerPin = 0;
int resetPin = 13;

EasyButton timerButton(timerPin);
EasyButton resetButton(resetPin);

void onTimerPressed() {
Serial.println("Timer Pressed);
};

void onResetPressed() {
Serial.println("Reset Pressed");
};

void setup() {

Serial.begin(9600);
timerButton.begin();
timerButton.onPressed(onTimerPressed);

resetButton.begin();
resetButton.onPressed(onResetPressed);
}

void loop() {
timerButton.read();
resetButton.read();
}

Error with Digistump/attiny85 compiling

Error with Digistump/attiny85 compiling. Any suggest? Thanks!

C:\Users\utente\Documents\Arduino\libraries\EasyButton\src\EasyButton.cpp: In member function 'bool EasyButton::supportsInterrupt()':
C:\Users\utente\Documents\Arduino\libraries\EasyButton\src\EasyButton.cpp:99:36: error: 'digitalPinToInterrupt' was not declared in this scope
return (digitalPinToInterrupt(_pin) != NOT_AN_INTERRUPT);
^
C:\Users\utente\Documents\Arduino\libraries\EasyButton\src\EasyButton.cpp: In member function 'void EasyButton::enableInterrupt(EasyButtonBase::callback_t)':
C:\Users\utente\Documents\Arduino\libraries\EasyButton\src\EasyButton.cpp:104:44: error: 'digitalPinToInterrupt' was not declared in this scope
attachInterrupt(digitalPinToInterrupt(_pin), callback, CHANGE);
^
C:\Users\utente\Documents\Arduino\libraries\EasyButton\src\EasyButton.cpp: In member function 'void EasyButton::disableInterrupt()':
C:\Users\utente\Documents\Arduino\libraries\EasyButton\src\EasyButton.cpp:110:44: error: 'digitalPinToInterrupt' was not declared in this scope
detachInterrupt(digitalPinToInterrupt(_pin));
^
C:\Users\utente\Documents\Arduino\libraries\EasyButton\src\EasyButtonBase.cpp: In member function 'void EasyButtonBase::_checkPressedTime()':
C:\Users\utente\Documents\Arduino\libraries\EasyButton\src\EasyButtonBase.cpp:71:23: error: range-based 'for' loops are not allowed in C++98 mode
for (Sequence seq : _sequences)
^

Joystick / ThumbPad support, where button can have both low and high values

Hi, I was woundering how to use your library to work with joystick buttons. They have basically x2 10K resistors, so values from analog read goes something like this:

  • Left-Right/Top-Down:
Left Middle Right
0 1850-1900 4096
  • Joystick press:
Pressed Default
0 800-1300

I've tried both Pull_down and Pull_up for the corresponding pins, but values are the same.

Is there any way how I can define (ideally with interrupts) buttons that have both high and low values ? Or define max/min value ?

I'm using ESP32 DEV and Joystick Like this

Thank you.

Multiple onPressedFor

Hi,
I would like to do something like this with the same button:

button.onPressedFor(1000, showIP); button.onPressedFor(3000, restartDevice);

so execute two different callback based on the pressing duration. It doesn't work for me. Just the last function is called.
Any idea?

Thank you so much,
Francesco

Filter.h not found on v2.0.3. Failed to compile

Hello.
First of all, thank you for your great job with this library.

I have been using this library on my project but now it throws a compilation error since v2.0.3:

In file included from .pio/libdeps/wemos_d1_mini32/EasyButton/src/EasyButtonTouch.cpp:9:
.pio/libdeps/wemos_d1_mini32/EasyButton/src/EasyButtonTouch.h:14:10: fatal error: Filter.h: No such file or directory
...
...
 #include <Filter.h>
          ^~~~~~~~~~
compilation terminated.
*** [.pio\build\wemos_d1_mini32\libe3f\EasyButton\EasyButtonTouch.cpp.o] Error 1

The same code compiles good on v2.0.1.
I am almost sure it is not an error on my environment because I run a before the compilation.
Also the MegunoLink dependency is resolved with [email protected]

My env:

  • PlatformIO
  • Board: Wemos_D1_miniESP32
  • Framework: Arduino

Best regards.

a triple click triggers callbacks for double and single clicks as well

When I triple click the button, it also fires events "below", that is to say event for double click and even for single click. How do I avoid that? I want the code to only fire the triple click event.

Example :

[...]
#include <EasyButton.h>

const uint8_t calibrationButtonPin = 1;
EasyButton calButton(calibrationButtonPin, 40, false, false);

[...]

void setup() {
  [...]
  calButton.begin();
  calButton.onPressed(singleClick);
  calButton.onSequence(2, 1500, doubleClick);
  calButton.onSequence(3, 2500, tripleClick);
  calButton.onPressedFor(1500, longClick);
  if (calButton.supportsInterrupt())
  {
    calButton.enableInterrupt(buttonISR);
    Serial.println("calButton will be used through interrupts");
  }
  [...]
}

void loop() {
  [...]
  calButton.update();
  [...]
}

void singleClick()
{
  Serial.println("Button pressed");
}

void doubleClick()
{
  Serial.println("Double click");
}

void tripleClick()
{
  Serial.println("Triple click");
}

void longClick()
{
  Serial.println("Long click");
}

void buttonISR()
{
  calButton.read();
}

On triple click, the serial monitor will print the following :

Button pressed
Button pressed
Double click
Button pressed
Triple click

Compile errors in MultipleButtons.ino

HI @evert-arias !

I'm getting the following error when compiling the example MultipleButtons.ino

\Arduino\libraries\EasyButton\src\EasyButton.cpp: In member function 'void EasyButton::enableInterrupt(EasyButton::callback_t)':

\Arduino\libraries\EasyButton\src\EasyButton.cpp:174:63: error: cannot convert 'EasyButton::callback_t {aka std::function<void()>}' to 'void (*)()' for argument '2' to 'void attachInterrupt(uint8_t, void (*)(), int)'

  attachInterrupt(digitalPinToInterrupt(_pin), callback, CHANGE);

                                                               ^
exit status 1
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.

This happens both in Arduino IDE v1.8.9 and PlatformIO (VSC)

solve the Filter.h not found problem

I open this new issue just for convenient, help the people who can find the solution immediately.
I use Platformio, and install the EasyButton2.0.3 library through the Platformio library installation:
image

I find that there is another library which named MegunoLink will also installed too. Because MegunoLink library is the depends of EasyButton2.0.3, as we can see from the library.properties file of EasyButton2.0.3:
image

We can find the Filter.h file in the library folder of MegunoLink/src, so just copy it to the library foler of EasyButton\src, the problem solved.
Or just unzip the Filter.zip below, get Filter.h file, and copy Filter.h into your EasyButton\src folder.
Filter.zip

Multiple .onSequence for a unique button

Hi ! First, thank you for this great library. It's make easier the button handling on my arduino projet.

I tried to use multiples sequences for a unique button but only the last declaration works. I know it's hard to implement but do you think you can could handle more than one event for a unique button ?

For example, with a 2000 timeout, you could run a callback if you press one time, and a different callback if you press 2 ou 3 times.

I think it would be great for doing some "settings menu".
But anyway, your library is already great :)

ESP32-C3 does not support Touch

Overview

In file where is defined support for Touch there is check if Micro Controller is ESP32:

#if defined(ESP32)

How ever ESP32-C3 include this flag but also does not support Touch what causes error on build.

Solution

So this check should be more precise excluding this MC.

Temp Solution

If you have project on ESP32-C3 you can just write in this line #if false or remove files ended with *Touch.cpp.

Some links

ESP32 Comparison
Full ESP32 Datasheets

#define INTERRUPT 0

please remove the line "#define INTERRUPT 0"
it interferes with other Liberiers , and does not serve any purpose.

e.g.: espressif\esp32/tools/sdk/include/esp32/xtensa/config/specreg.h --> " #define INTERRUPT 226"

vButton with MCP23017

Hello,
I wanted to try the vButton function on a button connected to an MCP23017 I/O Expander and. The MCP23017 is connected to an atmega328p. Unfortunately, no matter what I try, I can't get the code running. And I can't find any example code for it either.
For the MCP23017 I used the Adafruit_MCP23X17.h library!

Has anyone done this before and can help me?

Thanks!

onPressedForDuration not waiting for set duration?

Hi there.

I wired my test Arduino Pro Mini as follows:
image

When I run the onPressedForDuration() example (running on EasyButton v1.2.0)

#include <EasyButton.h>

// Arduino pin number where the button is connected.
#define BUTTON_PIN 9

// Duration.
int duration = 3000;

// Button.
EasyButton button(BUTTON_PIN);

// Callback.
void onPressedForDuration() {
  Serial.println("Button has been pressed for the given duration!");
}

void setup() {
  Serial.begin(9600);
 
  // Initialize the button.
  button.begin();

  // Attach callback.
  button.onPressedFor(duration, onPressedForDuration);
}

void loop() {
  // Continuously update the button state.
  button.read();
}

As soon as I press the button, I get "Button has been pressed for the given duration!", although I set duration to 3000.

Any suggestion?

Thanks!

Enhancement: Periodic callback when button is held down

My use case is for a light switch that normally functions as a momentary switch, but acts as a dim up/dim down switch when it is held for more than 250ms.

So to achieve this I have attached a function for the onPressedFor callback


I would then like another function to be called back every 50 ms so the lighting can be ramped up or down
````    powerButton.onPresseContinuesr(50, keepDimming); // notify the dimmer to move down a level

I have made some changes to a fork of the code. Are you interested in reviewing them for a pull request ?

Reading buttons in for loop

hi i created array of EasyButton objects button[] and i initialize them in for loop and it works fine but when i try to update their state by button[i].read()
its not working and buttons dont react to being pressed

nrf52 'NOT_AN_INTERRUPT' was not declared in this scope

Hi there.
Issue: When using EasyButton > 1.02 compilation failure with Adafruit nrf52 BSP
Using https://github.com/adafruit/Adafruit_nRF52_Arduino BSP.

Arduino 1.8.13
nrf52 BSP versions affected 0.70 - 0.21.0 (All)

Works on all versions: Easybutton 1.0.2
Fails: 1.1.0 up to and including 2.0.1

Error produced:
C:\Users\User\Documents\Arduino\libraries\EasyButton\src\EasyButton.cpp: In member function bool EasyButton::supportsInterrupt(): C:\Users\User\Documents\Arduino\libraries\EasyButton\src\EasyButton.cpp:139:41: error: NOT_AN_INTERRUPT was not declared in this scope 139 | return (digitalPinToInterrupt(_pin) != NOT_AN_INTERRUPT);

Error compiling for board Nordic nRF52840DK (PCA10056).

in EasyButton.cpp:
bool EasyButton::supportsInterrupt() { return (digitalPinToInterrupt(_pin) != NOT_AN_INTERRUPT); }

references:
C:\Users\User\AppData\Local\Arduino15\packages\adafruit\hardware\nrf52\0.21.0\cores\nRF5\Arduino.h

contains

#define digitalPinToInterrupt(P) ( P )

Any ideas?

Edited:
Compiles after adding to EasyButton.h
#define NOT_AN_INTERRUPT -1

Is this a vaild workaround as it seems NOT_AN_INTERRUPT -1 is Arduino 1.6 Legacy?

A note on the example of Interrupts, solve "Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)"

For the example of Interrupts, namely, the code in EasyButton\examples\Interrupts, I must add some time consuming code or a delay in loop(), such as:
image

The code can avoid the error: Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
1

If I do not add some time consuming code or a delay in loop(), namely, use a very short code instead, such as
digitalWrite(13, HIGH);
the error above can not be solved by the non-time consuming code.

I don't know why, I tested all afternoon and obtained the above conclusion.

P.S. My board are esp32 and esp32-s3, I test both of them.

Error example simple button with interrupt in ESP32.

Hi, I am testing the library to include it in a larger project and replace my rudimentary library to use short press and long press on various buttons. But after compiling and uploading the example code to my ESP32 with VScode, I get this error. I use the single button example with interrupt and my ESP32 is made by doit, esp-wroom-32 devkit v1.

#include <Arduino.h>
#include <EasyButton.h>

const uint8_t BOTON_ONOFF=23;

#define BAUDRATE 115200

// Instance of the button.
EasyButton button(23);

void IRAM_ATTR buttonPressed()
{
  Serial.println("Button pressed");
}


void IRAM_ATTR buttonISR()
{
  button.read();
}

void setup()
{

  // Initialize Serial for debuging purposes.
  Serial.begin(BAUDRATE);

  Serial.println(">>> EasyButton interrupts example <<<");

  // Initialize the button.
  button.begin();

  button.onPressed(buttonPressed);

  if (button.supportsInterrupt())
  {
    button.enableInterrupt(buttonISR);
    Serial.println("Button will be used through interrupts");
  }
}

void loop()
{
  // put your main code here, to run repeatedly:
  void(10);
}

Button pressed
Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). 

Core  1 register dump:
PC      : 0x4008a3b6  PS      : 0x00060b35  A0      : 0x8008960a  A1      : 0x3ffbec9c  
A2      : 0x3ffb8a00  A3      : 0x3ffb8890  A4      : 0x00000004  A5      : 0x00060b23  
A6      : 0x00060b23  A7      : 0x00000001  A8      : 0x3ffb8890  A9      : 0x00000018  
A10     : 0x3ffb8890  A11     : 0x00000018  A12     : 0x3ffc1894  A13     : 0x00060b23  
A14     : 0x007bee88  A15     : 0x003fffff  SAR     : 0x00000017  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x400860f9  LEND    : 0x40086109  LCOUNT  : 0xfffffffc  
Core  1 was running in ISR context:
EPC1    : 0x400d9a43  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x00000000


Backtrace:0x4008a3b3:0x3ffbec9c |<-CORRUPTED


Core  0 register dump:
PC      : 0x4008a537  PS      : 0x00060035  A0      : 0x80089233  A1      : 0x3ffbe7dc
A2      : 0x3ffbee88  A3      : 0xb33fffff  A4      : 0x0000abab  A5      : 0x00060023
A6      : 0x00060021  A7      : 0x0000cdcd  A8      : 0x0000abab  A9      : 0xffffffff
A10     : 0x3ffc16a0  A11     : 0x00000000  A12     : 0x3ffc169c  A13     : 0x00000007
A14     : 0x007bee88  A15     : 0x003fffff  SAR     : 0x0000001a  EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000


Backtrace:0x4008a534:0x3ffbe7dc |<-CORRUPTED




ELF file SHA256: 0000000000000000

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_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:12784
load:0x40080400,len:3032
entry 0x400805e4```

MCP 23017 Additional Inputs

Thank you for this library it has made my introduction to ESP and Arduino a lot easier.

I have found myself in need of more inputs, I was surprised at how many inputs cant be used on the ESP boards even on the larger version.

Hence I am now looking into the MCP23017 to get more and allow futher development for both inputs and outputs.

I have tried to read through and see if there is anyone using easy button on these exspansion boards and may be jumping the gun as my board has not arrived yet but can easy button define inputs from the 23017 easily.

I am going to have a play around and probably try using the adafruit library along with the wire library to see if its possible to mix and match the #define. Not sure if thats the way or just wake the bus and try to define the buttons manually before mapping them to easy button.

I am using the single press and pressed for part of easy button for the reading of the button presses and really dont want to lose that.

Thanks for any help

Error using library

I get the following error message

EasyButtonTouch.cpp:21:23: error: 'touchRead' was not declared in this scope
return touchRead(_pin) < _touch_threshold;

while trying to verify the code in Arduino/VSCode IDE. This happens whether the board is Arduino Uno or ESP8266

Using EasyButton with Low-Power

Hi there!

This is not an issue per-se, but I need your help clarifying this.

Currently I'm working on an irrigation project with Arduino. This setup is stand-alone, no connections to external apps or servers. This is challenging since I have buttons for:

  • button 1: enter programming mode while pressed
  • button 2: while on programming mode, switch from max moisture to min (swap values shown on LED display)
  • button 3: increment value
  • button 4: decrement value

Since I'm going to use a low power library to manage sleep modes and stuff, I also need a way to manually awake the device from sleep. I thought about using another button but that would be too much, so I came across PressedForDuration example from your library. I was wondering if I could use button 1 for waking up the Arduino (one press) and enter programming mode if pressed for 2-3 secs?

I order to wake it up, I need to use something like this:
https://github.com/rocketscream/Low-Power/blob/master/Examples/powerDownWakeExternalInterrupt/powerDownWakeExternalInterrupt.ino

My questions is, could I make both your library and Low Power work together? My main concern is having a button doing two things and working with different level (HIGH to enter programming mode, LOW to generate an interrupt and wake the board from sleep)

Thanks in advance with your help!

Jose

Feature request: Reset pressed time.

I have a case where I am using two buttons.
I am using "pressedFor" to trigger long press and if i press both buttons I can get an "extra" long press function.
My issue is that when i release one of the buttons, the other one triggers my "single button long press".
A function to reset the pressed time of the "other" button would force the "other" button to wait the whole allotted time again before pressedFor returns true.

Example:

void EasyButtonBase::resetTime()
{
	_last_change = millis();
} 

Thanks for a good, usable library!

Interrupt operation is unstable

When using interrupts the MCU will randomly hang and/or reset. Probably this is due to the global variables accessed by the read() function are not declared as volatile.

spurious pressed-for events

Hi! Thanks for writing this, it's designed to do exactly what I want.

I noticed a weird issue where mashing on the button seems to cause spurious pressed-for events. I set my debounce time to 50ms and the pressed-for duration to 5000ms.

I did a bunch of debugging and determined that when one of these spurious pressed-for events happens, _last_change is less than _time -- always by one ms. Since they're unsigned ints, subtracting them results in a huge numbers, so the test for a "pressed for" event passes and the callback is called.

It's late and I haven't managed to dig all the way through the logic to figure out what's happening but updating _time at the start of read() right after read_start_ms = millis() seems to fix the problem.

Pressed example does not work with new Arduino Nano ESP32 board

I posted an inquiry at:
https://forum.arduino.cc/t/easybutton-library-sample-code-does-not-work/1155696

The standard pressed.ino example throws exceptions:

In file included from /Users/jjs/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/cores/esp32/Arduino.h:223,
                 from /private/var/folders/6v/1p1396h55_72kp8gnv3gsnv00000gq/T/arduino/sketches/9AF4919C475D15D2FB9CC92B2D1DAFB4/sketch/Pressed-Nano-ESP32.ino.cpp:1:
/Users/jjs/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/cores/esp32/io_pin_remap.h:44:69: error: variable or field 'attachInterrupt' declared void
 #define attachInterrupt(pin, fcn, mode)             attachInterrupt(digitalPinToGPIONumber(pin), fcn, mode)
                                                                     ^~~~~~~~~~~~~~~~~~~~~~
/Users/jjs/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/cores/esp32/FunctionalInterrupt.h:18:6: note: in expansion of macro 'attachInterrupt'
 void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode);
      ^~~~~~~~~~~~~~~
/Users/jjs/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/cores/esp32/FunctionalInterrupt.h:18:30: error: expected primary-expression before 'pin'
 void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode);
                              ^~~
/Users/jjs/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/cores/esp32/io_pin_remap.h:44:92: note: in definition of macro 'attachInterrupt'
 #define attachInterrupt(pin, fcn, mode)             attachInterrupt(digitalPinToGPIONumber(pin), fcn, mode)
                                                                                            ^~~
/Users/jjs/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/cores/esp32/FunctionalInterrupt.h:18:61: error: expected primary-expression before 'intRoutine'
 void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode);
                                                             ^~~~~~~~~~
/Users/jjs/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/cores/esp32/io_pin_remap.h:44:98: note: in definition of macro 'attachInterrupt'
 #define attachInterrupt(pin, fcn, mode)             attachInterrupt(digitalPinToGPIONumber(pin), fcn, mode)
                                                                                                  ^~~
/Users/jjs/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/cores/esp32/FunctionalInterrupt.h:18:73: error: expected primary-expression before 'int'
 void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode);
                                                                         ^~~
/Users/jjs/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/cores/esp32/io_pin_remap.h:44:103: note: in definition of macro 'attachInterrupt'
 #define attachInterrupt(pin, fcn, mode)             attachInterrupt(digitalPinToGPIONumber(pin), fcn, mode)
                                                                                                       ^~~~

exit status 1

Compilation error: exit status 1

Feature request: onReleasedFor()

Hi!

thank you very much for this library!
I try to get an event, after the button was released after a long press.
I tried it in that way but without success:

button.read();
  if(button.wasReleased() && button.pressedFor(2000)) {
    Serial.println("Button was released after a long press!");
  }

What I looking for is actually something like:
onReleasedFor(2000)

Do you have an idea how to do that?
Thanks, André

Long button press issues

I'm trying out this library, but having issues, mainly with the long press function.

When the code starts, it almost instantly detects a long press. I have tried adding a delay (2 seconds) at startup, prior to initializing the button, but it still happens.

I also would like to have the button as dual-function (short & long press). When using both functions, both short & long press triggers the long press function. The code below is the current version, which only triggers the long press function.

`#include <EasyButton.h>

// pin assignments
const byte
btnHeatPin(2); //D2

#define LongPress 2000

EasyButton btnHeat(btnHeatPin);

void btnHeatShortPress() {

Serial.println("Button Heat short press");
}

void btnHeatLongPress() {
Serial.println("Button Heat long press");
}

void setup() {
Serial.begin(9600);
Serial.println("Startup");
btnHeat.begin();
btnHeat.onPressedFor(LongPress, btnHeatLongPress);
btnHeat.onPressed(btnHeatShortPress);
}

void loop() {
btnHeat.read();
}`

ESP32 compilation issues

I'm trying to implement EasyButton on an ESP32 project, but I'm receiving errors during compiling. I'm using pin D14, which has PULLUP enabled.

Code:
`#include <EasyButton.h>

// pin assignments
const byte
btnHeatPin(14);

#define LongPress 2000

EasyButton btnHeat(btnHeatPin);

void btnHeatShortPress() {

Serial.println("Button Heat short press");
}

void btnHeatLongPress() {
Serial.println("Button Heat long press");
}

void setup() {
Serial.begin(9600);
Serial.println("Startup");
btnHeat.begin();
btnHeat.onPressedFor(LongPress, btnHeatLongPress);
btnHeat.onPressed(btnHeatShortPress);
}

void loop() {
btnHeat.read();
}`

Error message:
`Arduino: 1.8.10 (Windows 10), Board: "DOIT ESP32 DEVKIT V1, 80MHz, 921600, None"

C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton-2019-09-01_06-58-44-272.cpp: In member function 'void EasyButton::onPressed(EasyButton::callback_t)':

C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton-2019-09-01_06-58-44-272.cpp:21:2: error: 'mPressedCallback' was not declared in this scope

mPressedCallback = callback;

^

C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton-2019-09-01_06-58-44-272.cpp: In member function 'void EasyButton::onPressedFor(uint32_t, EasyButton::callback_t)':

C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton-2019-09-01_06-58-44-272.cpp:26:2: error: 'mPressedForCallback' was not declared in this scope

mPressedForCallback = callback;

^

C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton-2019-09-01_06-58-44-272.cpp: In member function 'void EasyButton::onSequence(uint8_t, uint32_t, EasyButton::callback_t)':

C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton-2019-09-01_06-58-44-272.cpp:33:2: error: 'mPressedSequenceCallback' was not declared in this scope

mPressedSequenceCallback = callback;

^

C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton-2019-09-01_06-58-44-272.cpp: At global scope:

C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton-2019-09-01_06-58-44-272.cpp:66:6: error: prototype for 'bool EasyButton::read()' does not match any in class 'EasyButton'

bool EasyButton::read() {

  ^

In file included from C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton-2019-09-01_06-58-44-272.cpp:8:0:

C:\Users\Owner\Documents\Arduino\libraries\EasyButton\src\EasyButton.h:38:7: error: candidate is: bool EasyButton::read(int)

bool read(int read_type = POLL); // Returns the current debounced button state, true for pressed, false for released.

   ^

Multiple libraries were found for "EasyButton.h"
Used: C:\Users\Owner\Documents\Arduino\libraries\EasyButton
exit status 1
Error compiling for board DOIT ESP32 DEVKIT V1.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
`

Enhancement: instance pointer in callbacks

Devices often contain multiple buttons, the one I'm dealing with has 6. The easiest way to model these is in an array.

In a device with multiple buttons the code can get pretty unwieldy if you need to attach 3 callbacks to each of the 6 buttons, that's 18 functions to write, maintain and understand.

Is there a simple way to detect which button has fired the callback e.g. like "this" is javascript, c#, "self" in Delphi Pascal etc ?
void onPressed(button this) { Serial.println("Button x has been pressed!"); }

Clarify in Docs what INTERUPT is

The documentation is fantastic, the best I've ever seen.

On this page there is documentation on how to enable interupts

https://easybtn.earias.me/docs/fundamentals
Screen Shot 2022-08-09 at 7 58 07 PM

Yet its not clear what INTERUPT should be.

Should INTERUPT be the pin on the arduino? ❌

void buttonISR()
{
  button.read(2); 
}

Should INTERUPT be the Interupt name on the arduino? ❌

void buttonISR()
{
  button.read(INT.1); 
}

https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Should INTERUPT be the string litteral 'INTERUPT' ? ❌

void buttonISR()
{
  button.read(INTERUPT); 
}
src/main.cpp:91:15: error: 'INTERUPT' was not declared in this scope

Sorry if this is a beginner question. If I'm running into this obstacle, most likely someone else is too.

MyCustomLibrary function can´t use callback

To declare a callback is used

void onPressedCallback()
{
   //FUNCTION
}

button.onPressed(onPressedCallback);

But if I using the library inside a class, is not possible use a function inside my library

button.onPressed(MYCUSTOMLIBRARY::onPressedCallback);

or

button.onPressed(this->onPressedCallback);

I change the line 27 of file EasyButton.h

Before

typedef void(*callback_t)();

After

typedef void (*callback)();

And work with mycustomlibrary! I don´t now how to make a Pull Request for this correction, someone helpme? Or @evert-arias

v2 branch removal of begin() may be problematic

Constructors for c++ objects may run before frameworks on platforms like esp8266 and esp32 are fully initialized. Typically this is why begin() is used. I noticed this while looking for a solution for INTERRUPT being redefined in the current release on esp32.

Press duration

Hey,

I'm not seeing much activity, reason why I did not submit a PR straight away.
Is this codebase still maintained?

I'd like to make a suggestion to fetch how long the button has been pushed from within onPressed's callback.
Reason is I'd like to have a button with different actions if it's pressed for 1, 2, x seconds.

Thank you

too complicated documentation

the problem in understanding occured when reading invert and pullup resistors section.

Should use simple wordings, the wordings are not elaborating the function clearly, also elaborate more in a keep it short simple (KISS) manner. Also should be clear and concise.

vButton.onPressedFor issue

Hi I have used the example in the library examples to test the Vbutton code.

I am using esp8266 (12e) and a MCP23017 non interupt

I have tried both with a library for the 23017 and also direct register coding and I get the same result when trying to use on pressed for.

As soon as I add the vButton.onPressedFor(2000, buttonPressedForTwoSeconds); into the code then that it pretty much all you will get.

There is not really any single press anymore. As soon as you do a single press there is a slight delay and then the callback for onpressed for runs and not the single press.

I have no problem running on the Internal GPIO pins on the esp but using a 23017 and the Vbutton for io ports gives me this issue.

I have displayed the bool to see if it was holding an incorrect state but that it all fine.

It just seems to be as soon as you add in the pressed for it only uses that.

Has anyone else done a physical test that may be able to help.

Thanks

Delay in Reading

Here is my code below. I am using the Easybutton library for reading the button state. Problem is that in the loop function, even when I press my button for 2 seconds, it does not detect that and takes more time to detect, and even the detection is unreliable. I am sure there is a problem in my code, just can't figure it out. Please help.

Platform : NodeMCU
IDE : Arduino

Does onPressed() have higher priority over onPressedFor()?

//...
void onButton3Pressed(){
//...
}
void button3PressedFiveSeconds(){
//...
}
void button3ISR() {  button3.read(INTERRUPT); }

void setup(){
//...
button3.begin();
button3.onPressedFor(5000, button3PressedFiveSeconds);
button3.onPressed(onButton3Pressed);
//...
if (button3.supportsInterrupt())
  button3.enableInterrupt(button3ISR);
}
void loop(){}

I pressed button3 for more than 5 seconds and then released it, onPressed() responsed instead of onPressedFor().

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.