README and comments updated.

This commit is contained in:
JChristensen
2018-05-11 07:23:18 -04:00
parent abee83bbba
commit 268004a2f4
7 changed files with 124 additions and 65 deletions

View File

@@ -2,11 +2,20 @@
https://github.com/JChristensen/JC_Button
README file
![CC BY-SA](http://mirrors.creativecommons.org/presskit/buttons/80x15/png/by-sa.png)
## License
Arduino Button Library Copyright (C) 2018 Jack Christensen GNU GPL v3.0
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3.0 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/gpl.html>
## Introduction
The Button library is for debouncing and reading momentary contact switches like tactile button switches. "Long presses" of arbitrary length can be detected. Works well in state machine constructs. Use the read() function to read each button in the main loop, which should execute as fast as possible.
The simplest way to use a button with an AVR microcontroller is to wire the button between a GPIO pin and ground, and turn on the AVR internal pullup resistor. The Button class constructor takes four arguments, but three have default values that work for a button wired in this manner.
## Examples
The following example sketches are included with the **Button** library:
@@ -14,25 +23,48 @@ The following example sketches are included with the **Button** library:
- **LongPress**: Demonstrates detecting long and short button presses.
- **UpDown**: Counts up or down, one number at a time or rapidly by holding the button down.
## Button library functions
## Constructor
### Button(pin, puEnable, invert, dbTime)
### Button(pin, dbTime, puEnable, invert)
##### Description
The constructor defines a button object.
##### Syntax
`Button(pin, puEnable, invert, dbTime);`
##### Parameters
**pin:** Arduino pin number that the button is connected to *(byte)*
**puEnable:** *true* to enable the microcontroller's internal pull-up resistor, else *false* *(boolean)*
invert: *false* interprets a high logic level to mean the button is pressed, *true* interprets a low level as pressed. *true* should be used when a pull-up resistor is employed, *false* for a pull-down resistor. *(boolean)*
**dbTime:** Debounce time in milliseconds *(unsigned long)*
`Button(pin, dbTime, puEnable, invert);`
##### Required parameter
**pin:** Arduino pin number that the button is connected to *(byte)*
##### Optional parameters
**dbTime:** Debounce time in milliseconds. Defaults to 25ms if not given. *(unsigned long)*
**puEnable:** *true* to enable the microcontroller's internal pull-up resistor, else *false*. Defaults to *true* if not given. *(bool)*
**invert:** *false* interprets a high logic level to mean the button is pressed, *true* interprets a low level as pressed. *true* should be used when a pull-up resistor is employed, *false* for a pull-down resistor. Defaults to *true* if not given. *(bool)*
##### Returns
None.
##### Example
```c++
Button myButton = Button(2, true, true, 25); //25 ms debounce
```
// button connected from pin 2 to ground, 25ms debounce, pullup enabled, logic inverted
Button myButton(2);
// same as above but this button needs a longer debounce time (50ms)
Button myButton(3, 50);
// a button wired from the MCU pin to Vcc with an external pull-down resistor
Button myButton(4, 25, false, false);
```
##Library Functions
### begin()
##### Description
Initializes the Button object and the pin it is connected to.
##### Syntax
`myButton.begin();`
##### Parameters
None.
##### Returns
None.
##### Example
```c++
myButton.begin();
```
### read()
##### Description
Reads the button and returns a *boolean* value (*true* or *false*) to indicate whether the button is pressed. The read() function needs to execute very frequently in order for the sketch to be responsive. A good place for read() is at the top of loop(). Often, the return value from read() will not be needed if the other functions below are used.
@@ -41,7 +73,7 @@ Reads the button and returns a *boolean* value (*true* or *false*) to indicate w
##### Parameters
None.
##### Returns
*true* if the button is pressed, *else* false *(boolean)*
*true* if the button is pressed, *else* false *(bool)*
##### Example
```c++
myButton.read();
@@ -50,28 +82,30 @@ myButton.read();
### isPressed()
### isReleased()
##### Description
These methods check the button state at the point in time when it was last read, and return false or true accordingly. These functions **do not** cause the button to be read.
These functions check the button state from the last call to `read()` and return false or true accordingly. These functions **do not** cause the button to be read.
##### Syntax
`myButton.isPressed();`
`myButton.isReleased();`
##### Parameters
None.
##### Returns
*true* or *false*, depending on whether the button has been pressed (released) or not *(boolean)*
*true* or *false*, depending on whether the button has been pressed (released) or not *(bool)*
##### Example
```c++
if ( myButton.isPressed() ) {
//do some stuff
if ( myButton.isPressed() )
{
//do something
}
else {
//do some different stuff
else
{
//do something else
}
```
### wasPressed()
### wasReleased()
##### Description
These methods check the button state to see if it changed between the last two reads and return false or true accordingly. These functions **do not** cause the button to be read. Note that these functions may be more useful than `isPressed()` and `isReleased()` since they actually detect a **change** in the state of the button, which is usually what we want in order to cause some action.
These functions check the button state to see if it changed between the last two calls to `read()` and return false or true accordingly. These functions **do not** cause the button to be read. Note that these functions may be more useful than `isPressed()` and `isReleased()` since they actually detect a **change** in the state of the button, which is usually what we want in order to cause some action.
##### Syntax
`myButton.wasPressed();`
`myButton.wasReleased();`
@@ -81,28 +115,34 @@ None.
*true* or *false*, depending on whether the button was pressed (released) or not *(boolean)*
##### Example
```c++
if ( myButton.wasPressed() ) { ...
if ( myButton.wasPressed() )
{
//do something
}
```
### pressedFor(ms)
### releasedFor(ms)
##### Description
These methods check to see if the button is pressed (or released), and has been in that state for the specified time in milliseconds. Returns false or true accordingly. These functions are useful to detect "long presses". Note that these functions **do not** cause the button to be read.
These functions check to see if the button is pressed (or released), and has been in that state for the specified time in milliseconds. Returns false or true accordingly. These functions are useful to detect "long presses". Note that these functions **do not** cause the button to be read.
##### Syntax
`myButton.pressedFor(ms);`
`myButton.releasedFor(ms);`
##### Parameters
**ms:** The number of milliseconds *(unsigned long)*
##### Returns
*true* or *false*, depending on whether the button was pressed (released) for the specified time *(boolean)*
*true* or *false*, depending on whether the button was pressed (released) for the specified time *(bool)*
##### Example
```c++
if ( myButton.pressedFor(1000) ) { //has the button been pressed for one second?
if ( myButton.pressedFor(1000) )
{
// button has been pressed for one second
}
```
### lastChange()
##### Description
Under certain circumstances, it may be useful to know when a button last changed state. lastChange() returns the time the button last changed state, in milliseconds (the value is derived from the Arduino millis() function).
Under certain circumstances, it may be useful to know when a button last changed state. `lastChange()` returns the time the button last changed state, in milliseconds (the value is derived from the Arduino millis() function).
##### Syntax
`myButton.lastChange();`
##### Parameters
@@ -111,5 +151,5 @@ None.
The time in milliseconds when the button last changed state *(unsigned long)*
##### Example
```c++
unsigned long lastChange = myButton.lastChange();
unsigned long msLastChange = myButton.lastChange();
```

View File

@@ -32,7 +32,7 @@ void setup()
// sequence of states, i.e. ONOFF --> TO_BLINK --> BLINK --> TO_ONOFF --> ONOFF
// note that while the user perceives two "modes", i.e. ON/OFF mode and rapid blink mode,
// two extra states are needed in the state machine to transition between these modes.
enum states_t {ONOFF, TO_BLINK, BLINK, TO_ONOFF};
enum states_t {ONOFF, TO_BLINK, BLINK, TO_ONOFF};
bool ledState; // current LED status
unsigned long ms; // current time from millis()
@@ -43,18 +43,18 @@ void loop()
static states_t STATE; // current state machine state
ms = millis(); // record the current time
myBtn.read(); // read the button
switch (STATE)
{
// this state watches for short and long presses, switches the LED for
// short presses, and moves to the TO_BLINK state for long presses.
case ONOFF:
case ONOFF:
if (myBtn.wasReleased())
switchLED();
else if (myBtn.pressedFor(LONG_PRESS))
STATE = TO_BLINK;
break;
// this is a transition state where we start the fast blink as feedback to the user,
// but we also need to wait for the user to release the button, i.e. end the
// long press, before moving to the BLINK state.
@@ -64,7 +64,7 @@ void loop()
else
fastBlink();
break;
// the fast-blink state. Watch for another long press which will cause us to
// turn the LED off (as feedback to the user) and move to the TO_ONOFF state.
case BLINK:
@@ -77,7 +77,7 @@ void loop()
else
fastBlink();
break;
// this is a transition state where we just wait for the user to release the button
// before moving back to the ONOFF state.
case TO_ONOFF:
@@ -87,7 +87,7 @@ void loop()
}
}
// reverse the current LED state. if it's on, turn it off. If it's off, turn it on.
// reverse the current LED state. if it's on, turn it off. if it's off, turn it on.
void switchLED()
{
msLast = ms; // record the last switch time
@@ -95,7 +95,7 @@ void switchLED()
digitalWrite(LED_PIN, ledState);
}
// switch the LED on and off every BLINK_INETERVAL milliseconds.
// switch the LED on and off every BLINK_INTERVAL milliseconds.
void fastBlink()
{
if (ms - msLast >= BLINK_INTERVAL)

View File

@@ -3,7 +3,7 @@
// Copyright (C) 2018 by Jack Christensen and licensed under
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
//
// Example skletch that uses both short and long button presses to adjust
// Example sketch that uses both short and long button presses to adjust
// a number up and down, between two limits. Short presses increment
// or decrement by one, long presses repeat at a specified rate.
// Every time the number changes, it is written to the serial monitor.
@@ -43,13 +43,13 @@ void loop()
btnUP.read(); // read the buttons
btnDN.read();
if (count != lastCount) // print the count if it has changed
{
lastCount = count;
Serial.println(count, DEC);
}
switch (STATE)
{
case WAIT: // wait for a button event

View File

@@ -1,4 +1,5 @@
Button KEYWORD1
begin KEYWORD2
read KEYWORD2
isPressed KEYWORD2
isReleased KEYWORD2

View File

@@ -1,5 +1,5 @@
name=JC_Button
version=1.0.2
version=2.0.0
author=Jack Christensen <jack.christensen@outlook.com>
maintainer=Jack Christensen <jack.christensen@outlook.com>
sentence=Arduino library to debounce button switches, detect presses, releases, and long presses.

View File

@@ -2,28 +2,12 @@
// https://github.com/JChristensen/JC_Button
// Copyright (C) 2018 by Jack Christensen and licensed under
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
//
// Library for reading momentary contact switches like tactile button
// switches. Intended for use in state machine constructs.
// Use the read() function to read each button in the main loop,
// which should execute as fast as possible.
#include "JC_Button.h"
/*----------------------------------------------------------------------*
* Button(pin, puEnable, invert, dbTime) instantiates a button object. *
* pin Is the Arduino pin the button is connected to. *
* puEnable Enables the AVR internal pullup resistor if != 0 (can also *
* use true or false). *
* invert If invert == 0, interprets a high state as pressed, low as *
* released. If invert != 0, interprets a high state as *
* released, low as pressed (can also use true or false). *
* dbTime Is the debounce time in milliseconds. *
* *
* (Note that invert cannot be implied from puEnable since an external *
* pullup could be used.) *
*----------------------------------------------------------------------*/
/ initialize a Button object and the pin it's connected to. *
/-----------------------------------------------------------------------*/
void Button::begin()
{
pinMode(m_pin, m_puEnable ? INPUT_PULLUP : INPUT);
@@ -36,29 +20,27 @@ void Button::begin()
}
/*----------------------------------------------------------------------*
/ returns the state of the button, true==pressed, false==released, *
/ does debouncing, captures and maintains times, previous states, etc. *
/ returns the state of the button, true if pressed, false if released. *
/ does debouncing, captures and maintains times, previous state, etc. *
/-----------------------------------------------------------------------*/
bool Button::read()
{
uint32_t ms = millis();
uint8_t pinVal = digitalRead(m_pin);
bool pinVal = digitalRead(m_pin);
if (m_invert) pinVal = !pinVal;
if (ms - m_lastChange < m_dbTime)
{
m_time = ms;
m_changed = false;
return m_state;
}
else
{
m_lastState = m_state;
m_state = pinVal;
m_time = ms;
m_changed = (m_state != m_lastState);
if (m_changed) m_lastChange = ms;
return m_state;
}
m_time = ms;
return m_state;
}
/*----------------------------------------------------------------------*
@@ -73,7 +55,7 @@ bool Button::isPressed()
bool Button::isReleased()
{
return m_state;
return !m_state;
}
/*----------------------------------------------------------------------*

View File

@@ -6,23 +6,59 @@
#ifndef JC_BUTTON_H_INCLUDED
#define JC_BUTTON_H_INCLUDED
#include <Arduino.h>
#include <Arduino.h>
class Button
{
public:
// Button(pin, dbTime, puEnable, invert) instantiates a button object.
//
// Required parameter:
// pin The Arduino pin the button is connected to
//
// Optional parameters:
// dbTime Debounce time in milliseconds (default 25ms)
// puEnable true to enable the AVR internal pullup resistor (default true)
// invert true to interpret a low logic level as pressed (default true)
Button::Button(uint8_t pin, uint32_t dbTime=25, uint8_t puEnable=true, uint8_t invert=true)
: m_pin(pin), m_dbTime(dbTime), m_puEnable(puEnable), m_invert(invert) {}
// Initialize a Button object and the pin it's connected to
void begin();
// Returns the current debounced button state, true for pressed,
// false for released. Call this function frequently to ensure
// the sketch is responsive to user input.
bool read();
// Returns true if the button state was pressed at the last call to read().
// Does not cause the button to be read.
bool isPressed();
// Returns true if the button state was released at the last call to read().
// Does not cause the button to be read.
bool isReleased();
// Returns true if the button state at the last call to read() was pressed,
// and this was a change since the previous read.
bool wasPressed();
// Returns true if the button state at the last call to read() was released,
// and this was a change since the previous read.
bool wasReleased();
// Returns true if the button state at the last call to read() was pressed,
// and has been in that state for at least the given number of milliseconds.
bool pressedFor(uint32_t ms);
// Returns true if the button state at the last call to read() was released,
// and has been in that state for at least the given number of milliseconds.
bool releasedFor(uint32_t ms);
// Returns the time in milliseconds (from millis) that the button last
// changed state.
uint32_t lastChange();
private:
uint8_t m_pin; // arduino pin number connected to button
bool m_puEnable; // internal pullup resistor enabled