From 187dbd40af7a97e4ce5f3a4d0da17f8b653b3574 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Fri, 11 Nov 2016 10:16:26 +0100 Subject: [PATCH] Possibility to handle multiple button Hib should be instantiate on the heap (new Hib()) because of memory overflow on the stack (c.f. https://github.com/esp8266/Arduino/issues/2667) --- HIB.cpp | 118 ++++++++++++++++++++++++++++++-------------------------- HIB.h | 19 ++++++--- 2 files changed, 76 insertions(+), 61 deletions(-) diff --git a/HIB.cpp b/HIB.cpp index d29decd..39124fb 100644 --- a/HIB.cpp +++ b/HIB.cpp @@ -1,80 +1,88 @@ #include "HIB.h" +#define MAX_PIN 15 -static uint8_t pin; -static uint8_t initialState; -static int state; -static volatile bool debouncing; -static ETSTimer timer; -static unsigned long previousMillis; -static unsigned int longPressMsec; -void timerCallback(void *); -void IRQ_handler(); -void onButtonPressed(); -void onButtonReleased(); -void onLongButtonPressed(); -void setConfig(uint8_t p, uint8_t initState, int longPress ); +HIB *HibList[MAX_PIN+1]; +void ICACHE_RAM_ATTR sws_isr_0() { HibList[0]->IRQ_handler(); } +void ICACHE_RAM_ATTR sws_isr_1() { HibList[1]->IRQ_handler(); } +void ICACHE_RAM_ATTR sws_isr_2() { HibList[2]->IRQ_handler(); } +void ICACHE_RAM_ATTR sws_isr_3() { HibList[3]->IRQ_handler(); } +void ICACHE_RAM_ATTR sws_isr_4() { HibList[4]->IRQ_handler(); } +void ICACHE_RAM_ATTR sws_isr_5() { HibList[5]->IRQ_handler(); } +// Pin 6 to 11 can not be used +void ICACHE_RAM_ATTR sws_isr_12() { HibList[12]->IRQ_handler(); } +void ICACHE_RAM_ATTR sws_isr_13() { HibList[13]->IRQ_handler(); } +void ICACHE_RAM_ATTR sws_isr_14() { HibList[14]->IRQ_handler(); } +void ICACHE_RAM_ATTR sws_isr_15() { HibList[15]->IRQ_handler(); } +static void (*ISRList[MAX_PIN+1])() = { + sws_isr_0, + sws_isr_1, + sws_isr_2, + sws_isr_3, + sws_isr_4, + sws_isr_5, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + sws_isr_12, + sws_isr_13, + sws_isr_14, + sws_isr_15 +}; -HIB::HIB(uint8_t pin, uint8_t initialState, int longPressMsec) -{ - setConfig(pin, initialState, longPressMsec); +void timerCallback(void *data) { + HIB *hib = static_cast(data); + hib->debouncing = false; + hib->invertState(); + if (hib->state != digitalRead(hib->pin)){ + Serial.println("Debounce failed"); + hib->state = !hib->state; + return; + } + if(hib->state != hib->initialState) + hib->onButtonPressed(); + else + hib->onButtonReleased(); } -HIB::HIB(){ + +HIB::HIB(uint8_t p, uint8_t initState, unsigned long longPress): + previousMillis(0), longPressMsec(longPress), + pin(p), initialState(initState), + state(initState), debouncing(false) { + pinMode(pin, INPUT_PULLUP); + HibList[pin] = this; + attachInterrupt(digitalPinToInterrupt(pin), ISRList[pin], CHANGE); + os_timer_setfn(&timer, timerCallback, this); } -void HIB::configure(uint8_t pin, uint8_t initState, int longPressMsec){ - setConfig(pin, initState, longPressMsec); -} - -void setConfig(uint8_t p, uint8_t initState, int longPress ){ - pin = p; - initialState = initState; - state = initialState; - debouncing = false; - previousMillis = 0; - longPressMsec = longPress; - - pinMode(pin, INPUT); - attachInterrupt(digitalPinToInterrupt(pin), IRQ_handler, CHANGE); - os_timer_setfn(&timer, timerCallback, NULL); -} - -void IRQ_handler(){ +void HIB::IRQ_handler(){ if(!debouncing){ debouncing = true; os_timer_arm(&timer, 50, 0); } } -void timerCallback(void *){ - debouncing = false; - state = !state; - if (state != digitalRead(pin)){ - Serial.println("Debounce failed"); - state = !state; - return; - } - if(state != initialState) - onButtonPressed(); - else - onButtonReleased(); -} -void onButtonPressed(){ - Serial.println("Button Pressed"); +void HIB::onButtonPressed(){ + Serial.printf("Button Pressed %d\n", pin); previousMillis = millis(); } -void onLongButtonPressed(){ - Serial.println("Long Button Pressed"); +void HIB::onLongButtonPressed(){ + Serial.printf("Long Button Pressed %d \n", pin); } -void onButtonReleased(){ - Serial.println("Button Released"); +void HIB::onButtonReleased(){ + Serial.printf("Button Released %d \n", pin); if(millis() - previousMillis >= longPressMsec){ onLongButtonPressed(); } } -HIB Hib; +void HIB::invertState(){ + state = !state; +} diff --git a/HIB.h b/HIB.h index 7f8a86b..02e87fd 100644 --- a/HIB.h +++ b/HIB.h @@ -6,12 +6,19 @@ extern "C" { // Human Interface Button class HIB { private: + ETSTimer timer; + unsigned long previousMillis; + unsigned long longPressMsec; public: - HIB(uint8_t pin, uint8_t initialState, int longPressMsec = 5000); - HIB(); - void configure(uint8_t pin, uint8_t initialState, int longPressMsec = 5000); + uint8_t pin; + uint8_t initialState; + uint8_t state; + uint8_t debouncing; + HIB(uint8_t pin, uint8_t initialState, unsigned long longPressMsec = 5000); + void IRQ_handler(); + void onButtonPressed(); + void onButtonReleased(); + void onLongButtonPressed(); + void invertState(); }; - - -extern HIB Hib;