Skip to content

Commit

Permalink
Adds Button class with support for software debouncing
Browse files Browse the repository at this point in the history
  • Loading branch information
m1cr0lab committed Sep 24, 2021
1 parent cab9f0e commit 191d5ef
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 0 deletions.
75 changes: 75 additions & 0 deletions lib/ESPboy/Button.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "Button.h"

void Button::read(uint8_t input) {

for (uint8_t i = 0; i < 8; ++i) {

uint8_t reading = input & (1 << i);

/**
* Software debouncing algorithm (Kennet A. Kuhn)
* @see https://www.kennethkuhn.com/electronics/debounce.c
*/
if (!reading) { if (_integrator[i]) _integrator[i]--; }
else if (_integrator[i] < _DEBOUNCING_THRESHOLD) _integrator[i]++;
uint8_t output = !_integrator[i] ? 0 : (_integrator[i] == _DEBOUNCING_THRESHOLD ? 1 : 0);

switch (_state[i])
{
case _State::FREE:
if (output) _state[i] = _State::PRESSED;
break;

case _State::PRESSED:
if (output) {
_state[i] = _State::HELD;
_held_start_ms[i] = millis();
} else _state[i] = _State::RELEASED;
break;

case _State::HELD:
if (!output) _state[i] = _State::RELEASED;
break;

case _State::RELEASED:
_state[i] = _State::FREE;
break;
}

}

}

bool Button::pressed(uint8_t button) { return _state[button & 0x7] == _State::PRESSED; }
bool Button::released(uint8_t button) { return _state[button & 0x7] == _State::RELEASED; }

bool Button::held(uint8_t button, uint32_t delay_ms) {

return _state[button & 0x7] == _State::HELD && (
delay_ms
? millis() - _held_start_ms[button & 0x7] >= delay_ms
: true
);

}

/**
* ----------------------------------------------------------------------------
* First experiments with ESPboy2
* ----------------------------------------------------------------------------
* Copyright (c) 2021 Stéphane Calderoni (https://github.com/m1cr0lab)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* ----------------------------------------------------------------------------
*/
54 changes: 54 additions & 0 deletions lib/ESPboy/Button.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#pragma once

#include <Arduino.h>

class Button {

private:

static constexpr uint8_t _DEBOUNCING_THRESHOLD = 3;

enum class _State : uint8_t { FREE, PRESSED, HELD, RELEASED };

_State _state[8];
uint32_t _held_start_ms[8];
uint8_t _integrator[8];

public:

static constexpr uint8_t LEFT = 0;
static constexpr uint8_t UP = 1;
static constexpr uint8_t DOWN = 2;
static constexpr uint8_t RIGHT = 3;
static constexpr uint8_t ACT = 4;
static constexpr uint8_t ESC = 5;
static constexpr uint8_t TOP_LEFT = 6;
static constexpr uint8_t TOP_RIGHT = 7;

void read(uint8_t input);
bool pressed(uint8_t button);
bool released(uint8_t button);
bool held(uint8_t button, uint32_t delay_ms = 0);

};

/**
* ----------------------------------------------------------------------------
* First experiments with ESPboy2
* ----------------------------------------------------------------------------
* Copyright (c) 2021 Stéphane Calderoni (https://github.com/m1cr0lab)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* ----------------------------------------------------------------------------
*/
2 changes: 2 additions & 0 deletions lib/ESPboy/ESPboy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ void ESPboy::begin(bool show_logo) {
}

void ESPboy::update() {

button.read(~(_mcp.readGPIOAB() & 0xff));

if (_fading.active) _fade();

Expand Down
2 changes: 2 additions & 0 deletions lib/ESPboy/ESPboy.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#pragma once

#include <Adafruit_MCP23X17.h>
#include "Button.h"
#include "NeoPixel.h"
#include "lgfx.h"
#include "espboy-logo.h"
Expand Down Expand Up @@ -46,6 +47,7 @@ class ESPboy {
public:

LGFX tft;
Button button;
NeoPixel pixel;

void begin(bool show_logo = true);
Expand Down
8 changes: 8 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ src_filter = -<*> +<05-slide/*>
board_build.f_cpu = 160000000L
src_filter = -<*> +<06-jump/*>

; ----------------------------------------------------------------------------
; Improved button handling and support for software debouncing
; ----------------------------------------------------------------------------

[env:07-buttons]
board_build.f_cpu = 160000000L
src_filter = -<*> +<07-buttons.cpp>

; ----------------------------------------------------------------------------
; First experiments with ESPboy2
; ----------------------------------------------------------------------------
Expand Down
75 changes: 75 additions & 0 deletions src/07-buttons.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* ----------------------------------------------------------------------------
* Improved button handling and support for software debouncing
* ----------------------------------------------------------------------------
*/
#include <ESPboy.h>

ESPboy espboy;
LGFX_Sprite fb(&espboy.tft);

uint16_t pressed = 0;
uint16_t held = 0;
uint16_t released = 0;

void clear() { pressed = held = released = 0; }

void setup() {

espboy.begin(false);
fb.createSprite(29, 31);

espboy.tft.setTextColor(TFT_LIGHTGRAY);
espboy.tft.drawCenterString("Press ACT", 64, 16);

espboy.tft.setTextColor(TFT_DARKGRAY);
espboy.tft.drawString("Pressed", 22, 40);
espboy.tft.drawString("Held", 22, 52);
espboy.tft.drawString("Released", 22, 64);

espboy.tft.setTextColor(TFT_LIGHTGRAY);
espboy.tft.drawCenterString("Reset by holding", 64, 88);
espboy.tft.drawCenterString("ESC down for 1 sec", 64, 100);

}

void loop() {

espboy.update();

fb.fillSprite(0);

if (espboy.button.pressed(Button::ACT)) pressed++;
if (espboy.button.held(Button::ACT)) held++;
if (espboy.button.released(Button::ACT)) { released++; held = 0; }

if (espboy.button.held(Button::ESC, 1000)) clear();

fb.drawNumber(pressed, 0, 0);
fb.drawNumber(held, 0, 12);
fb.drawNumber(released, 0, 24);

fb.pushSprite(82, 40);

}

/**
* ----------------------------------------------------------------------------
* First experiments with ESPboy2
* ----------------------------------------------------------------------------
* Copyright (c) 2021 Stéphane Calderoni (https://github.com/m1cr0lab)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* ----------------------------------------------------------------------------
*/

0 comments on commit 191d5ef

Please sign in to comment.