forked from benlaurie/arduino--
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquadrature.h
126 lines (97 loc) · 3.47 KB
/
quadrature.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
/******************************************************************************
* quadrature.h - Arduino library for reading quadrature encoders.
* Version 0.90
* Created by Keith Neufeld, June 29, 2008.
*
* Templatified for use with arduino-- by Lars Immisch
*
* This work is licensed under the Creative Commons Attribution-Share Alike
* 3.0 Unported License. To view a copy of this license, visit
* http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to
* Creative Commons, 171 Second Street, Suite 300, San Francisco, California,
* 94105, USA.
******************************************************************************/
#ifndef ARDUINO_MINUS_MINUS_QUADRATURE_H
#define ARDUINO_MINUS_MINUS_QUADRATURE_H
// These constants should probably be in the _Quadrature class, but I don't
// trust the compiler to fold multiple template instantiations into one yet
namespace Encoding {
static const char Half[4][4] = {
{ 0, -1, 1, 0 }, // 00 -> 10 is CW
{ 1, 0, 0, -1 }, // 01 -> 00 is CW
{ -1, 0, 0, 1 }, // 10 -> 11 is CW
{ 0, 1, -1, 0 } // 11 -> 01 is CW
};
static const char Full[4][4] = {
{ 0, 0, 0, 0 }, // 00 -> 10 is silent CW
{ 1, 0, 0, -1 }, // 01 -> 00 is CW
{ -1, 0, 0, 1 }, // 10 -> 11 is CW
{ 0, 0, 0, 0 } // 11 -> 01 is silent CW
};
static const char Alps[4][4] = {
{ 0, 0, 0, 0 },
{ -1, 0, 0, 0 },
{ 1, 0, 0, 0 },
{ 0, 0, 0, 0 }
};
static const int NoLimit = -1;
};
template<class Pin1_, class Pin2_, int min_ = Encoding::NoLimit,
int max_ = Encoding::NoLimit, const char encoding_[4][4] = Encoding::Alps>
class _Quadrature
{
public:
static void init()
{
Pin1_::modeInputPullup();
Pin2_::modeInputPullup();
_previous = _readpins(); // read initial position
}
static void initChangeInterrupt()
{
Pin1_::modeInputPullup();
Pin2_::modeInputPullup();
Pin1_::enableChangeInterrupt();
Pin2_::enableChangeInterrupt();
_previous = _readpins(); // read initial position
}
static int position(void)
{
return _position;
}
static void position(int pos)
{
_position = pos;
}
/** This should be called from the clock ISR
*/
static int update()
{
const int quadbits = _readpins();
if (quadbits != _previous)
{
int position = _position +
encoding_[_previous][quadbits];
// limit to minimum if assigned
position = (min_ != Encoding::NoLimit)
? (min_ > position ? min_ : position) : position;
// limit to maximum if assigned
_position = (max_ != Encoding::NoLimit)
? (max_ < position ? max_ : position) : position;
_previous = quadbits;
}
return quadbits;
}
private:
static int _readpins(void)
{
return Pin2_::read() << 1 | Pin1_::read();
}
volatile static int _position;
volatile static int _previous;
};
template<class Pin1_, class Pin2_, int min_, int max_, const char encoding_[4][4]>
volatile int _Quadrature<Pin1_, Pin2_, min_, max_, encoding_>::_position = 0;
template<class Pin1_, class Pin2_, int min_, int max_, const char encoding_[4][4]>
volatile int _Quadrature<Pin1_, Pin2_, min_, max_, encoding_>::_previous = 0;
#endif // ARDUINO_MINUS_MINUS_QUADRATURE_H