Skip to content

Commit

Permalink
Merge branch 'btn/cfg-delay' into led/patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
mcspr committed Mar 12, 2020
2 parents 3383f5d + 2d5e03f commit ae87b5c
Show file tree
Hide file tree
Showing 37 changed files with 20,759 additions and 20,379 deletions.
75 changes: 30 additions & 45 deletions code/espurna/DebounceEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
----------------------------------------------------------------------------------
Modified to include generic INPUT / OUTPUT pin support through a custom interface.
Copyright (C) 2020 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
Modified to include generic INPUT / OUTPUT pin support through a custom interface.
Definitions are incompatible with DebounceEvent, you should not include it's headers.
*/
Expand All @@ -31,34 +32,14 @@

#include "libs/DebounceEvent.h"

namespace DebounceEvent {

// We need to explicitly call the constructor, because we need to set the const `pin`:
// https://isocpp.org/wiki/faq/multiple-inheritance#virtual-inheritance-ctors
DigitalPin::DigitalPin(unsigned char pin) :
PinBase(pin)
{}

inline void DigitalPin::pinMode(int8_t mode) {
::pinMode(this->pin, mode);
}

inline void DigitalPin::digitalWrite(int8_t val) {
::digitalWrite(this->pin, val);
}
namespace debounce_event {

inline int DigitalPin::digitalRead() {
return ::digitalRead(this->pin);
}

// TODO: current implementation allows pin == nullptr

EventHandler::EventHandler(std::shared_ptr<PinBase> pin, EventHandler::callback_f callback, int mode, unsigned long debounce_delay, unsigned long repeat) :
EventEmitter::EventEmitter(types::Pin pin, types::EventHandler callback, const types::Config& config, unsigned long debounce_delay, unsigned long repeat) :
_pin(pin),
_callback(callback),
_mode(mode),
_is_switch(mode & Types::ModeSwitch),
_default_status(mode & Types::ModeDefaultHigh),
_config(config),
_is_switch(config.mode == types::Mode::Switch),
_default_status(config.default_state == types::DefaultState::High),
_delay(debounce_delay),
_repeat(repeat),
_status(false),
Expand All @@ -68,9 +49,11 @@ EventHandler::EventHandler(std::shared_ptr<PinBase> pin, EventHandler::callback_
_event_length(0),
_event_count(0)
{
if (_mode & Types::ModeSetPullup) {
if (!pin) return;

if (_config.pin_mode == types::PinMode::InputPullup) {
_pin->pinMode(INPUT_PULLUP);
} else if (_mode & Types::ModeSetPulldown) {
} else if (_config.pin_mode == types::PinMode::InputPulldown) {
// ESP8266 does not have INPUT_PULLDOWN definition, and instead
// has a GPIO16-specific INPUT_PULLDOWN_16:
// - https://github.com/esp8266/Arduino/issues/478
Expand All @@ -91,35 +74,37 @@ EventHandler::EventHandler(std::shared_ptr<PinBase> pin, EventHandler::callback_
_status = _is_switch ? (_pin->digitalRead() == (HIGH)) : _default_status;
}

EventHandler::EventHandler(std::shared_ptr<PinBase> pin, int mode, unsigned long delay, unsigned long repeat) :
EventHandler(pin, nullptr, mode, delay, repeat)
EventEmitter::EventEmitter(types::Pin pin, const types::Config& config, unsigned long delay, unsigned long repeat) :
EventEmitter(pin, nullptr, config, delay, repeat)
{}

bool EventHandler::pressed() {
bool EventEmitter::isPressed() {
return (_status != _default_status);
}

const unsigned char EventHandler::getPin() const {
return _pin->pin;
const types::Pin EventEmitter::getPin() const {
return _pin;
}

const int EventHandler::getMode() const {
return _mode;
const types::Config EventEmitter::getConfig() const {
return _config;
}

unsigned long EventHandler::getEventLength() {
unsigned long EventEmitter::getEventLength() {
return _event_length;
}
unsigned long EventHandler::getEventCount() {
unsigned long EventEmitter::getEventCount() {
return _event_count;
}

Types::event_t EventHandler::loop() {
// TODO: current implementation allows pin == nullptr

types::Event EventEmitter::loop() {

static_assert((HIGH) == 1, "Arduino API HIGH is not 1");
static_assert((LOW) == 0, "Arduino API LOW is not 0");

auto event = Types::EventNone;
auto event = types::EventNone;
bool status = _pin->digitalRead() == (HIGH);

if (status != _status) {
Expand All @@ -134,13 +119,13 @@ Types::event_t EventHandler::loop() {
_status = !_status;

if (_is_switch) {
event = Types::EventChanged;
event = types::EventChanged;
} else {
if (_status == _default_status) {
_event_length = millis() - _event_start;
_ready = true;
} else {
event = Types::EventPressed;
event = types::EventPressed;
_event_start = millis();
_event_length = 0;
if (_reset_count) {
Expand All @@ -158,15 +143,15 @@ Types::event_t EventHandler::loop() {
if (_ready && (millis() - _event_start > _repeat)) {
_ready = false;
_reset_count = true;
event = Types::EventReleased;
event = types::EventReleased;
}

if (_callback && (event != Types::EventNone)) {
_callback(this, event, _event_count, _event_length);
if (_callback && (event != types::EventNone)) {
_callback(*this, event, _event_count, _event_length);
}

return event;

}

} // namespace DebounceEvent
} // namespace debounce_event
46 changes: 35 additions & 11 deletions code/espurna/button.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,66 @@ Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>

#pragma once

#include "libs/BasePin.h"
#include "libs/DebounceEvent.h"

#include <memory>

constexpr size_t BUTTONS_MAX = 32;
constexpr size_t ButtonsPresetMax = 8;
constexpr size_t ButtonsMax = 32;

enum class button_event_t {
None = 0,
Pressed = 1,
Click = 2,
DoubleClick = 3,
LongClick = 4,
LongLongClick = 5,
TripleClick = 6
};

struct button_actions_t {
uint16_t pressed;
uint16_t click;
uint16_t dblclick;
uint16_t lngclick;
uint16_t lnglngclick;
uint16_t trplclick;
};

struct button_event_delays_t {
button_event_delays_t();
button_event_delays_t(unsigned long debounce, unsigned long dblclick, unsigned long lngclick, unsigned long lnglngclick);
button_event_delays_t(unsigned long debounce, unsigned long repeat, unsigned long lngclick, unsigned long lnglngclick);

const unsigned long debounce;
const unsigned long dblclick;
const unsigned long repeat;
const unsigned long lngclick;
const unsigned long lnglngclick;
};

struct button_t {

button_t(unsigned long actions, unsigned char relayID, button_event_delays_t delays);
button_t(std::shared_ptr<DebounceEvent::PinBase> pin, int mode, unsigned long actions, unsigned char relayID, button_event_delays_t delays);
button_t(unsigned char relayID, const button_actions_t& actions, const button_event_delays_t& delays);
button_t(std::shared_ptr<BasePin> pin, const debounce_event::types::Config& config,
unsigned char relayID, const button_actions_t& actions, const button_event_delays_t& delays);

bool state();
button_event_t loop();

std::unique_ptr<debounce_event::EventEmitter> event_emitter;

std::unique_ptr<DebounceEvent::EventHandler> event_handler;
button_event_delays_t event_delays;
const button_event_delays_t event_delays;
const button_actions_t actions;

const unsigned long actions;
const unsigned char relayID;

};

bool buttonState(unsigned char id);
unsigned char buttonAction(unsigned char id, unsigned char event);
uint16_t buttonAction(unsigned char id, const button_event_t event);

void buttonMQTT(unsigned char id, uint8_t event);
void buttonEvent(unsigned char id, unsigned char event);
void buttonMQTT(unsigned char id, button_event_t event);
void buttonEvent(unsigned char id, button_event_t event);

unsigned char buttonCount();
void buttonSetup();
Loading

0 comments on commit ae87b5c

Please sign in to comment.