Repository navigation
Expand file tree
/
Copy pathencoderIn.h
More file actions
85 lines (75 loc) · 2.71 KB
/
Copy pathencoderIn.h
File metadata and controls
85 lines (75 loc) · 2.71 KB
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
/* -*- C++ -*- */
/********************
Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
quadrature encoder driver (PCINT)
quadrature encoder stream (fake, not using buffers)
*/
#ifndef RSITE_ARDUINO_MENU_ENCODER
#define RSITE_ARDUINO_MENU_ENCODER
#include <pcint.h> //https://github.com/neu-rah/PCINT
#include "../menuDefs.h"
namespace Menu {
template<uint8_t pinA,uint8_t pinB>
class encoderIn {
public:
volatile int pos=0;
//int pinA,pinB;
//encoderIn<pinA,pinB>(int a,int b):pinA(a),pinB(b) {}
void begin() {
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
//attach pin change handlers
PCattachInterrupt<pinA>(mixHandler((void(*)(void*))encoderInUpdateA,this), CHANGE);
PCattachInterrupt<pinB>(mixHandler((void(*)(void*))encoderInUpdateB,this), CHANGE);
}
//PCint handlers
static void encoderInUpdateA(class encoderIn<pinA,pinB> *e);
static void encoderInUpdateB(class encoderIn<pinA,pinB> *e);
};
//PCint handlers
template<uint8_t pinA,uint8_t pinB>
void encoderIn<pinA,pinB>::encoderInUpdateA(class encoderIn<pinA,pinB> *e) {
if (digitalRead(pinA)^digitalRead(pinB)) e->pos--;
else e->pos++;
}
template<uint8_t pinA,uint8_t pinB>
void encoderIn<pinA,pinB>::encoderInUpdateB(class encoderIn<pinA,pinB> *e) {
if (digitalRead(pinA)^digitalRead(pinB)) e->pos++;
else e->pos--;
}
//emulate a stream based on encoderIn movement returning +/- for every 'sensivity' steps
//buffer not needer because we have an accumulator
template<uint8_t pinA,uint8_t pinB>
class encoderInStream:public menuIn {
public:
encoderIn<pinA,pinB> &enc;//associated hardware encoderIn
int sensivity;
int oldPos=0;
encoderInStream(encoderIn<pinA,pinB> &enc,int sensivity):enc(enc), sensivity(sensivity) {}
inline void setSensivity(int s) {sensivity=s;}
int available(void) {return abs(enc.pos-oldPos)/sensivity;}
int peek(void) override {
int d=enc.pos-oldPos;
if (d<=-sensivity)return options->navCodes[downCmd].ch;
if (d>=sensivity) return options->navCodes[upCmd].ch;
return -1;
}
int read() override {
int d=enc.pos-oldPos;
if(d>0 && oldPos<0) d+=sensivity;
else if(d<0 && oldPos>0) d-=sensivity;
if (d<=-sensivity) {
oldPos-=sensivity;
return options->navCodes[downCmd].ch;
}
if (d>=sensivity) {
oldPos+=sensivity;
return options->navCodes[upCmd].ch;
}
return -1;
}
void flush() {oldPos=enc.pos;}
size_t write(uint8_t v) {oldPos=v;return 1;}
};
}//namespace Menu
#endif