mathertel / OneButton

An Arduino library for using a single button for multiple purpose input.
http://www.mathertel.de/Arduino/OneButtonLibrary.aspx
Other
920 stars 230 forks source link

Library not working on Nano ESP32 Board #129

Open pietsmar opened 10 months ago

pietsmar commented 10 months ago

Hi,

i am migrating a sketch from Arduino Nano / Nano Every to a Nano ESP32 board and had some challenges (current lib version). The button clicks were not properly recognized. It seems that the button assignment to INPUT_PULLUP does not work correctly. The digitalRead() of the respective Pin switches to 0, if pressed (LOW-active), however, it never goes back to 1 when released.

Maybe it is related to the Pin numbers of the ESP32 and the matching to traditional Nano pins.

A workaround (see line 65) that I found was to add for every used Pin the PinMode (Pin, INPUT_PULLUP) in setup().

`/* This is a sample sketch to show how to use the OneButtonLibrary to detect double-click events on a button. The library internals are explained at http://www.mathertel.de/Arduino/OneButtonLibrary.aspx

Setup a test circuit:

// 03.03.2011 created by Matthias Hertel // 01.12.2011 extension changed to work with the Arduino 1.0 environment

include "OneButton.h"

if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)

// Example for Arduino UNO with input button on pin 2 and builtin LED on pin 13

define PIN_INPUT 2

define PIN_LED 13

elif defined(ESP8266)

// Example for NodeMCU with input button using FLASH button on D3 and using the led on -12 module (D4). // This LED is lighting on output level LOW.

define PIN_INPUT D3

define PIN_LED D4

elif defined(ESP32)

// Example pin assignments for a ESP32 board // Some boards have a BOOT switch using GPIO 0.

define PIN_INPUT 4

// Attach a LED using GPIO 25 and VCC. The LED is on when output level is LOW.

define PIN_LED 13

endif

// Setup a new OneButton on pin PIN_INPUT // The 2. parameter activeLOW is true, because external wiring sets the button to LOW when pressed. OneButton button(PIN_INPUT, true, true);

// In case the momentary button puts the input to HIGH when pressed: // The 2. parameter activeLOW is false when the external wiring sets the button to HIGH when pressed. // The 3. parameter can be used to disable the PullUp . // OneButton button(PIN_INPUT, false, false);

// current LED state, staring with LOW (0) int ledState = LOW;

// setup code here, to run once: void setup() { Serial.begin(115200); delay(2000); Serial.println("One Button Example with polling.");

// enable the standard led on pin 13. pinMode(PIN_LED, OUTPUT); // sets the digital pin as output

// Workaround for ESP32 usage // !!! Without this line the digitalRead() of the Pin never goes back to 1 even if button released !!! pinMode(4, INPUT_PULLUP);

// enable the standard led on pin 13. digitalWrite(PIN_LED, ledState);

// link the Click function to be called on a single click event. button.attachClick(Click); } // setup

// main code here, to run repeatedly: void loop() { // keep watching the push button: button.tick(); Serial.println(digitalRead(PIN_INPUT)); // You can implement other code in here or just wait a while delay(50); } // loop

// this function will be called when the button was pressed 2 times in a short timeframe. void Click() { Serial.println("Click");

ledState = !ledState; // reverse the LED digitalWrite(PIN_LED, ledState); } // doubleClick

// End`

eastwife commented 7 months ago

Did you try the examples?

pietsmar commented 7 months ago

yes, I used the examples as a basis. In the meantime I switched to another library that solved my problem.

JM-FRANCE commented 6 months ago

an hypothesis on why this happens

the library does not implement a begin() function that would actually set the pin mode to INPUT_PULLUP. this is done in the constructor.

In C++ the constructor is called super early, way before main() (let alone setup()) is called

It could be possible that the Nano ESP32 init phase in its main() removes the pullup and just sets all pins to INPUT again.

➜ proper solution would require to implement a begin() method and have the user call begin() in the setup. This would impact all existing examples.

(EDIT: confirmed that by forcing again the PULLUP mode in the setup solves the issue)

zenz commented 4 months ago

an hypothesis on why this happens

the library does not implement a begin() function that would actually set the pin mode to INPUT_PULLUP. this is done in the constructor.

In C++ the constructor is called super early, way before main() (let alone setup()) is called

It could be possible that the Nano ESP32 init phase in its main() removes the pullup and just sets all pins to INPUT again.

➜ proper solution would require to implement a begin() method and have the user call begin() in the setup. This would impact all existing examples.

(EDIT: confirmed that by forcing again the PULLUP mode in the setup solves the issue)

How to forcing again the PULLUP mode in the setup?

JM-FRANCE commented 4 months ago

you add pinMode(buttonPIn, INPUT_PULLUP); in the setup but best would be to add a begin() method to the library that would do so.

wltue commented 4 months ago

It could be possible that the Nano ESP32 init phase in its main() removes the pullup and just sets all pins to INPUT again.

confirmed.

paelzer commented 1 week ago

yes, I used the examples as a basis. In the meantime I switched to another library that solved my problem.

@pietsmar Hi, what is the library you used, to solve your problem? I'm having exact same issue. Boris

pietsmar commented 1 week ago

I am using the Button2 lib.

https://github.com/LennartHennigs/Button2

JM-FRANCE commented 1 week ago

@pietsmar Hi, what is the library you used, to solve your problem? I'm having exact same issue. Boris

If you don’t want to change your code, add pinMode(buttonPIn, INPUT_PULLUP); in the setup

paelzer commented 1 week ago

Thanks a lot, will give it a try :-)