-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRoveQuadEncoder.cpp
81 lines (67 loc) · 1.85 KB
/
RoveQuadEncoder.cpp
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
#include "RoveQuadEncoder.h"
#include <Arduino.h>
RoveQuadEncoder::RoveQuadEncoder(uint8_t pinA, uint8_t pinB, float cpr) {
m_pinA = pinA;
m_pinB = pinB;
m_countsToDegrees = 360.0 / cpr;
}
/*
_______ _______
______| |_______| |______ A
_______ _______ __
__| |_______| |_______| B
negative <--- ---> positive
last current
B A B A Movement
------------------------
0 | 0 | 0 | 0 | 0
0 | 0 | 0 | 1 | +1
0 | 0 | 1 | 0 | -1
0 | 0 | 1 | 1 | +2
0 | 1 | 0 | 0 | -1
0 | 1 | 0 | 1 | 0
0 | 1 | 1 | 0 | -2
0 | 1 | 1 | 1 | +1
1 | 0 | 0 | 0 | +1
1 | 0 | 0 | 1 | -2
1 | 0 | 1 | 0 | 0
1 | 0 | 1 | 1 | -1
1 | 1 | 0 | 0 | +2
1 | 1 | 0 | 1 | -1
1 | 1 | 1 | 0 | +1
1 | 1 | 1 | 1 | 0
* Movements of +/- 2 assume pin A edges, should mostly average out
*/
void RoveQuadEncoder::update() {
uint8_t state = (m_lastB<<3) | (m_lastA<<2) | (m_currentB<<1) | (m_currentA<<0);
switch (state) {
case 1: case 7: case 8: case 14:
m_count++;
break;
case 2: case 4: case 11: case 13:
m_count--;
break;
case 3: case 12:
m_count += 2;
break;
case 6: case 9:
m_count -= 2;
break;
}
}
void RoveQuadEncoder::handleInterrupt() {
m_lastA = m_currentA;
m_lastB = m_currentB;
m_currentA = digitalRead(m_pinA);
m_currentB = digitalRead(m_pinB);
update();
}
void RoveQuadEncoder::begin(void (*isr)(void)) {
pinMode(m_pinA, INPUT);
pinMode(m_pinB, INPUT);
attachInterrupt(digitalPinToInterrupt(m_pinA), isr, CHANGE);
attachInterrupt(digitalPinToInterrupt(m_pinB), isr, CHANGE);
}
float RoveQuadEncoder::readDegrees() const {
return (m_inverted? -1 : 1) * m_count * m_countsToDegrees - m_offsetDegrees;
}