forked from soligen2010/encoder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ClickEncoder.h
196 lines (159 loc) · 4.39 KB
/
ClickEncoder.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// ----------------------------------------------------------------------------
// Rotary Encoder Driver with Acceleration
// Supports Click, DoubleClick, Long Click
//
// (c) 2010 karl@pitrich.com
// (c) 2014 karl@pitrich.com
//
// Timer-based rotary encoder logic by Peter Dannegger
// http://www.mikrocontroller.net/articles/Drehgeber
// ----------------------------------------------------------------------------
#ifndef __have__ClickEncoder_h__
#define __have__ClickEncoder_h__
// ---Button defaults-------------------------------------------------------------
#define BTN_DOUBLECLICKTIME 400 // second click within 400ms
#define BTN_HOLDTIME 1000 // report held button after 1s
// ----------------------------------------------------------------------------
#include <stdint.h>
#if defined(__AVR__)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#endif
#include "Arduino.h"
// ----------------------------------------------------------------------------
#define ENC_NORMAL (1 << 1) // use Peter Danneger's decoder
#define ENC_FLAKY (1 << 2) // use Table-based decoder
// ----------------------------------------------------------------------------
#ifndef ENC_DECODER
# define ENC_DECODER ENC_NORMAL
#endif
#if ENC_DECODER == ENC_FLAKY
# ifndef ENC_HALFSTEP
# define ENC_HALFSTEP 1 // use table for half step per default
# endif
#endif
// ----------------------------------------------------------------------------
#if defined(__arm__) && (defined (__STM32F1__) || defined (__STM32F4__) )
typedef WiringPinMode pinMode_t;
#else
typedef uint8_t pinMode_t;
#endif
class ClickEncoder
{
public:
typedef enum Button_e {
Open = 0,
Closed,
Pressed,
Held,
Released,
Clicked,
DoubleClicked
} Button;
public:
ClickEncoder(int8_t A, int8_t B, int8_t BTN = -1,
uint8_t stepsPerNotch = 4, bool active = LOW);
#ifndef WITHOUT_BUTTON
explicit ClickEncoder(int8_t BTN, bool active = false); // Depricated. Use Digtial Button instead
#endif
void service(void);
int16_t getValue(void);
#ifndef WITHOUT_BUTTON
public:
Button getButton(void);
#endif
#ifndef WITHOUT_BUTTON
public:
void setDoubleClickTime(uint16_t durationMilliseconds)
{
buttonDoubleClickTime = durationMilliseconds;
}
public:
void setHoldTime(uint16_t durationMilliseconds)
{
buttonHoldTime = durationMilliseconds;
}
public:
void setDoubleClickEnabled(const bool &d)
{
doubleClickEnabled = d;
}
const bool getDoubleClickEnabled()
{
return doubleClickEnabled;
}
public:
void setButtonHeldEnabled(const bool &d)
{
buttonHeldEnabled = d;
}
const bool getButtonHeldEnabled()
{
return buttonHeldEnabled;
}
public:
void setButtonOnPinZeroEnabled(const bool &d)
{
buttonOnPinZeroEnabled = d;
}
const bool getButtonOnPinZeroEnabled()
{
return buttonOnPinZeroEnabled;
}
#endif
public:
void setAccelerationEnabled(const bool &a)
{
accelerationEnabled = a;
if (accelerationEnabled == false) {
acceleration = 0;
}
}
const bool getAccelerationEnabled()
{
return accelerationEnabled;
}
protected:
int8_t pinA;
int8_t pinB;
int8_t pinBTN;
bool pinsActive;
volatile int16_t delta;
volatile int16_t last;
volatile uint8_t steps;
volatile uint16_t acceleration;
bool accelerationEnabled;
#if ENC_DECODER != ENC_NORMAL
static const int8_t table[16];
#endif
#ifndef WITHOUT_BUTTON
volatile Button button;
bool doubleClickEnabled;
bool buttonHeldEnabled;
bool buttonOnPinZeroEnabled = false;
bool analogInput = false;
uint16_t keyDownTicks = 0;
uint16_t doubleClickTicks = 0;
uint16_t buttonHoldTime = BTN_HOLDTIME;
uint16_t buttonDoubleClickTime = BTN_DOUBLECLICKTIME;
unsigned long lastButtonCheck = 0;
int16_t anlogActiveRangeLow = 0;
int16_t anlogActiveRangeHigh = 0;
bool getPinState();
#endif
};
#ifndef WITHOUT_BUTTON
class AnalogButton : public ClickEncoder
{
public:
explicit AnalogButton(int8_t BTN, int16_t rangeLow, int16_t rangeHigh); // Constructor for using analog input range as a button
};
class DigitalButton : public ClickEncoder
{
public:
explicit DigitalButton(int8_t BTN, bool active = false); // Constructor for using a button only
};
#endif
// ----------------------------------------------------------------------------
#endif // __have__ClickEncoder_h__