diff --git a/code/espurna/DebounceEvent.cpp b/code/espurna/DebounceEvent.cpp index ae7bc571..ef45e1a1 100644 --- a/code/espurna/DebounceEvent.cpp +++ b/code/espurna/DebounceEvent.cpp @@ -42,7 +42,7 @@ EventEmitter::EventEmitter(types::Pin pin, types::EventHandler callback, const t _default_value(config.default_value == types::PinValue::High), _delay(debounce_delay), _repeat(repeat), - _value(false), + _value(_default_value), _ready(false), _reset_count(true), _event_start(0), @@ -70,8 +70,6 @@ EventEmitter::EventEmitter(types::Pin pin, types::EventHandler callback, const t } else { _pin->pinMode(INPUT); } - - _value = _is_switch ? (_pin->digitalRead() == (HIGH)) : _default_value; } EventEmitter::EventEmitter(types::Pin pin, const types::Config& config, unsigned long delay, unsigned long repeat) : @@ -119,7 +117,9 @@ types::Event EventEmitter::loop() { _value = !_value; if (_is_switch) { - event = types::EventChanged; + event = isPressed() + ? types::EventPressed + : types::EventReleased; } else { if (_value == _default_value) { _event_length = millis() - _event_start; diff --git a/code/espurna/button.cpp b/code/espurna/button.cpp index 0db0b36e..19eb1cfb 100644 --- a/code/espurna/button.cpp +++ b/code/espurna/button.cpp @@ -141,6 +141,7 @@ constexpr const debounce_event::types::Config _buttonDecodeConfigBitmask(const u constexpr const button_action_t _buttonDecodeEventAction(const button_actions_t& actions, button_event_t event) { return ( (event == button_event_t::Pressed) ? actions.pressed : + (event == button_event_t::Released) ? actions.released : (event == button_event_t::Click) ? actions.click : (event == button_event_t::DoubleClick) ? actions.dblclick : (event == button_event_t::LongClick) ? actions.lngclick : @@ -151,6 +152,7 @@ constexpr const button_action_t _buttonDecodeEventAction(const button_actions_t& constexpr const button_event_t _buttonMapReleased(uint8_t count, unsigned long length, unsigned long lngclick_delay, unsigned long lnglngclick_delay) { return ( + (0 == count) ? button_event_t::Released : (1 == count) ? ( (length > lnglngclick_delay) ? button_event_t::LongLongClick : (length > lngclick_delay) ? button_event_t::LongClick : button_event_t::Click @@ -164,6 +166,7 @@ constexpr const button_event_t _buttonMapReleased(uint8_t count, unsigned long l button_actions_t _buttonConstructActions(unsigned char index) { return { _buttonPress(index), + _buttonRelease(index), _buttonClick(index), _buttonDoubleClick(index), _buttonLongClick(index), @@ -220,20 +223,10 @@ bool button_t::state() { } button_event_t button_t::loop() { - if (!event_emitter) { - return button_event_t::None; - } - - auto event = event_emitter->loop(); - if (event == debounce_event::types::EventNone) { - return button_event_t::None; - } - - switch (event) { + if (event_emitter) { + switch (event_emitter->loop()) { case debounce_event::types::EventPressed: return button_event_t::Pressed; - case debounce_event::types::EventChanged: - return button_event_t::Click; case debounce_event::types::EventReleased: { return _buttonMapReleased( event_emitter->getEventCount(), @@ -243,8 +236,8 @@ button_event_t button_t::loop() { ); } case debounce_event::types::EventNone: - default: break; + } } return button_event_t::None; @@ -267,13 +260,6 @@ std::bitset _buttons_mqtt_retain( (1 == BUTTON_MQTT_RETAIN) ? 0xFFFFFFFFUL : 0UL ); -void buttonMQTT(unsigned char id, button_event_t event) { - char payload[4] = {0}; - itoa(_buttonEventNumber(event), payload, 10); - // mqttSend(topic, id, payload, force, retain) - mqttSend(MQTT_TOPIC_BUTTON, id, payload, false, _buttons_mqtt_retain[id]); -} - #endif #if WEB_SUPPORT @@ -391,60 +377,40 @@ button_action_t buttonAction(unsigned char id, const button_event_t event) { return _buttonDecodeEventAction(_buttons[id].actions, event); } -// Approach based on https://github.com/esp8266/Arduino/pull/6950 -// "PROGMEM footprint cleanup for responseCodeToString (#6950)" +// Note that we don't directly return F(...), but use a temporary to assign it conditionally +// (ref. https://github.com/esp8266/Arduino/pull/6950 "PROGMEM footprint cleanup for responseCodeToString") // In this particular case, saves 76 bytes (120 vs 44) -#if 1 String _buttonEventString(button_event_t event) { const __FlashStringHelper* ptr = nullptr; switch (event) { case button_event_t::Pressed: - ptr = F("Pressed"); + ptr = F("pressed"); + break; + case button_event_t::Released: + ptr = F("released"); break; case button_event_t::Click: - ptr = F("Click"); + ptr = F("click"); break; case button_event_t::DoubleClick: - ptr = F("Double-click"); + ptr = F("double-click"); break; case button_event_t::LongClick: - ptr = F("Long-click"); + ptr = F("long-click"); break; case button_event_t::LongLongClick: - ptr = F("Looong-click"); + ptr = F("looong-click"); break; case button_event_t::TripleClick: - ptr = F("Triple-click"); + ptr = F("triple-click"); break; case button_event_t::None: - default: - ptr = F("None"); + ptr = F("none"); break; } return String(ptr); } -#else -String _buttonEventString(button_event_t event) { - switch (event) { - case button_event_t::Pressed: - return F("Pressed"); - case button_event_t::Click: - return F("Click"); - case button_event_t::DoubleClick: - return F("Double-click"); - case button_event_t::LongClick: - return F("Long-click"); - case button_event_t::LongLongClick: - return F("Looong-click"); - case button_event_t::TripleClick: - return F("Triple-click"); - case button_event_t::None: - default: - return F("None"); - } -} -#endif void buttonEvent(unsigned char id, button_event_t event) { @@ -462,7 +428,7 @@ void buttonEvent(unsigned char id, button_event_t event) { #if MQTT_SUPPORT if (action || _buttons_mqtt_send_all[id]) { - buttonMQTT(id, event); + mqttSend(MQTT_TOPIC_BUTTON, id, _buttonEventString(event).c_str(), false, _buttons_mqtt_retain[id]); } #endif @@ -828,6 +794,7 @@ void buttonSetup() { for (unsigned char index = 0; index < buttons; ++index) { const button_actions_t actions { + BUTTON_ACTION_NONE, BUTTON_ACTION_NONE, // The only generated event is ::Click getSetting({"btnClick", index}, _buttonClick(index)), @@ -872,6 +839,7 @@ void buttonSetup() { const button_actions_t actions { getSetting({"btnPress", index}, _buttonPress(index)), + getSetting({"btnRlse", index}, _buttonRelease(index)), getSetting({"btnClick", index}, _buttonClick(index)), getSetting({"btnDclk", index}, _buttonDoubleClick(index)), getSetting({"btnLclk", index}, _buttonLongClick(index)), diff --git a/code/espurna/button.h b/code/espurna/button.h index 951c8cc4..0acdddc2 100644 --- a/code/espurna/button.h +++ b/code/espurna/button.h @@ -23,17 +23,19 @@ constexpr size_t ButtonsMax = 32; using button_action_t = uint8_t; enum class button_event_t { - None = 0, - Pressed = 1, - Click = 2, - DoubleClick = 3, - LongClick = 4, - LongLongClick = 5, - TripleClick = 6 + None, + Pressed, + Released, + Click, + DoubleClick, + LongClick, + LongLongClick, + TripleClick }; struct button_actions_t { button_action_t pressed; + button_action_t released; button_action_t click; button_action_t dblclick; button_action_t lngclick; @@ -74,7 +76,6 @@ BrokerDeclare(ButtonBroker, void(unsigned char id, button_event_t event)); bool buttonState(unsigned char id); button_action_t buttonAction(unsigned char id, const button_event_t event); -void buttonMQTT(unsigned char id, button_event_t event); void buttonEvent(unsigned char id, button_event_t event); unsigned char buttonCount(); diff --git a/code/espurna/button_config.h b/code/espurna/button_config.h index 66e07bd9..ebcbad46 100644 --- a/code/espurna/button_config.h +++ b/code/espurna/button_config.h @@ -46,6 +46,19 @@ constexpr const unsigned char _buttonConfigBitmask(unsigned char index) { ); } +constexpr const unsigned char _buttonRelease(unsigned char index) { + return ( + (index == 0) ? BUTTON1_RELEASE : + (index == 1) ? BUTTON2_RELEASE : + (index == 2) ? BUTTON3_RELEASE : + (index == 3) ? BUTTON4_RELEASE : + (index == 4) ? BUTTON5_RELEASE : + (index == 5) ? BUTTON6_RELEASE : + (index == 6) ? BUTTON7_RELEASE : + (index == 7) ? BUTTON8_RELEASE : BUTTON_ACTION_NONE + ); +} + constexpr const unsigned char _buttonPress(unsigned char index) { return ( (index == 0) ? BUTTON1_PRESS : diff --git a/code/espurna/config/defaults.h b/code/espurna/config/defaults.h index 789eda5b..d77fc3d6 100644 --- a/code/espurna/config/defaults.h +++ b/code/espurna/config/defaults.h @@ -83,6 +83,31 @@ #define BUTTON8_PRESS BUTTON_ACTION_NONE #endif +#ifndef BUTTON1_RELEASE +#define BUTTON1_RELEASE BUTTON_ACTION_NONE +#endif +#ifndef BUTTON2_RELEASE +#define BUTTON2_RELEASE BUTTON_ACTION_NONE +#endif +#ifndef BUTTON3_RELEASE +#define BUTTON3_RELEASE BUTTON_ACTION_NONE +#endif +#ifndef BUTTON4_RELEASE +#define BUTTON4_RELEASE BUTTON_ACTION_NONE +#endif +#ifndef BUTTON5_RELEASE +#define BUTTON5_RELEASE BUTTON_ACTION_NONE +#endif +#ifndef BUTTON6_RELEASE +#define BUTTON6_RELEASE BUTTON_ACTION_NONE +#endif +#ifndef BUTTON7_RELEASE +#define BUTTON7_RELEASE BUTTON_ACTION_NONE +#endif +#ifndef BUTTON8_RELEASE +#define BUTTON8_RELEASE BUTTON_ACTION_NONE +#endif + #ifndef BUTTON1_CLICK #define BUTTON1_CLICK BUTTON_ACTION_TOGGLE #endif diff --git a/code/espurna/config/hardware.h b/code/espurna/config/hardware.h index 080a98c5..082db49e 100644 --- a/code/espurna/config/hardware.h +++ b/code/espurna/config/hardware.h @@ -1682,11 +1682,16 @@ // Buttons #define BUTTON1_PIN 5 - #define BUTTON2_PIN 4 #define BUTTON1_RELAY 1 - #define BUTTON2_RELAY 2 #define BUTTON1_CONFIG BUTTON_SWITCH | BUTTON_DEFAULT_HIGH | BUTTON_SET_PULLUP + #define BUTTON1_PRESS BUTTON_ACTION_ON + #define BUTTON1_RELEASE BUTTON_ACTION_OFF + + #define BUTTON2_PIN 4 + #define BUTTON2_RELAY 2 #define BUTTON2_CONFIG BUTTON_SWITCH | BUTTON_DEFAULT_HIGH | BUTTON_SET_PULLUP + #define BUTTON2_PRESS BUTTON_ACTION_ON + #define BUTTON2_RELEASE BUTTON_ACTION_OFF // Relays #define RELAY1_PIN 14 @@ -2560,11 +2565,8 @@ #define BUTTON1_CONFIG BUTTON_SWITCH | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH #define BUTTON1_RELAY 1 - #define BUTTON1_PRESS BUTTON_ACTION_NONE - #define BUTTON1_CLICK BUTTON_ACTION_TOGGLE - #define BUTTON1_DBLCLICK BUTTON_ACTION_NONE - #define BUTTON1_LNGCLICK BUTTON_ACTION_NONE - #define BUTTON1_LNGLNGCLICK BUTTON_ACTION_NONE + #define BUTTON1_PRESS BUTTON_ACTION_ON + #define BUTTON1_RELEASE BUTTON_ACTION_OFF // Relays #define RELAY1_PIN 5 // D1 @@ -2842,17 +2844,15 @@ #define BUTTON1_RELAY 1 #define BUTTON1_CONFIG BUTTON_SWITCH | BUTTON_DEFAULT_HIGH //Hardware Pullup - #define BUTTON1_PRESS BUTTON_ACTION_NONE - #define BUTTON1_CLICK BUTTON_ACTION_TOGGLE - #define BUTTON1_DBLCLICK BUTTON_ACTION_NONE - #define BUTTON1_LNGCLICK BUTTON_ACTION_NONE - #define BUTTON1_LNGLNGCLICK BUTTON_ACTION_NONE + #define BUTTON1_PRESS BUTTON_ACTION_ON + #define BUTTON1_RELEASE BUTTON_ACTION_OFF #define BUTTON2_PIN 13 #define BUTTON2_RELAY 2 #define BUTTON2_CONFIG BUTTON_SWITCH | BUTTON_DEFAULT_HIGH //Hardware Pullup - #define BUTTON2_CLICK BUTTON_ACTION_TOGGLE + #define BUTTON2_PRESS BUTTON_ACTION_ON + #define BUTTON2_RELEASE BUTTON_ACTION_OFF // Relays #define RELAY1_PIN 4 @@ -3664,6 +3664,9 @@ #define BUTTON1_CONFIG BUTTON_SWITCH #define BUTTON1_RELAY 1 + #define BUTTON1_PRESS BUTTON_ACTION_ON + #define BUTTON1_RELEASE BUTTON_ACTION_OFF + // Relays #define RELAY1_PIN 4 #define RELAY1_TYPE RELAY_TYPE_NORMAL @@ -3676,12 +3679,19 @@ // Buttons #define BUTTON1_PIN 12 - #define BUTTON2_PIN 14 + #define BUTTON1_RELAY 1 #define BUTTON1_CONFIG BUTTON_SWITCH + + #define BUTTON1_PRESS BUTTON_ACTION_ON + #define BUTTON1_RELEASE BUTTON_ACTION_OFF + + #define BUTTON2_PIN 14 #define BUTTON2_CONFIG BUTTON_SWITCH - #define BUTTON1_RELAY 1 #define BUTTON2_RELAY 2 + #define BUTTON2_PRESS BUTTON_ACTION_ON + #define BUTTON2_RELEASE BUTTON_ACTION_OFF + // Relays #define RELAY1_PIN 4 #define RELAY1_TYPE RELAY_TYPE_NORMAL @@ -3698,6 +3708,9 @@ #define BUTTON1_CONFIG BUTTON_SWITCH #define BUTTON1_RELAY 1 + #define BUTTON1_PRESS BUTTON_ACTION_ON + #define BUTTON1_RELEASE BUTTON_ACTION_OFF + #define BUTTON2_PIN 2 #define BUTTON2_CONFIG BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH #define BUTTON2_LNGCLICK BUTTON_ACTION_RESET @@ -3741,10 +3754,16 @@ #define BUTTON1_CONFIG BUTTON_SWITCH #define BUTTON1_RELAY 1 + #define BUTTON1_PRESS BUTTON_ACTION_ON + #define BUTTON1_RELEASE BUTTON_ACTION_OFF + #define BUTTON2_PIN 5 #define BUTTON2_CONFIG BUTTON_SWITCH #define BUTTON2_RELAY 2 + #define BUTTON2_PRESS BUTTON_ACTION_ON + #define BUTTON2_RELEASE BUTTON_ACTION_OFF + #define BUTTON3_PIN 2 #define BUTTON3_CONFIG BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH #define BUTTON3_LNGCLICK BUTTON_ACTION_RESET diff --git a/code/espurna/config/types.h b/code/espurna/config/types.h index 08ccacbc..241a7fb9 100644 --- a/code/espurna/config/types.h +++ b/code/espurna/config/types.h @@ -19,7 +19,7 @@ // BUTTONS //------------------------------------------------------------------------------ -// button actions, limited to 4-bit number (0b1111 / 0xf / 15) +// button actions, limited to 8-bit number (0b11111111 / 0xff / 255) #define BUTTON_ACTION_NONE 0u #define BUTTON_ACTION_TOGGLE 1u #define BUTTON_ACTION_ON 2u @@ -33,7 +33,7 @@ #define BUTTON_ACTION_DIM_UP 10u #define BUTTON_ACTION_DIM_DOWN 11u #define BUTTON_ACTION_DISPLAY_ON 12u -#define BUTTON_ACTION_MAX 15u +#define BUTTON_ACTION_MAX 255u // Deprecated: legacy mapping, changed to action from above #define BUTTON_MODE_NONE BUTTON_ACTION_NONE diff --git a/code/espurna/libs/DebounceEvent.h b/code/espurna/libs/DebounceEvent.h index 473cea7f..d19aca34 100644 --- a/code/espurna/libs/DebounceEvent.h +++ b/code/espurna/libs/DebounceEvent.h @@ -69,7 +69,6 @@ namespace types { enum Event { EventNone, - EventChanged, EventPressed, EventReleased };