Coder Social home page Coder Social logo

mathertel / onebutton Goto Github PK

View Code? Open in Web Editor NEW
928.0 928.0 230.0 149 KB

An Arduino library for using a single button for multiple purpose input.

Home Page: http://www.mathertel.de/Arduino/OneButtonLibrary.aspx

License: Other

C++ 99.65% Shell 0.35%
arduino arduino-library button

onebutton's Introduction

onebutton's People

Contributors

arjenbreur avatar bjrnptrsn avatar caveman99 avatar cheese2611 avatar cogito666 avatar eiwi1101 avatar florianbeck avatar idolpx avatar ihornehrutsa avatar ivankravets avatar jakobglieder avatar kigster avatar mathertel avatar mattallen37 avatar mkinney avatar nicolaivr avatar nielsvandepas avatar per1234 avatar pheipheiphei avatar s4mw1s3 avatar sbonaime avatar scls19fr avatar trantuananh1996 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  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

onebutton's Issues

2 buttons together

hello forks

i am working on one small project & i want to run 2 button code together i attached my code here. it was like when button 1 print something with small delay and suddenly i press button 2 its not working. i just want print that button 2 thing when button 1 print something.

I dont have any coding experience so if it easy sorry for issue..

have a nice day my friends
HELLO WORLD.TXT

Debounce tick times

Hello

As far as I can see there is no way to set:

unsigned int _debounceTicks
unsigned int _clickTicks
unsigned int _pressTicks

whether via constructor or later during runtime, can you confirm this? If so, would you consider adding such a functionality or accepting a PR that adds it?

BUG: Invalid value of getPressedTicks on press stopped event was raised

#include <Arduino.h>
#include "OneButton.h"
OneButton _button = OneButton(4, true, true);
void setup()
{
    Serial.begin(9600);
    Serial.println("Serial OK");

    _button.attachLongPressStop([]() { 
        Serial.println("Press Stop");
        Serial.print(_button.getPressedTicks());
        Serial.println(" ticks"); });
}
void loop()
{
    _button.tick();
}

output everytime when I release pressed button:

Press Stop
1001 ticks

How to fix: you have to remember _stopTime before raise events.
image. Threre are 3-4 such places in the code.

nano every

So i tried to compile your "Interrupt one button" example and it had this error

/home/scott/Arduino/libraries/OneButton-master/examples/InterruptOneButton/InterruptOneButton.ino: In function 'void setup()':
InterruptOneButton:40:3: error: 'PCICR' was not declared in this scope
PCICR |= (1 << PCIE1); // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
^~~~~
InterruptOneButton:40:18: error: 'PCIE1' was not declared in this scope
PCICR |= (1 << PCIE1); // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
^~~~~
/home/scott/Arduino/libraries/OneButton-master/examples/InterruptOneButton/InterruptOneButton.ino:40:18: note: suggested alternative: 'PIN1'
PCICR |= (1 << PCIE1); // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
^~~~~
PIN1
InterruptOneButton:41:3: error: 'PCMSK1' was not declared in this scope
PCMSK1 |= (1 << PCINT9); // This enables the interrupt for pin 1 of Port C: This is A1.
^~~~~~
InterruptOneButton:41:19: error: 'PCINT9' was not declared in this scope
PCMSK1 |= (1 << PCINT9); // This enables the interrupt for pin 1 of Port C: This is A1.
^~~~~~
/home/scott/Arduino/libraries/OneButton-master/examples/InterruptOneButton/InterruptOneButton.ino:41:19: note: suggested alternative: 'PIN0'
PCMSK1 |= (1 << PCINT9); // This enables the interrupt for pin 1 of Port C: This is A1.
^~~~~~
PIN0
exit status 1
'PCICR' was not declared in this scope

Problems with long press on esp8266

I have a simple push button pulling LOW on GPIO2 as per this code:

#include <OneButton.h>

OneButton gpio2Input(2, true);

void setup() {
  // attach handler under assumption relay will hold on
  gpio2Input.attachLongPressStart(alarmIsSounding);

  Serial.begin(115200);   // for debugging
  Serial.println("\r\n*** Ready to rock! ***");
}

void loop() {
  gpio2Input.tick();


  // ...
}

void alarmIsSounding(){
  Serial.println("alarm!");
}

The problem is that I'm only occasionally getting "alarm!" in my serial monitor. I'm long-pressing for various durations (all > 1000ms) and only some of the messages get into the monitor. From reading https://github.com/mathertel/OneButton/blob/master/OneButton.cpp line 128 I'm assuming that every long press (>1000ms) I should see the logging after the 1000ms mark. Is that right?

Maybe it's the esp8266 I don't know. Buy one on ebay: they're like $4 and you can test it yourself. Thanks

PressStart has no debounce ?

Maybe I'm wrong, but there should be debounce in pressStart. because now multiple pressStart events can be generated from one click action. My button is connected with activelow.

Working with analog keypad

I wondering if this library would be used with a keypad that uses only 3 pins? I have the metod to detect every key without wrong keys by I need to implement long press in a few keys.

Regards

BUG: wrong time of double click event raising

#include <Arduino.h>
#include "OneButton.h"
OneButton _button = OneButton(4, true, true);
void setup()
{
    Serial.begin(9600);
    Serial.println("Serial OK");
    _button.attachDoubleClick([]() { Serial.println("Double Click"); });
}

void loop()
{
    _button.tick();
}

