Last active
January 16, 2018 20:55
-
-
Save bart9h/663f8346bd3a8908037730fd88edd8ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//{{{ button123.h | |
#ifndef button123_h_included | |
#define button123_h_included | |
/* | |
* Usage: | |
* | |
* Button123_State button1, button2; | |
* | |
* void start() { | |
* button123_init (&button1, MY_BUTTON1_PIN); | |
* button123_init (&button2, MY_BUTTON2_PIN); | |
* } | |
* | |
* void loop() { | |
* | |
* int button1_event = button123_read(&button1); | |
* int button2_event = button123_read(&button2); | |
* | |
* if (button1_event == 2) | |
* Serial.println("Got two clicks on button 1"); | |
* | |
* if (button2_event == -1) | |
* Serial.println("Got a long press on button 2"); | |
* } | |
* | |
*/ | |
#include <stdbool.h> | |
#include <stdint.h> | |
/* Data structure to hold a button state and configuration. */ | |
typedef struct { | |
/* state */ | |
unsigned long last_debounce_ms; | |
bool last_debounced_read; | |
int clicks; | |
bool long_press; | |
/* config */ | |
uint8_t port; | |
unsigned long debounce_threshold_ms; | |
unsigned long long_threshold_ms; | |
} Button123_State; | |
/* button123_read() returns: | |
* -1 for long a press, | |
* 0 for no event, | |
* n>0 for n consecutive button clicks | |
*/ | |
int button123_read (Button123_State*); | |
void button123_init (Button123_State*, uint8_t port); | |
void button123_set_debounce_threshold (Button123_State*, unsigned long); | |
void button123_set_long_threshold (Button123_State*, unsigned long); | |
#define BUTTON123_DEFAULT_DEBOUNCE_THRESHOLD_MS 50 | |
#define BUTTON123_DEFAULT_LONG_THRESHOLD_MS 2000 | |
#endif | |
//}}} | |
//{{{ button123.c | |
//#include "button123.h" | |
void button123_init (Button123_State* button, uint8_t port) | |
{ | |
button->clicks = 0; | |
button->last_debounce_ms = 0; | |
button->last_debounced_read = false; | |
button->long_press = false; | |
button->port = port; | |
button->long_threshold_ms = BUTTON123_DEFAULT_LONG_THRESHOLD_MS; | |
button->debounce_threshold_ms = BUTTON123_DEFAULT_DEBOUNCE_THRESHOLD_MS; | |
} | |
int button123_read (Button123_State* button) | |
{ | |
bool button_read = digitalRead(button->port); | |
unsigned long curr_ms = millis(); | |
long dt = curr_ms - button->last_debounce_ms; | |
int rc = 0; | |
if (button_read != button->last_debounced_read) { | |
if (dt > button->debounce_threshold_ms) { | |
if (!button_read) { | |
if (button->long_press) | |
button->long_press = false; | |
else | |
++button->clicks; | |
} | |
button->last_debounce_ms = curr_ms; | |
button->last_debounced_read = button_read; | |
} | |
} | |
else if (dt > button->long_threshold_ms) { | |
if (button_read) { | |
if (button->clicks == 0) { | |
if (!button->long_press) | |
rc = -1; | |
button->long_press = true; | |
} | |
} | |
else if (button->clicks > 0) { | |
rc = button->clicks; | |
button->clicks = 0; | |
} | |
} | |
return rc; | |
} | |
void button123_set_debounce_threshold (Button123_State* button, unsigned long debounce_threshold_ms) | |
{ | |
button->debounce_threshold_ms = debounce_threshold_ms; | |
} | |
void button123_set_long_threshold (Button123_State* button, unsigned long long_threshold_ms) | |
{ | |
button->long_threshold_ms = long_threshold_ms; | |
} | |
//}}} | |
#define BUTTON 2 | |
#define LED 13 | |
Button123_State button; | |
int state; | |
bool blink (const char* s, int n) | |
{ | |
return (s[(millis()/100)%n] == '1'); | |
} | |
void setup() | |
{ | |
button123_init(&button, BUTTON); | |
pinMode(LED, OUTPUT); | |
pinMode(BUTTON, INPUT); | |
} | |
void loop() | |
{ | |
int event = button123_read(&button); | |
if (event == -1) | |
state = (state == -1) ? -2 : -1; | |
else if (event > 0) | |
state = event; | |
digitalWrite(LED, | |
(state == -1) ? HIGH : | |
(state == -2) ? LOW : | |
(state == 1) ? blink("1110000000", 10) : | |
(state == 2) ? blink("111001110000000", 15) : | |
(state == 3) ? blink("11100111001110000000", 20) : | |
blink("10", 2)); | |
} | |
// vim:fdm=marker: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment