lib/QEI/QEI.cpp

Thu, 12 Nov 2020 20:26:35 +0100

author
David Douard <david.douard@sdf3.org>
date
Thu, 12 Nov 2020 20:26:35 +0100
changeset 53
74e85b34d26b
parent 27
8f2be7aaec00
permissions
-rw-r--r--

Reorganize the display + improvements for dimmed flags

- the whole upper zone is now dediacated to the main character line
- make sure eash flag has a dedicated non-overlaping area
- improve support for dimmed flags (not yet properly functionning since this
dimm state is actually stateful, so some major refactorings are needed to
properly handle this).

27
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
1 /**
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
2 * @author Aaron Berk
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
3 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
4 * @section LICENSE
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
5 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
6 * Copyright (c) 2010 ARM Limited
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
7 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
9 * of this software and associated documentation files (the "Software"), to deal
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
10 * in the Software without restriction, including without limitation the rights
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
12 * copies of the Software, and to permit persons to whom the Software is
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
13 * furnished to do so, subject to the following conditions:
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
14 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
15 * The above copyright notice and this permission notice shall be included in
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
16 * all copies or substantial portions of the Software.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
17 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
24 * THE SOFTWARE.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
25 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
26 * @section DESCRIPTION
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
27 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
28 * Quadrature Encoder Interface.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
29 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
30 * A quadrature encoder consists of two code tracks on a disc which are 90
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
31 * degrees out of phase. It can be used to determine how far a wheel has
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
32 * rotated, relative to a known starting position.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
33 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
34 * Only one code track changes at a time leading to a more robust system than
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
35 * a single track, because any jitter around any edge won't cause a state
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
36 * change as the other track will remain constant.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
37 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
38 * Encoders can be a homebrew affair, consisting of infrared emitters/receivers
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
39 * and paper code tracks consisting of alternating black and white sections;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
40 * alternatively, complete disk and PCB emitter/receiver encoder systems can
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
41 * be bought, but the interface, regardless of implementation is the same.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
42 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
43 * +-----+ +-----+ +-----+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
44 * Channel A | ^ | | | | |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
45 * ---+ ^ +-----+ +-----+ +-----
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
46 * ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
47 * ^ +-----+ +-----+ +-----+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
48 * Channel B ^ | | | | | |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
49 * ------+ +-----+ +-----+ +-----
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
50 * ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
51 * ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
52 * 90deg
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
53 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
54 * The interface uses X2 encoding by default which calculates the pulse count
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
55 * based on reading the current state after each rising and falling edge of
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
56 * channel A.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
57 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
58 * +-----+ +-----+ +-----+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
59 * Channel A | | | | | |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
60 * ---+ +-----+ +-----+ +-----
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
61 * ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
62 * ^ +-----+ ^ +-----+ ^ +-----+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
63 * Channel B ^ | ^ | ^ | ^ | ^ | |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
64 * ------+ ^ +-----+ ^ +-----+ +--
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
65 * ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
66 * ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
67 * Pulse count 0 1 2 3 4 5 ...
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
68 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
69 * This interface can also use X4 encoding which calculates the pulse count
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
70 * based on reading the current state after each rising and falling edge of
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
71 * either channel.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
72 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
73 * +-----+ +-----+ +-----+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
74 * Channel A | | | | | |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
75 * ---+ +-----+ +-----+ +-----
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
76 * ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
77 * ^ +-----+ ^ +-----+ ^ +-----+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
78 * Channel B ^ | ^ | ^ | ^ | ^ | |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
79 * ------+ ^ +-----+ ^ +-----+ +--
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
80 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
81 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
82 * Pulse count 0 1 2 3 4 5 6 7 8 9 ...
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
83 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
84 * It defaults
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
85 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
86 * An optional index channel can be used which determines when a full
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
87 * revolution has occured.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
88 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
89 * If a 4 pules per revolution encoder was used, with X4 encoding,
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
90 * the following would be observed.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
91 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
92 * +-----+ +-----+ +-----+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
93 * Channel A | | | | | |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
94 * ---+ +-----+ +-----+ +-----
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
95 * ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
96 * ^ +-----+ ^ +-----+ ^ +-----+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
97 * Channel B ^ | ^ | ^ | ^ | ^ | |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
98 * ------+ ^ +-----+ ^ +-----+ +--
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
99 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
100 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
101 * ^ ^ ^ +--+ ^ ^ +--+ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
102 * ^ ^ ^ | | ^ ^ | | ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
103 * Index ------------+ +--------+ +-----------
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
104 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
105 * Pulse count 0 1 2 3 4 5 6 7 8 9 ...
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
106 * Rev. count 0 1 2
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
107 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
108 * Rotational position in degrees can be calculated by:
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
109 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
110 * (pulse count / X * N) * 360
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
111 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
112 * Where X is the encoding type [e.g. X4 encoding => X=4], and N is the number
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
113 * of pulses per revolution.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
114 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
115 * Linear position can be calculated by:
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
116 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
117 * (pulse count / X * N) * (1 / PPI)
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
118 *
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
119 * Where X is encoding type [e.g. X4 encoding => X=44], N is the number of
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
120 * pulses per revolution, and PPI is pulses per inch, or the equivalent for
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
121 * any other unit of displacement. PPI can be calculated by taking the
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
122 * circumference of the wheel or encoder disk and dividing it by the number
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
123 * of pulses per revolution.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
124 */
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
125
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
126 /**
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
127 * Includes
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
128 */
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
129 #include "QEI.h"
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
130
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
131 QEI::QEI(PinName channelA,
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
132 PinName channelB,
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
133 PinName index,
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
134 int pulsesPerRev,
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
135 Encoding encoding,
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
136 const event_callback_t& ev_callback) :
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
137 channelA_(channelA),
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
138 channelB_(channelB),
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
139 index_(index),
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
140 _callback(ev_callback) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
141
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
142 pulses_ = 0;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
143 revolutions_ = 0;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
144 pulsesPerRev_ = pulsesPerRev;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
145 encoding_ = encoding;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
146
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
147 //Workout what the current state is.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
148 int chanA = channelA_.read();
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
149 int chanB = channelB_.read();
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
150
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
151 //2-bit state.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
152 currState_ = (chanA << 1) | (chanB);
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
153 prevState_ = currState_;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
154
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
155 //X2 encoding uses interrupts on only channel A.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
156 //X4 encoding uses interrupts on channel A,
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
157 //and on channel B.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
158 channelA_.rise(callback(this, &QEI::encode));
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
159 channelA_.fall(callback(this, &QEI::encode));
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
160
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
161 //If we're using X4 encoding, then attach interrupts to channel B too.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
162 if (encoding == X4_ENCODING) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
163 channelB_.rise(callback(this, &QEI::encode));
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
164 channelB_.fall(callback(this, &QEI::encode));
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
165 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
166 //Index is optional.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
167 if (index_ != NC) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
168 index_.rise(callback(this, &QEI::index));
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
169 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
170
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
171 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
172
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
173 void QEI::reset(void) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
174
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
175 pulses_ = 0;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
176 revolutions_ = 0;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
177
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
178 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
179
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
180 int QEI::getCurrentState(void) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
181
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
182 return currState_;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
183
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
184 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
185
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
186 int QEI::getPulses(void) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
187
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
188 return pulses_;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
189
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
190 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
191
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
192 int QEI::getRevolutions(void) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
193
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
194 return revolutions_;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
195
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
196 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
197
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
198 // +-------------+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
199 // | X2 Encoding |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
200 // +-------------+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
201 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
202 // When observing states two patterns will appear:
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
203 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
204 // Counter clockwise rotation:
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
205 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
206 // 10 -> 01 -> 10 -> 01 -> ...
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
207 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
208 // Clockwise rotation:
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
209 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
210 // 11 -> 00 -> 11 -> 00 -> ...
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
211 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
212 // We consider counter clockwise rotation to be "forward" and
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
213 // counter clockwise to be "backward". Therefore pulse count will increase
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
214 // during counter clockwise rotation and decrease during clockwise rotation.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
215 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
216 // +-------------+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
217 // | X4 Encoding |
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
218 // +-------------+
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
219 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
220 // There are four possible states for a quadrature encoder which correspond to
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
221 // 2-bit gray code.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
222 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
223 // A state change is only valid if of only one bit has changed.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
224 // A state change is invalid if both bits have changed.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
225 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
226 // Clockwise Rotation ->
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
227 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
228 // 00 01 11 10 00
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
229 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
230 // <- Counter Clockwise Rotation
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
231 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
232 // If we observe any valid state changes going from left to right, we have
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
233 // moved one pulse clockwise [we will consider this "backward" or "negative"].
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
234 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
235 // If we observe any valid state changes going from right to left we have
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
236 // moved one pulse counter clockwise [we will consider this "forward" or
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
237 // "positive"].
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
238 //
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
239 // We might enter an invalid state for a number of reasons which are hard to
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
240 // predict - if this is the case, it is generally safe to ignore it, update
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
241 // the state and carry on, with the error correcting itself shortly after.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
242 void QEI::encode(void) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
243
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
244 int change = 0;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
245 int chanA = channelA_.read();
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
246 int chanB = channelB_.read();
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
247
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
248 //2-bit state.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
249 currState_ = (chanA << 1) | (chanB);
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
250
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
251 if (encoding_ == X2_ENCODING) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
252
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
253 //11->00->11->00 is counter clockwise rotation or "forward".
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
254 if ((prevState_ == 0x3 && currState_ == 0x0) ||
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
255 (prevState_ == 0x0 && currState_ == 0x3)) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
256 change = 1;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
257 pulses_++;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
258
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
259 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
260 //10->01->10->01 is clockwise rotation or "backward".
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
261 else if ((prevState_ == 0x2 && currState_ == 0x1) ||
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
262 (prevState_ == 0x1 && currState_ == 0x2)) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
263 change = -1;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
264 pulses_--;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
265
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
266 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
267
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
268 } else if (encoding_ == X4_ENCODING) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
269
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
270 //Entered a new valid state.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
271 if (((currState_ ^ prevState_) != INVALID) && (currState_ != prevState_)) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
272 //2 bit state. Right hand bit of prev XOR left hand bit of current
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
273 //gives 0 if clockwise rotation and 1 if counter clockwise rotation.
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
274 change = (prevState_ & PREV_MASK) ^ ((currState_ & CURR_MASK) >> 1);
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
275
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
276 if (change == 0) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
277 change = -1;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
278 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
279
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
280 pulses_ -= change;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
281 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
282
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
283 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
284
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
285 if (_callback && (change != 0))
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
286 _callback.call(change==1?1:0);
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
287
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
288 prevState_ = currState_;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
289
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
290 }
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
291
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
292 void QEI::index(void) {
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
293
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
294 revolutions_++;
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
295
8f2be7aaec00 add QEI
David Douard <david.douard@sdfa3.org>
parents:
diff changeset
296 }

mercurial