STR:

  1. double click (don't release button after second click)
  2. wait for a while (no matter, 1 sec, 5 sec or 1 hour)
  3. release the button.

Actual result: "Double Click" is in output after releasing the button
Expected result: "Double Click" is in output after second click detected

Map same callback to multiple buttons and handle button presses using button id parameter passed into call back.

I'm building an arduino with 20 buttons. Each callback is handled exactly the same, the only difference being the message displayed on screen.
I was wondering if it is possible to assign the same call back to multiple buttons and then differentiate between different buttons inside the callback using a button id.

This would allow me to do the following rather than have 20 call back functions that all do the same thing except pass a different integer into the functions and arrays.

void sqButton1_SC(int id)
{
  Serial.println("buttonNames[id]");
  toggleState(id);
  showButtonFeedbackOnScreen(id);
}

can't include library

when i go to include the library to the ide, it comes up with this error
Arduino: 1.8.9 (Windows 10), Board: "Arduino/Genuino Uno"

LEFT_RIGHT__CENTER:32:23: error: OneButton.h: No such file or directory

compilation terminated.

exit status 1
OneButton.h: No such file or directory

trying to create 3 buttons fails

hello,
trying to create 3 buttons fails:

exit status 1
'click3' was not declared in this scope

why is that so, what is missing?

/*
 This is a sample sketch to show how to use the OneButtonLibrary
 to detect click events on 2 buttons in parallel. 
 The library internals are explained at
 http://www.mathertel.de/Arduino/OneButtonLibrary.aspx 
 https://github.com/mathertel/OneButton
 
 Setup a test circuit:
 * Connect a pushbutton to pin A1 (ButtonPin) and ground.
 * Connect a pushbutton to pin A2 (ButtonPin) and ground.
 * The Serial interface is used for output the detected button events.
 
 The Sketch shows how to setup the library and bind 2 buttons to their functions.
 In the loop function the button1.tick and button2.tick functions have to be called as often as you like.
 */

// 01.03.2014 created by Matthias Hertel
// ... and working.

/* Sample output:

Starting TwoButtons...
Button 1 click.
Button 2 click.
Button 1 doubleclick.
Button 2 doubleclick.
Button 1 longPress start
Button 1 longPress...
Button 1 longPress...
Button 1 longPress...
Button 1 longPress stop
Button 2 longPress start
Button 2 longPress...
Button 2 longPress...
Button 2 longPress stop

*/

#include "OneButton.h"

// Setup a new OneButton   
OneButton button1(D4, true);
OneButton button2(D5, true);
OneButton button3(D6, true);


//------------------------------------------------------------ 
// setup 
void setup() {
  // Setup the Serial port.  
  Serial.begin(115200);
  delay(2000);
  Serial.println("Starting TwoButtons...");

  // link the button 1 functions.
  button1.attachClick(click1);
  button1.attachDoubleClick(doubleclick1);
  button1.attachLongPressStart(longPressStart1);
  button1.attachLongPressStop(longPressStop1);
  button1.attachDuringLongPress(longPress1);

  // link the button 2 functions.
  button2.attachClick(click2);
  button2.attachDoubleClick(doubleclick2);
  button2.attachLongPressStart(longPressStart2);
  button2.attachLongPressStop(longPressStop2);
  button2.attachDuringLongPress(longPress2);

  // link the button 3 functions.
  button3.attachClick(click3);
  button3.attachDoubleClick(doubleclick3);
  button3.attachLongPressStart(longPressStart3);
  button3.attachLongPressStop(longPressStop3);
  button3.attachDuringLongPress(longPress3);


} 

//------------------------------------------------------------ 
// loop

void loop() {
  // keep watching the push buttons:
  button1.tick();
  button2.tick();
  button3.tick();


  delay(10);
} // loop


//------------------------------------------------------------ 
// ----- button 1 callback functions

// This function will be called when the button1 was pressed 1 time (and no 2. button press followed).
void click1() {
  Serial.println("Button 1 click.");
} // click1


// This function will be called when the button1 was pressed 2 times in a short timeframe.
void doubleclick1() {
  Serial.println("Button 1 doubleclick.");
} // doubleclick1


// This function will be called once, when the button1 is pressed for a long time.
void longPressStart1() {
  Serial.println("Button 1 longPress start");
} // longPressStart1


// This function will be called often, while the button1 is pressed for a long time.
void longPress1() {
  //Serial.println("Button 1 longPress...");
} // longPress1


// This function will be called once, when the button1 is released after beeing pressed for a long time.
void longPressStop1() {
  Serial.println("Button 1 longPress stop/true");
} // longPressStop1


// ... and the same for button 2:

void click2() {
  Serial.println("Button 2 click.");
} // click2


void doubleclick2() {
  Serial.println("Button 2 doubleclick.");
} // doubleclick2


void longPressStart2() {
  Serial.println("Button 2 longPress start");
} // longPressStart2


void longPress2() {
  Serial.println("Button 2 longPress...");
} // longPress2

void longPressStop2() {
  Serial.println("Button 2 longPress stop");
} // longPressStop2

// End


Time for long press

Is it possible to define a time what is considered as long press?
I want to run a Function only if the button is pressed for 5 seconds or longer.

comparison between signed and unsigned integer expressions

When compiling with a recent version of the compiler for Arduino (1.8.5), the compiler has a warning about the following

OneButton.cpp: In member function 'void OneButton::tick()': .../OneButton.cpp:140:80: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] if ((buttonLevel == _buttonReleased) && ((unsigned long)(now - _startTime) < _debounceTicks)) {

This is because _debounceTicks is an int and should be an unsigned int (same goes for _clickTicks and _pressTicks)

So I suggest changing

`
int _debounceTicks; // number of ticks for debounce times.

int _clickTicks; // number of ticks that have to pass by before a click is detected

int _pressTicks; // number of ticks that have to pass by before a long button press is detected
`

into

`
unsigned int _debounceTicks; // number of ticks for debounce times.

unsigned int _clickTicks; // number of ticks that have to pass by before a click is detected

unsigned int _pressTicks; // number of ticks that have to pass by before a long button press is detected
`

Update docu

#define BUTTON_PIN 4

/**
 * Initialize a new OneButton instance for a button
 * connected to digital pin 4 and GND, which is active low
 * and uses the internal pull-up resistor.
 */

OneButton btn = OneButton(
  BUTTON_PIN, // Input pin for the button
  LOW,       // Button is active LOW
  true       // Enable internal pull-up resistor
);

to:

#define BUTTON_PIN 4

/*
 * Initialize a new OneButton instance for a button
 * connected to digital pin 4 and GND, which is active low
 * and uses the internal pull-up resistor.
 */

OneButton btn = OneButton(
  BUTTON_PIN,  // Input pin for the button
  true               // Button is active LOW
);

DigiSpark issues

I'm trying to combine these two videos

https://www.youtube.com/watch?v=trx5ZWl9i3Q

https://www.youtube.com/watch?v=TwM1sp2IXYI

#include "OneButton.h"
#include "DigiKeyboard.h"

OneButton button(0, true);

void setup() {
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);

  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);

  DigiKeyboard.sendKeyStroke(0);

  button.attachDoubleClick(doubleClick);
  button.attachClick(singleClick);
  button.attachLongPressStop(longClick);
}

