-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhwRotary.h
98 lines (94 loc) · 2.7 KB
/
hwRotary.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
#pragma once
#include "utils.h"
#include <Wire.h>
/*
Documentation:
Rotary knob code derived from:
https://github.com/buxtronix/arduino/tree/master/libraries/Rotary
Copyright 2011 Ben Buxton. Licenced under the GNU GPL Version 3.
Contact: bb@cactii.net
when the mechanical rotary knob is turned,
the two pins go through a set sequence of
states during one physical "click", as follows:
Direction Binary state of pin A\B
Counterclockwise = 1\1, 0\1, 0\0, 1\0, 1\1
Clockwise = 1\1, 1\0, 0\0, 0\1, 1\1
The neutral state of the knob is 1\1; a turn
is complete when 1\1 is reached again after
passing through all the valid states above,
at which point action should be taken depending
on the direction of the turn.
The variable "state" captures all this as follows
Value Meaning
0 Knob is in neutral state
1, 2, 3 CCW turn state 1, 2, 3
4, 5, 6 CW turn state 1, 2, 3
8, 16 Completed turn CCW, CW
*/
class rotary_obj {
private:
uint _Apin;
uint _Bpin;
uint _Cpin;
bool _invert;
uint _turnState;
uint _clickState;
int _turnBuffer;
time_uS _lastClickTime;
time_queue _clickQueue;
const uint stateMatrix[7][4] = {
{0,4,1,0},
{2,0,1,0},{2,3,1,0},{2,3,0,8},
{5,4,0,0},{5,4,6,0},{5,0,6,16}
};
public:
void setup(uint Apin, uint Bpin, uint Cpin) {
_Apin = Apin;
_Bpin = Bpin;
_Cpin = Cpin;
pinMode(_Apin, INPUT_PULLUP);
pinMode(_Bpin, INPUT_PULLUP);
pinMode(_Cpin, INPUT_PULLUP);
_invert = false;
_turnState = 0;
_clickState = 0;
_turnBuffer = 0;
_lastClickTime = 0;
_clickQueue.clear();
}
void invertDirection(bool invert) {
_invert = invert;
}
void poll() {
uint A = digitalRead(_Apin);
uint B = digitalRead(_Bpin);
uint getRotation = (_invert ? ((A << 1) | B) : ((B << 1) | A));
_turnState = stateMatrix[_turnState & 0b00111][getRotation];
_turnBuffer += (_turnState & 0b01000) >> 3;
_turnBuffer -= (_turnState & 0b10000) >> 4;
_clickState = (0b00011 & ((_clickState << 1) + (digitalRead(_Cpin) == LOW)));
switch (_clickState) {
case 0b11:
_lastClickTime = getTheCurrentTime();
break;
case 0b10:
_clickQueue.push_back(getTheCurrentTime() - _lastClickTime);
break;
default:
break;
}
}
int getTurnFromBuffer() {
int x = ((_turnBuffer > 0) ? 1 : -1) * (_turnBuffer != 0);
_turnBuffer -= x;
return x;
}
time_uS getClickFromBuffer() {
time_uS x = 0;
if (!(_clickQueue.empty())) {
x = pop_and_get(_clickQueue);
}
return x;
}
};
rotary_obj rotary;