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)
This commit is contained in:
Mathieu Maret 2016-11-11 10:16:26 +01:00
parent d5396d7580
commit 187dbd40af
2 changed files with 76 additions and 61 deletions

118
HIB.cpp
View File

@ -1,80 +1,88 @@
#include "HIB.h" #include "HIB.h"
#define MAX_PIN 15
static uint8_t pin; HIB *HibList[MAX_PIN+1];
static uint8_t initialState; void ICACHE_RAM_ATTR sws_isr_0() { HibList[0]->IRQ_handler(); }
static int state; void ICACHE_RAM_ATTR sws_isr_1() { HibList[1]->IRQ_handler(); }
static volatile bool debouncing; void ICACHE_RAM_ATTR sws_isr_2() { HibList[2]->IRQ_handler(); }
static ETSTimer timer; void ICACHE_RAM_ATTR sws_isr_3() { HibList[3]->IRQ_handler(); }
static unsigned long previousMillis; void ICACHE_RAM_ATTR sws_isr_4() { HibList[4]->IRQ_handler(); }
static unsigned int longPressMsec; void ICACHE_RAM_ATTR sws_isr_5() { HibList[5]->IRQ_handler(); }
void timerCallback(void *); // Pin 6 to 11 can not be used
void IRQ_handler(); void ICACHE_RAM_ATTR sws_isr_12() { HibList[12]->IRQ_handler(); }
void onButtonPressed(); void ICACHE_RAM_ATTR sws_isr_13() { HibList[13]->IRQ_handler(); }
void onButtonReleased(); void ICACHE_RAM_ATTR sws_isr_14() { HibList[14]->IRQ_handler(); }
void onLongButtonPressed(); void ICACHE_RAM_ATTR sws_isr_15() { HibList[15]->IRQ_handler(); }
void setConfig(uint8_t p, uint8_t initState, int longPress );
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) void timerCallback(void *data) {
{ HIB *hib = static_cast<HIB *>(data);
setConfig(pin, initialState, longPressMsec); 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){ void HIB::IRQ_handler(){
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(){
if(!debouncing){ if(!debouncing){
debouncing = true; debouncing = true;
os_timer_arm(&timer, 50, 0); 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(){ void HIB::onButtonPressed(){
Serial.println("Button Pressed"); Serial.printf("Button Pressed %d\n", pin);
previousMillis = millis(); previousMillis = millis();
} }
void onLongButtonPressed(){ void HIB::onLongButtonPressed(){
Serial.println("Long Button Pressed"); Serial.printf("Long Button Pressed %d \n", pin);
} }
void onButtonReleased(){ void HIB::onButtonReleased(){
Serial.println("Button Released"); Serial.printf("Button Released %d \n", pin);
if(millis() - previousMillis >= longPressMsec){ if(millis() - previousMillis >= longPressMsec){
onLongButtonPressed(); onLongButtonPressed();
} }
} }
HIB Hib; void HIB::invertState(){
state = !state;
}

19
HIB.h
View File

@ -6,12 +6,19 @@ extern "C" {
// Human Interface Button // Human Interface Button
class HIB { class HIB {
private: private:
ETSTimer timer;
unsigned long previousMillis;
unsigned long longPressMsec;
public: public:
HIB(uint8_t pin, uint8_t initialState, int longPressMsec = 5000); uint8_t pin;
HIB(); uint8_t initialState;
void configure(uint8_t pin, uint8_t initialState, int longPressMsec = 5000); 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;