void loop() {
 button.tick();
 delay(10);
}

void singleClick(){
  DigiKeyboard.println("Pass1");
}

void doubleClick(){
  DigiKeyboard.println("Pass2");
}

void longClick(){
  DigiKeyboard.println("Pass3");
}

But it seems to have some trouble differentiating the different types of button press

most of the time it just spits out "Pass3"

I'm only able to flash it at 16.5 MHz and not 8 MHz like suggested in #5

did not work on attiny85

SimpleButton Example not work on attiny85 (Using arduino core frome here). Changed the output pin to 0 (D0) and the kept the input to A1 (D2). Neither Double Click nor Single Click works for me. Is the milli() function supported on attiny?

Changed code:

/*
 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:
 * Connect a pushbutton to pin A1 (ButtonPin) and ground.
 * The pin 13 (StatusPin) is used for output attach a led and resistor to ground
   or see the built-in led on the standard arduino board.

 The Sketch shows how to setup the library and bind a special function to the click event.
 In the loop function the button.tick function has to be called as often as you like.
*/

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

#include "OneButton.h"

// Setup a new OneButton on pin A1.  
OneButton button(A2, false);


// setup code here, to run once:
void setup() {
  // enable the standard led on pin 13.
  pinMode(0, OUTPUT);      // sets the digital pin as output

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


// main code here, to run repeatedly: 
void loop() {
  // keep watching the push button:
  button.tick();

  // You can implement other code in here or just wait a while 
  delay(10);
} // loop


// this function will be called when the button was pressed 2 times in a short timeframe.
void click() {
  static int m = LOW;
  // reverse the LED 
  m = !m;
  digitalWrite(0, m);
} // click

// End

Parallel buttons press events

Parallel button press events (single and long press) would be a nice feature for future updates.

To give an example lets say you have an array of 5 buttons and you want to trigger a special menu if two of the buttons are long pressed simultaneously.

debounce

Hi, I had some problems with the library. If the Input is dedected with _buttonPressed for one time a click is detected without debounce. I implemented a debounce-time (step 7):

void OneButton::tick(void)
{
// Detect the input information
int buttonLevel = digitalRead(_pin); // current button signal.
unsigned long now = millis(); // current (relative) time in msecs.

// Implementation of the state machine
if (_state == 0) { // waiting for menu pin being pressed.
if (buttonLevel == _buttonPressed) {
_state = 7; // step to state 1
_startTime = now; // remember starting time
} // if

} else if (_state == 7) { // debounce check if the button is really pressed
if ((buttonLevel == _buttonPressed) && (now > _startTime + _debounce)) {
_state = 1; // OK button pressed for debounce- time. step to state 1
} // if
if (buttonLevel == _buttonReleased) {
_state = 0; // STOP step to state 0
}

} else if (_state == 1) { // waiting for menu pin being released.
if (buttonLevel == _buttonReleased) {
_state = 2; // step to state 2

} else if ((buttonLevel == _buttonPressed) && (now > _startTime + _pressTicks)) {
  _isLongPressed = true;  // Keep track of long press state
  if (_pressFunc) _pressFunc();
  if (_longPressStartFunc) _longPressStartFunc();
  if (_duringLongPressFunc) _duringLongPressFunc();
  _state = 6; // step to state 6

} else {
  // wait. Stay in this state.
} // if

} else if (_state == 2) { // waiting for menu pin being pressed the second time or timeout.
if (now > _startTime + _clickTicks) {
// this was only a single short click
if (_clickFunc) _clickFunc();
_state = 0; // restart.

} else if (buttonLevel == _buttonPressed) {
  _state = 3; // step to state 3
} // if

} else if (_state == 3) { // waiting for menu pin being released finally.
if (buttonLevel == _buttonReleased) {
// this was a 2 click sequence.
if (_doubleClickFunc) _doubleClickFunc();
_state = 0; // restart.
} // if

} else if (_state == 6) { // waiting for menu pin being release after long press.
if (buttonLevel == _buttonReleased) {
_isLongPressed = false; // Keep track of long press state
if(_longPressStopFunc) _longPressStopFunc();
_state = 0; // restart.
} else {
// button is being long pressed
_isLongPressed = true; // Keep track of long press state
if (_duringLongPressFunc) _duringLongPressFunc();
} // if

} // if
} // OneButton.tick()

// end.

Bug on the website example code

It says:

OneButton button(A1);

I spent a LOT of time trying to understand libraries, using yours as an example, and couldn't understand how that was supposed to work.

Then I tried compiling it and found that it wouldn't compile because that line is missing an argument.

Just thought I'd pass the info along.

Extending the OneButton class to support event based callbacks

In my project I have a set of buttons and the click handler is almost the same but does something different depending on the button (id)
I suggest adding internal functions to the class that will do nothing and will be overrided later in extended class.

function to retrieve number of buttonclicks and short or long press?

hello,
how about a function to retrieve the number of buttonclicks and/or short or long press?
e.g.


void loop() {
  button1.tick();
 button2.tick();

  if(button1.click()) {  // returns 0 if no click  - or number of clicks or long press
     Serial.println(button1.click() ); //  1 for single click , 2 for doubleClick, 3 for long press
  }

// or
   if(button2.click() == 1) {do something ;}
   if(button2.click() == 2) {do other special;}
   if(button2.click() == 3) {do something else;}

  delay(10);
} // loop

Support an arbitrary number of clicks

It would be nice if this library could support triple clicks, quadruple clicks, etc.

Tentatively, it doesn't seem as if it'd be too hard to do this in a backwards-compatible way. I'd like to try to implement it. I recently made a project with a really nice wooden case, but only one button, so I'm pretty invested in seeing how much functionality can be squeezed out of a single button.

Would you be interested in accepting a pull request that solves this issue?

If so, in terms of approach, what are your thought about the following API?

void attachMultiClick(int clicks, callbackFunction newFunction);

I figure attachClick and attachDoubleClick can call attachMultiClick behind-the-scenes.

Probably related to the need behind #42.

Click detected as doubleclick

Hi.
Just found this. It is awesome to get three functions from one button.
I use this with mysensors library to create a smart button.
I got one problem..
Sometimes when i press the button one time it is detected as a doubleclick..
I tried with two switches, both of the same type but i still get this. Is there any values to modify to solve this?
This is the sketch i use. I have the button set up on D2 bacause I want to use interupt.

/*
  Mysensors Smart Button
*/

#define MY_DEBUG
#define MY_RADIO_NRF24

#include "OneButton.h"
#include <SPI.h>
#include <MySensors.h>

#define SN "MySmartButton"
#define SV "1.0"
#define CHILD_ID 1
#define SLEEP_PIN 2
// Setup a new OneButton on pin D2. true will set pin high (internal pull up), false will set pin low.
OneButton button(2, true);
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
const long interval = 5000;

MyMessage on(CHILD_ID, V_SCENE_ON);

// setup code here, to run once:
void setup() {

  // link the doubleclick function to be called on a doubleclick event.
  button.attachClick(click);
  button.attachDoubleClick(doubleclick);
  button.attachPress(press);

} // setup

void presentation()  {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo(SN, SV);
  present(CHILD_ID, S_SCENE_CONTROLLER);
}

int messageA = 1;
int messageB = 2;
int messageC = 3;


void loop() {
  currentMillis = millis();
  // keep watching the push button:
  button.tick();

  if (currentMillis - previousMillis >= interval) {
    Serial.println("Sleep");
    previousMillis = currentMillis;
    sleep(SLEEP_PIN - 2, CHANGE, 0);
  }
} // loop
// this function will be called when the button was pressed one time

void click() {
  send(on.set(messageA));
}
// this function will be called when the button was pressed 2 times in a short timeframe.
void doubleclick() {
  send(on.set(messageB));
} // doubleclick
// this function will be called when the button was pressed for about one second
void press() {
  send(on.set(messageC));
}

Minimum value of setClickTicks for double click feature

It might be useful to note somewhere in the code that it will be hard to detect a double click unless setClickTicks is at least 200 milliseconds (or so). Anything shorter than 200 ms and there just isn't enough time for the user to press a button twice.

When I started thinking a bit, it makes sense that there needed to be a bit of time passed in order to register a double click, but it wasn't immediately obvious how that factored into the setClickTicks function itself (at least not to me...maybe everyone else is fine).

I initially had setClickTicks to 10 ms in order to make the button very responsive. When I tried adding a double click feature, I noticed the double click callback function simply would not register, even when I tried clicking the button as fast as possible. Eventually, I realized that I had to increase setClickTicks to at least 200 ms. I ultimately set setClickTicks to 275 ms which I thought was more comfortable.

Anyways, just a suggestion. Really great library.

Can i request a couple of changes?

I would like to have isPressed function and change the callbackfunction type to a std::function, so that it's easier to bind functors from lambda or some other cpp features.
If you dont mind, I could make the change as well and you will review.

Using internal pullup resistor

I am using this library with nodemcu module. When i use TwoButtons example without using any resistor and connect button to pin and gnd, long press event never stops. I thought it was floating issue because i didn't set INPUT_PULLUP in anywhere. After that in setup() i set this pins to INPUT_PULLUP and worked flawlessly. What is your suggestions to use internal pullups? Changing library or setting it manually in setup()?

Make this work with port expanders?

After having used this lib as intended quite a few times new, I would also like to use it in my new project, which makes use of a port expander (MCP23017). Originally I thought "Well, guess I have to fork OneButton for that", but looking into the code, it seems there could be an easier solution.
Add a constructor
OneBotton(int activeLow) - that does not save a pin
and a method
void tick(int pinValue) - which takes the new pin value (void tick(void) would then call tick(digitalRead(_pin)))

In the loop, you could then call all sorts of stuff like
button.tick(digitalRead(_pin)) (same as button.tick())
button.tick(digitalReadFast(_pin)) (e.g. for Teensy)
button.tick(mcp.digitalRead(0)) (for the Adafruit MCP23017 lib)
...

Would you generally be interested in including something like this? I could implement the described changes and make a pull request.

5 buttons

Hello. Does the library support 5 buttons?

Single Click with Interrupt possible?

I tried to realize a solution with interrupt and single click.
But I can not get it to work.

My function works every second single click or every double click, but not on single clicks.

I want to realize a state machine that switches to the next state with every single click.

TasterTest3.txt

// Taster
#include "OneButton.h"
// The actions I ca do...
typedef enum {
ACTION_NONE, // Wertauswahl reset
ACTION_VORGABE, // Wertauswahl
ACTION_WAHL, // Wertübernahme
ACTION_A, // test
ACTION_B, // test
ACTION_C // test
}
MyActions;

// Setup a new OneButton on pin A1.
OneButton button(A1, true);

MyActions nextAction = ACTION_NONE; // no action when starting

//Setup-----------------------------------------------------------------------------------------
void setup() {
Serial.begin(9600);

// link the myClickFunction function to be called on a click event. 
button.attachClick(myClickFunction); 

// link the doubleclick function to be called on a doubleclick event. 
//button.attachDoubleClick(myDoubleClickFunction); 

// You may have to modify the next 2 lines if using another pin than A1
PCICR |= (1 << PCIE1); // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
PCMSK1 |= (1 << PCINT9); // This enables the interrupt for pin 1 of Port C: This is A1.

// set # millisec after safe click is assumed.
button.setDebounceTicks(50);

// set # millisec after single click is assumed.
button.setClickTicks(500);

// set # millisec after press is assumed.
//button.setPressTicks(1000); //z.Z. nicht genutzt

}

// Main------------------------------------------------------------------------------------------
void loop() {

Serial.print("Nextaction: ");
Serial.println(nextAction);
delay(900);

} // Ende Loop

// Taster
// this function will be called when the button was pressed 1 time and them some time has passed.
void myClickFunction() {
if (nextAction == ACTION_NONE) {
nextAction = ACTION_VORGABE;
Serial.println("VORGABE");
} else if (nextAction == ACTION_VORGABE) {
nextAction = ACTION_WAHL;
Serial.println("WAHL");
} else if (nextAction == ACTION_WAHL) {
nextAction = ACTION_A;
Serial.println("A");
} else if (nextAction == ACTION_A) {
nextAction = ACTION_B;
Serial.println("B");
} else if (nextAction == ACTION_B) {
nextAction = ACTION_C;
Serial.println("C");
} else if (nextAction == ACTION_C) {
nextAction = ACTION_NONE;
}
} // myClickFunction
/*
// this function will be called when the button was pressed 2 times in a short timeframe.
void myDoubleClickFunction() {
if (nextAction == ACTION_VORGABE) {
//l = zykvar[k-1];
nextAction = ACTION_WAHL;

} else if (nextAction == ACTION_A) {
//nextAction = ACTION_NONE;
//Do nothing
}
} // myDoubleClickFunction
*/

// The Interrupt Service Routine for Pin Change Interrupt 1
// This routine will only be called on any signal change on A1: exactly where we need to check.
ISR(PCINT1_vect) {
// keep watching the push button:
button.tick(); // just call tick() to check the state.
}

Could anyone help?

Regards
Volker

Passing a GPIO when using an MCP23s17

Don't have free GPIO and I am using a 23S17 which gives me extra 16 digital GPIO but don't know how to pass the parameter.

OneButton button(A1, true);

my GPIO is:
mcp23s17.pinMode( button8, INPUT_PULLUP );

Debounce when "going up".

The debouncing is only doen when going to pressed state. There can also be bouncing when going up (e.g. some relay contacts can bounce in either way the switching goes).

So it would be good to add debouncing for the up states.

Kind regards,

Compile error

Using #include "OneButton.h" on my Arduino IDE 1.0.6 gives me error:

C:\Program Files (x86)\Arduino\libraries\OneButton/OneButton.h:59: error: ISO C++ forbids initialization of member '_debounceTicks'
C:\Program Files (x86)\Arduino\libraries\OneButton/OneButton.h:59: error: making '_debounceTicks' static

Avoid calling `pinMode` in constructor

Currently, it seems that pinMode is being set in the OneButton constructor.

This seems to be bad practice:

(Ugh, sticky headers. Scroll up a bit after clicking these links.)

The general advice is to have an init or begin function that is called from setup() after the object has been created. This allows time for the hardware to settle down to a stable state before being used.

...more specifically:

C++ constructors are called BEFORE main() (which makes sense, right?)
The AVR peripherals are initialized AFTER main() (main() calls init(), from the core library.)
Therefore, constructors cannot do things to peripherals that are dependent on them already being initialized, or that will be un-done when the peripherals are initialized. You should not do pinMode(pin, OUTPUT) in a constructor because other things needed before pinMode() will work might not have been done, and because init() might (sensibly) set the pins to the expected startup state (all inputs) afterwards...

(now, in fact, init() on AVRs doesn't do anything with the gpio pins, counts on "all inputs" being left over from the HW reset, and pinMode() from a constructor would probably work just fine. But you still shouldn't do it! (especially because AVRs are not the only CPUs out there any more!)

I feel like this is dangerous if the init() causes your input to default to INPUT when you're expecting INPUT_PULLUP as defined in your OneButton() call, and then you connect it to ground by clicking it. Aren't you risking creating a short circuit? Or is that just for OUTPUT?

It seems that other libraries have solved this by creating a separate method from the constructor, e.g. begin() that's meant to be called inside setup(). The constructor just creates an empty object. It's the begin method that would accept pin, activeLow, etc.

I'm new to this, so I'm not sure. Thoughts?

Can't make it work on the Feather Huzzah

I've tried using this library on my Feather Huzzah, but can't get it to compile.

I've added the following to my sketch, but am unable to build as I'm getting error: 'D2' was not declared in this scope.

OneButton button(D2);

From what I understand, the feather huzzah doesn't have the A and D pin definitions, and I'm unable to simply use an integer (2, in this case) as this is incompatible with the library.

Thanks.

longPress doesn't invert for active HIGH

Hi,

I am using this library to monitor one of my buttons to use the longPress detection.

The button is active HIGH and setup using
OneButton selectButton(17, HIGH, false);
It worked fine on my breadBoard using active LOW, but on the board I made its active HIGH since theres some other circuitry.
When I changed it to active HIGH the attachClick is now called correctly but the longPress still seems to be active LOW.
Is anyone else experiencing this? ESP32

removed attachPressStart

pressStart is still mentioned in readme and changelog says that is same as attachLongPressStart but pressStart is activated without delay and longPressStart need to be active for 1 sec.
Consider adding it back.

Compile Warning

My sketch has been working great before this last update, but now I'm getting the following compile warning:

\Arduino\libraries\OneButton\src\OneButton.cpp: In member function 'void OneButton::tick(bool)':
\Arduino\libraries\OneButton\src\OneButton.cpp:223:10: warning: enumeration value 'UNKNOWN' not handled in switch [-Wswitch]
   switch (_state) {
          ^
Sketch uses 35712 bytes (1%) of program storage space. Maximum is 2031616 bytes.
Global variables use 49844 bytes (9%) of dynamic memory, leaving 474444 bytes for local variables. Maximum is 524288 bytes.

how to get the RISING / FALLING?

is there any easy way to get the "start" of the pressed button?

when using a pulled up button, the library gets the click when it's released, but I would like to capture the RISING too...

question with interrupts

Hi!
First: I like your code! Seems really neat! Just earlier today I decided to look for a library with the exact same features and here it is, handcrafted only days ago... wow!
No my question is, as I would like to extend on your "interrupt" example, ...
Oh.. while writing this I realized my queston doesn't make sense...
Just a note: If you use an interrupt to call tick() you also can't use Serial in the callbacks singleClick, doubleClick, ... Because the callbacks are also run from the interrupt.
Thanks again ;)

update example on website

Hi,
just wanted to let you know, that the example is missing the second parameter OneButton button(A1, true);

Thanks for the library :)

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.