-
Notifications
You must be signed in to change notification settings - Fork 0
/
Buttons.h
126 lines (107 loc) · 3.68 KB
/
Buttons.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*******************************************************************************
* This file is part of LeoBraille. *
* *
* Copyright (C) 2016 by SukkoPera <software@sukkology.net> *
* *
* LeoBraille 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. *
* *
* LeoBraille 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 LeoBraille. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************
*
* Watashitachi no ookina yume
*/
#ifndef BUTTONS_H_INCLUDED
#define BUTTONS_H_INCLUDED
#include "config.h"
#include "common.h"
#include "debug.h"
class Buttons {
private:
/* Combo debounce time: The combo will be considered valid only after it has
* been stable for this amount of milliseconds
*/
static const unsigned long HOLD_TIME = 40;
/* Combo repeat delay: The combo will repeat after this amount of
* milliseconds since the first valid pressure was detected.
*/
static const unsigned long REPEAT_DELAY = 800;
/* Combo repeat interval: When combo repeat starts, multiple pressions will
* be reported every this amount of milliseconds.
*/
static const unsigned long REPEAT_INTERVAL = 250;
// Reads and debounces
byte readDebounced () {
static byte oldKeys = 0;
static unsigned long pressedOn = 0;
byte ret = 0;
byte keys = readRaw ();
//~ DPRINT (F("Keys = "));
//~ DPRINTLN (allKeys, BIN);
if (keys == oldKeys) {
if (millis () - pressedOn >= HOLD_TIME) {
// Same combo hold long enough
ret = keys;
} else {
// Combo hold not yet long enough
}
} else {
// Keys bouncing
oldKeys = keys;
pressedOn = millis ();
}
return ret;
}
// Returns an 8-bit mask, where each button maps to bit
byte readRaw () {
byte b = 0;
#ifdef KEY_PREV_PIN
if (digitalRead (KEY_PREV_PIN) == LOW)
b |= KEY_PREV;
#endif
if (digitalRead (KEY_NEXT_PIN) == LOW)
b |= KEY_NEXT;
if (digitalRead (KEY_SELECT_PIN) == LOW)
b |= KEY_SELECT;
#ifdef KEY_BACK_PIN
if (digitalRead (KEY_BACK_PIN) == LOW)
b |= KEY_BACK;
#endif
return b;
}
public:
enum _PACKED_ Key {
KEY_NONE = 0,
KEY_PREV = 1 << 0,
KEY_NEXT = 1 << 1,
KEY_SELECT = 1 << 2,
KEY_BACK = 1 << 3,
};
// Reads and repeats
byte read () {
static byte oldKeys = 0;
static unsigned long nextRepeat = 0;
byte ret = KEY_NONE;
byte keys = readDebounced ();
if (keys != oldKeys) {
// First press of new combo, return it and wait for repeat delay
oldKeys = keys;
ret = keys;
nextRepeat = millis () + REPEAT_DELAY;
} else if (keys != 0 && millis () >= nextRepeat) {
// Combo kept pressed, return it and wait for repeat interval
ret = keys;
nextRepeat = millis () + REPEAT_INTERVAL;
}
return ret;
}
};
#endif