Commit 187dbd40 authored by Mathieu Maret's avatar Mathieu Maret

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)
parent d5396d75
#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);
}
HIB::HIB(){
}
void HIB::configure(uint8_t pin, uint8_t initState, int longPressMsec){
setConfig(pin, initState, longPressMsec);
void timerCallback(void *data) {
HIB *hib = static_cast<HIB *>(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();
}
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);
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 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;
}
......@@ -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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment