VizBlocks
RotaryEncoder.h
Go to the documentation of this file.
1 #ifndef ROTARYENCODER_h
2 #define ROTARYENCODER_h
3 
4 class RotaryEncoder {
5 
6  // Private members:
7 
8  int _pinA;
9  int _pinB;
10  int _id;
11 
12  volatile int _state[2];
13  volatile int _position;
14 
15  volatile bool _inputFlag = false;
16  bool _changeFlag = false;
17 
18  unsigned long _previousTimer;
19  int _interval = 200;
20 
21  void (*_cb)(RotaryEncoder*, uint8_t, int); // Callback function
22 
23  // {newPin2, newPin1, oldPin2, oldPin1}
24  int movements[5][4][4] = {
25  { // No movement
26  {0, 0, 0, 0},
27  {0, 1, 0, 1},
28  {1, 0, 1, 0},
29  {1, 1, 1, 1}
30  },
31  { // +1
32  {0, 0, 0, 1},
33  {0, 1, 1, 1},
34  {1, 0, 0, 0},
35  {1, 1, 1, 0}
36  },
37  { // -1
38  {0, 0, 1, 0},
39  {0, 1, 0, 0},
40  {1, 0, 1, 1},
41  {1, 1, 0, 1}
42  },
43  { // +2
44  {0, 0, 1, 1},
45  {1, 1, 0, 0}
46  },
47  { // -2
48  {0, 1, 1, 0},
49  {1, 0, 0, 1}
50  },
51  };
52 
53  // Private Functions:
54 
55  void _setState(int a, int b) {
56  _state[0] = a;
57  _state[1] = b;
58  }
59 
60  void _incrementPosition(int delta) {
61  _position = _position + delta;
62  }
63 
64  int _findChange(int state1[2], volatile int state2[2]) {
65  int stateAppend[] = {state1[1], state1[0], state2[1], state2[0]};
66 
67  for (int i = 0; i < 3; i++) {
68  for (int j = 0; j < 4; j++) {
69  if (_compareArrays(stateAppend, movements[i][j])) {
70  if (i == 0) {
71  return 0;
72  }
73  else if (i == 1) {
74  return 1;
75  }
76  else if (i == 2) {
77  return -1;
78  }
79  else if (i == 3) {
80  return 2;
81  }
82  else if (i == 4) {
83  return -2;
84  }
85  }
86  }
87  }
88 
89  for (int i = 3; i < 5; i++) {
90  for (int j = 0; j < 2; j++) {
91  if (_compareArrays(stateAppend, movements[i][j])) {
92  if (i == 3) {
93  return 2;
94  }
95  else if (i == 4) {
96  return -2;
97  }
98  }
99  }
100  }
101  Serial.println("INVALID DATA");
102  return 0;
103  }
104 
105  boolean _compareArrays(int a[4], int b[4]) {
106  if (a[0] != b[0]) {
107  return false;
108  }
109  if (a[1] != b[1]) {
110  return false;
111  }
112  if (a[2] != b[2]) {
113  return false;
114  }
115  if (a[3] != b[3]) {
116  return false;
117  }
118  return true;
119  }
120 
121  public:
122 
123  // Public members:
124 
125  static const uint8_t kEventStableUpdate = 0;
126  static const uint8_t kEventUnstableUpdate = 1;
127 
128  //Public Functions:
129 
130  RotaryEncoder(int pinA, int pinB, int id = 99) : _pinA(pinA), _pinB(pinB), _id(id) {
131  pinMode(_pinA, INPUT_PULLUP);
132  pinMode(_pinB, INPUT_PULLUP);
133 
134  _previousTimer = millis();
135  _setState(digitalRead(_pinA), digitalRead(_pinB));
136  setPosition(0);
137  }
138 
139  void initInterrupts(void(*function)()) {
140  attachInterrupt(_pinA, function, CHANGE);
141  attachInterrupt(_pinB, function, CHANGE);
142  }
143 
144  void setEventHandler(void(*function)(RotaryEncoder*, uint8_t, int)) {
145  _cb = function;
146  }
147 
148  int getPostition() {
149  return _position;
150  }
151 
152  int getId() {
153  return _id;
154  }
155 
156  void setPosition(int value) {
157  _position = value;
158  }
159 
160  void check() {
161  unsigned long timer = millis();
162  unsigned long deltaTime = timer - _previousTimer;
163 
164  if (_inputFlag == true) {
165  _inputFlag = false;
166 
167  _changeFlag = true;
168  _previousTimer = timer;
169 
170  _cb(this, kEventUnstableUpdate, getPostition());
171  }
172 
173  if (_changeFlag == true && deltaTime > _interval) {
174  _changeFlag = false;
175 
176  _cb(this, kEventStableUpdate, getPostition());
177  }
178  }
179 
180  void ICACHE_RAM_ATTR tick() {
181  int tempState[] = {digitalRead(_pinA), digitalRead(_pinB)};
182  int delta = _findChange(tempState, _state);
183  if (delta != 0) {
184  _incrementPosition(delta);
185  _inputFlag = true;
186  }
187  _setState(tempState[0], tempState[1]);
188  }
189 
190 };
191 
192 #endif
RotaryEncoder::tick
void ICACHE_RAM_ATTR tick()
Definition: RotaryEncoder.h:180
RotaryEncoder::kEventUnstableUpdate
static const uint8_t kEventUnstableUpdate
Definition: RotaryEncoder.h:126
RotaryEncoder::setEventHandler
void setEventHandler(void(*function)(RotaryEncoder *, uint8_t, int))
Definition: RotaryEncoder.h:144
RotaryEncoder::kEventStableUpdate
static const uint8_t kEventStableUpdate
Definition: RotaryEncoder.h:125
RotaryEncoder::initInterrupts
void initInterrupts(void(*function)())
Definition: RotaryEncoder.h:139
RotaryEncoder
Definition: RotaryEncoder.h:4
RotaryEncoder::setPosition
void setPosition(int value)
Definition: RotaryEncoder.h:156
RotaryEncoder::RotaryEncoder
RotaryEncoder(int pinA, int pinB, int id=99)
Definition: RotaryEncoder.h:130
RotaryEncoder::check
void check()
Definition: RotaryEncoder.h:160
RotaryEncoder::getId
int getId()
Definition: RotaryEncoder.h:152
RotaryEncoder::getPostition
int getPostition()
Definition: RotaryEncoder.h:148