Quadrature Encoder Interface for motion control with resistance to jitter and chatter on AB signals and motor vibrations

Dependents:   QEIx4_Example realtimeMM_V3 realtimeMM_V3

Quadrature Encoder Interface for Motion Control.

A class to decode pulses on a rotary encoder with AB signals (quadrature encoder). It uses all 4 edges of the AB signals to increase the counter resolution 4 times of cycles per rotation/revolution (CPR) (e.g. an encoder with 500 CPR get 2000 counts per rotation)

In opposite to most common QEI implementation this is resistant to jitter and chatter on AB signals and motor vibrations. When using interrupts (IRQ_NO_JAMMING-mode) only the needed edge and pin is activated to prevent jamming CPU time with unnecessary interrupts. Whes reaching the next position the edge that triggerd this position (state) is ignored to aboid oscillating up/down counts.

It can also be used in polling mode i.g. in idle routines if interrupts are not desired. At this mode be sure that the sampling frequency is heigher than the maximum rotation speed (expeced counts per second)

The internal state machine is based on a look up table (LUT) to minimize interrupt retention time and get all necessary flags at once.

Additional the rotation speed of the encoder can be measured. The algorithm is based on the measuring time between the edges to get a very precise speed at very slow rotation.

The library is designed to support closed loop speed- and motion-controller for also slow and smooth motions like movie camera motion control.

Quadrature Encoder Signals:

/media/uploads/jocis/qeix4.png

(+) Count UP; (-) Count DOWN

Committer:
jocis
Date:
Wed Oct 01 10:23:21 2014 +0000
Revision:
2:c0b87b11b9cd
Parent:
1:ac6b7b1bf6c5
replaced virtual functions by attached functions; added documentation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jocis 1:ac6b7b1bf6c5 1 /*
jocis 0:46b8d5680f66 2 * @author Jochen Krapf
jocis 1:ac6b7b1bf6c5 3 * parts by Andy Kirkham
jocis 0:46b8d5680f66 4 *
jocis 0:46b8d5680f66 5 * @section LICENSE
jocis 0:46b8d5680f66 6 *
jocis 1:ac6b7b1bf6c5 7 * Copyright (c) 2014 Jochen Krapf, MIT License
jocis 0:46b8d5680f66 8 *
jocis 0:46b8d5680f66 9 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
jocis 0:46b8d5680f66 10 * and associated documentation files (the "Software"), to deal in the Software without restriction,
jocis 0:46b8d5680f66 11 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
jocis 0:46b8d5680f66 12 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
jocis 0:46b8d5680f66 13 * furnished to do so, subject to the following conditions:
jocis 0:46b8d5680f66 14 *
jocis 0:46b8d5680f66 15 * The above copyright notice and this permission notice shall be included in all copies or
jocis 0:46b8d5680f66 16 * substantial portions of the Software.
jocis 0:46b8d5680f66 17 *
jocis 0:46b8d5680f66 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
jocis 0:46b8d5680f66 19 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
jocis 0:46b8d5680f66 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
jocis 0:46b8d5680f66 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
jocis 0:46b8d5680f66 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
jocis 0:46b8d5680f66 23 *
jocis 0:46b8d5680f66 24 * @section DESCRIPTION
jocis 1:ac6b7b1bf6c5 25 * mbed QEI (quadrature encoder interface) library, for decoding AB signals from a rotary encoder
jocis 0:46b8d5680f66 26 *
jocis 0:46b8d5680f66 27 * Use cases:
jocis 0:46b8d5680f66 28 * - Rotary encoder in closed loop motor regulation
jocis 0:46b8d5680f66 29 * - Hand wheel
jocis 0:46b8d5680f66 30 * - Input device for motion control (MoCo)
jocis 0:46b8d5680f66 31 */
jocis 0:46b8d5680f66 32
jocis 0:46b8d5680f66 33 #include "mbed.h"
jocis 1:ac6b7b1bf6c5 34 #include "FPointer_vi.h"
jocis 0:46b8d5680f66 35
jocis 2:c0b87b11b9cd 36 /** Quadrature Encoder Interface for Motion Control.
jocis 1:ac6b7b1bf6c5 37 *
jocis 2:c0b87b11b9cd 38 * A class to decode pulses on a rotary encoder with AB signals (quadrature encoder).
jocis 2:c0b87b11b9cd 39 * It uses all 4 edges of the AB signals to increase the counter resolution 4 times of cycles per rotation/revolution (CPR) (e.g. an encoder with 500 CPR get 2000 counts per rotation)
jocis 1:ac6b7b1bf6c5 40 *
jocis 2:c0b87b11b9cd 41 * In opposite to most common QEI implementation this is resistant to jitter and chatter on AB signals and motor vibrations.
jocis 2:c0b87b11b9cd 42 * When using interrupts (IRQ_NO_JAMMING-mode) only the needed edge and pin is activated to prevent jamming CPU time with unnecessary interrupts.
jocis 2:c0b87b11b9cd 43 * Whes reaching the next position the edge that triggerd this position (state) is ignored to aboid oscillating up/down counts.
jocis 0:46b8d5680f66 44 *
jocis 2:c0b87b11b9cd 45 * It can also be used in polling mode i.g. in idle routines if interrupts are not desired.
jocis 2:c0b87b11b9cd 46 * At this mode be sure that the sampling frequency is heigher than the maximum rotation speed (expeced counts per second)
jocis 1:ac6b7b1bf6c5 47 *
jocis 1:ac6b7b1bf6c5 48 * The internal state machine is based on a look up table (LUT) to minimize interrupt retention time and get all necessary flags at once.
jocis 0:46b8d5680f66 49 *
jocis 1:ac6b7b1bf6c5 50 * Additional the rotation speed of the encoder can be measured. The algorithm is based on the measuring time between the edges to get a very precise speed at very slow rotation.
jocis 1:ac6b7b1bf6c5 51 *
jocis 1:ac6b7b1bf6c5 52 * The library is designed to support closed loop speed- and motion-controller for also slow and smooth motions like movie camera motion control.
jocis 0:46b8d5680f66 53 *
jocis 0:46b8d5680f66 54 * Example:
jocis 0:46b8d5680f66 55 *
jocis 0:46b8d5680f66 56 * @code
jocis 0:46b8d5680f66 57 #include "mbed.h"
jocis 0:46b8d5680f66 58 #include "QEIx4.h"
jocis 0:46b8d5680f66 59
jocis 2:c0b87b11b9cd 60 DigitalOut LEDalive(LED1);
jocis 2:c0b87b11b9cd 61 DigitalOut LEDzero(LED2);
jocis 2:c0b87b11b9cd 62 DigitalOut LEDup(LED4);
jocis 2:c0b87b11b9cd 63 DigitalOut LEDdown(LED3);
jocis 2:c0b87b11b9cd 64
jocis 2:c0b87b11b9cd 65 Timer t; // timer for polling
jocis 0:46b8d5680f66 66
jocis 0:46b8d5680f66 67 // ports for nxp LPC 1768
jocis 2:c0b87b11b9cd 68 QEIx4 qei1(p30, p29, p28, (QEIx4::EMODE)(QEIx4::IRQ | QEIx4::SPEED)); // QEI with index signal for zeroing
jocis 2:c0b87b11b9cd 69 QEIx4 qei2(p21, p22, NC, QEIx4::IRQ_NO_JAMMING); // QEI with AB signals only
jocis 2:c0b87b11b9cd 70 QEIx4 qei3(p25, p24, NC, QEIx4::POLLING); // QEI without interrups in polling mode
jocis 2:c0b87b11b9cd 71
jocis 2:c0b87b11b9cd 72 // The callback functions
jocis 2:c0b87b11b9cd 73 void myCounterChangeCallback(int value)
jocis 2:c0b87b11b9cd 74 {
jocis 2:c0b87b11b9cd 75 static int valueLast=-1;
jocis 0:46b8d5680f66 76
jocis 2:c0b87b11b9cd 77 if ( value > valueLast ) {
jocis 2:c0b87b11b9cd 78 LEDup = !LEDup;
jocis 2:c0b87b11b9cd 79 LEDdown = 0;
jocis 2:c0b87b11b9cd 80 } else {
jocis 2:c0b87b11b9cd 81 LEDdown = !LEDdown;
jocis 2:c0b87b11b9cd 82 LEDup = 0;
jocis 2:c0b87b11b9cd 83 }
jocis 2:c0b87b11b9cd 84 valueLast = value;
jocis 2:c0b87b11b9cd 85 }
jocis 2:c0b87b11b9cd 86
jocis 2:c0b87b11b9cd 87 void myIndexTriggerCallback(int value)
jocis 2:c0b87b11b9cd 88 {
jocis 2:c0b87b11b9cd 89 qei1 = 0; // reset counter
jocis 2:c0b87b11b9cd 90 LEDzero = 1;
jocis 2:c0b87b11b9cd 91 }
jocis 2:c0b87b11b9cd 92
jocis 2:c0b87b11b9cd 93 int main()
jocis 2:c0b87b11b9cd 94 {
jocis 0:46b8d5680f66 95 t.start();
jocis 0:46b8d5680f66 96
jocis 2:c0b87b11b9cd 97 qei1.setIndexTrigger(true); // set the flag to zero counter on next index signal rises
jocis 2:c0b87b11b9cd 98 qei1.setSpeedFactor(1.0f); // factor to scale from Hz (edges pe second = 4 * CPS) to user units (1.0=Hz, 1/(4*CPR)=rps, 1/(60*4*CPR)=rpm, 360/(4*CPR)=°/s, ...)
jocis 2:c0b87b11b9cd 99 qei3.attachIndexTrigger(myIndexTriggerCallback);
jocis 2:c0b87b11b9cd 100
jocis 2:c0b87b11b9cd 101 qei3.attachCounterChange(myCounterChangeCallback);
jocis 0:46b8d5680f66 102
jocis 2:c0b87b11b9cd 103 while(1) {
jocis 0:46b8d5680f66 104 qei3.poll(); // poll manually without interrupt - sampling in this loop with about 2kHz
jocis 1:ac6b7b1bf6c5 105
jocis 2:c0b87b11b9cd 106 if ( t.read_ms() > 250 ) { // every quater second (4 Hz)
jocis 0:46b8d5680f66 107 t.reset();
jocis 0:46b8d5680f66 108 t.start();
jocis 2:c0b87b11b9cd 109 LEDalive = !LEDalive;
jocis 1:ac6b7b1bf6c5 110
jocis 2:c0b87b11b9cd 111 printf ( "\r\n%6d %6d %6d %10.3f", (int)qei1, (int)qei2, (int)qei3, (float)qei1.getSpeed() ); // print counter values
jocis 0:46b8d5680f66 112 }
jocis 0:46b8d5680f66 113
jocis 2:c0b87b11b9cd 114 wait_us(20); // for about 50kHz polling
jocis 0:46b8d5680f66 115 }
jocis 0:46b8d5680f66 116 }
jocis 0:46b8d5680f66 117 * @endcode
jocis 0:46b8d5680f66 118 */
jocis 1:ac6b7b1bf6c5 119 class QEIx4
jocis 1:ac6b7b1bf6c5 120 {
jocis 0:46b8d5680f66 121 public:
jocis 0:46b8d5680f66 122
jocis 1:ac6b7b1bf6c5 123 typedef enum EMODE {
jocis 1:ac6b7b1bf6c5 124 POLLING = 0,
jocis 1:ac6b7b1bf6c5 125 IRQ = 1,
jocis 1:ac6b7b1bf6c5 126 IRQ_NO_JAMMING = 2,
jocis 1:ac6b7b1bf6c5 127 SPEED = 4,
jocis 1:ac6b7b1bf6c5 128 } EMODE;
jocis 1:ac6b7b1bf6c5 129
jocis 0:46b8d5680f66 130 /** constructor of QEIx4 object
jocis 0:46b8d5680f66 131 *
jocis 0:46b8d5680f66 132 * @param pinA Pin number of input/interrupt pin for encoder line A. All port pins are possible except p19 and p20
jocis 0:46b8d5680f66 133 * @param pinB Pin number of input/interrupt pin for encoder line B. All port pins are possible except p19 and p20
jocis 0:46b8d5680f66 134 * @param pinI Pin number of input pin for optional encoder index or reference switch.
jocis 1:ac6b7b1bf6c5 135 * @param eMode Flag to use interrups to detect changes on line A and B. For none interrupt use mode POLLING and call the function poll() frequently. For optional speed calculation the mode SPEED can be ored
jocis 0:46b8d5680f66 136 */
jocis 1:ac6b7b1bf6c5 137 QEIx4 ( PinName pinA, PinName pinB, PinName pinI=NC, EMODE eMode=IRQ );
jocis 1:ac6b7b1bf6c5 138
jocis 0:46b8d5680f66 139 /** destructor of QEIx4 object
jocis 0:46b8d5680f66 140 */
jocis 0:46b8d5680f66 141 ~QEIx4();
jocis 0:46b8d5680f66 142
jocis 0:46b8d5680f66 143 /** Gets the actual counter value.
jocis 0:46b8d5680f66 144 *
jocis 0:46b8d5680f66 145 * @return Actual counter value
jocis 0:46b8d5680f66 146 */
jocis 1:ac6b7b1bf6c5 147 int read() {
jocis 1:ac6b7b1bf6c5 148 return _counter;
jocis 1:ac6b7b1bf6c5 149 }
jocis 0:46b8d5680f66 150
jocis 0:46b8d5680f66 151 /** Gets the actual counter value as int operator.
jocis 0:46b8d5680f66 152 *
jocis 0:46b8d5680f66 153 * @return Actual counter value as int operator
jocis 0:46b8d5680f66 154 */
jocis 1:ac6b7b1bf6c5 155 operator int () { // int-Operator
jocis 1:ac6b7b1bf6c5 156 return _counter;
jocis 1:ac6b7b1bf6c5 157 }
jocis 1:ac6b7b1bf6c5 158
jocis 0:46b8d5680f66 159 /** Sets the counter value at actual encoder position to given value.
jocis 0:46b8d5680f66 160 *
jocis 0:46b8d5680f66 161 * @param Counter value
jocis 0:46b8d5680f66 162 */
jocis 1:ac6b7b1bf6c5 163 void write ( int counter ) {
jocis 1:ac6b7b1bf6c5 164 _counter = counter;
jocis 1:ac6b7b1bf6c5 165 }
jocis 1:ac6b7b1bf6c5 166
jocis 0:46b8d5680f66 167 /** Sets the counter value at actual encoder position to given value as assign operator.
jocis 0:46b8d5680f66 168 *
jocis 0:46b8d5680f66 169 * @param Counter value
jocis 0:46b8d5680f66 170 */
jocis 1:ac6b7b1bf6c5 171 int operator= ( int counter ) { // Assign-Operator
jocis 1:ac6b7b1bf6c5 172 write(counter);
jocis 1:ac6b7b1bf6c5 173 return counter;
jocis 1:ac6b7b1bf6c5 174 }
jocis 1:ac6b7b1bf6c5 175
jocis 0:46b8d5680f66 176 /** Polls the state machine manually and updates the counter value.
jocis 0:46b8d5680f66 177 */
jocis 1:ac6b7b1bf6c5 178 void poll () {
jocis 1:ac6b7b1bf6c5 179 ProcessISR();
jocis 1:ac6b7b1bf6c5 180 }
jocis 1:ac6b7b1bf6c5 181
jocis 2:c0b87b11b9cd 182 /** Sets the flag for zeroing on next high on index pin while AB lines triggers next counting. The trigger calls tha callback function in which the counter can be set to zero or the actual counter can be latched in for later offset calculation
jocis 0:46b8d5680f66 183 *
jocis 2:c0b87b11b9cd 184 * @param Flag for triggering. Set to 1 for call the attached callback. It is reseted after this call
jocis 0:46b8d5680f66 185 */
jocis 2:c0b87b11b9cd 186 void setIndexTrigger ( bool bIndexTrigger ) {
jocis 2:c0b87b11b9cd 187 _bIndexTrigger = bIndexTrigger;
jocis 1:ac6b7b1bf6c5 188 }
jocis 0:46b8d5680f66 189
jocis 1:ac6b7b1bf6c5 190 /** attach - Overloaded attachment function.
jocis 1:ac6b7b1bf6c5 191 *
jocis 1:ac6b7b1bf6c5 192 * Attach a C type function pointer as the callback.
jocis 1:ac6b7b1bf6c5 193 *
jocis 1:ac6b7b1bf6c5 194 * Note, the callback function prototype must be:-
jocis 1:ac6b7b1bf6c5 195 * @code
jocis 1:ac6b7b1bf6c5 196 * void myCallbackFunction(int);
jocis 1:ac6b7b1bf6c5 197 * @endcode
jocis 1:ac6b7b1bf6c5 198 * @param A C function pointer to call.
jocis 1:ac6b7b1bf6c5 199 */
jocis 1:ac6b7b1bf6c5 200 void attachCounterChange(void (*function)(int) = 0) {
jocis 1:ac6b7b1bf6c5 201 fPointerCounterChange.attach (function);
jocis 1:ac6b7b1bf6c5 202 }
jocis 1:ac6b7b1bf6c5 203
jocis 1:ac6b7b1bf6c5 204 /** attachCounterChange - Overloaded attachment function.
jocis 1:ac6b7b1bf6c5 205 *
jocis 1:ac6b7b1bf6c5 206 * Attach a C++ type object/method pointer as the callback.
jocis 1:ac6b7b1bf6c5 207 *
jocis 1:ac6b7b1bf6c5 208 * Note, the callback method prototype must be:-
jocis 1:ac6b7b1bf6c5 209 * @code
jocis 1:ac6b7b1bf6c5 210 * public:
jocis 1:ac6b7b1bf6c5 211 * static void myCallbackFunction(int);
jocis 1:ac6b7b1bf6c5 212 * @endcode
jocis 1:ac6b7b1bf6c5 213 * @param A C++ object pointer.
jocis 1:ac6b7b1bf6c5 214 * @param A C++ method within the object to call.
jocis 1:ac6b7b1bf6c5 215 */
jocis 1:ac6b7b1bf6c5 216 template<class T>
jocis 1:ac6b7b1bf6c5 217 void attachCounterChange(T* item, void (T::*method)(int)) {
jocis 1:ac6b7b1bf6c5 218 fPointerCounterChange.attach( item, method);
jocis 1:ac6b7b1bf6c5 219 }
jocis 1:ac6b7b1bf6c5 220
jocis 1:ac6b7b1bf6c5 221 /** attachDirectionChange - Overloaded attachment function.
jocis 1:ac6b7b1bf6c5 222 *
jocis 1:ac6b7b1bf6c5 223 * Attach a C type function pointer as the callback.
jocis 1:ac6b7b1bf6c5 224 *
jocis 1:ac6b7b1bf6c5 225 * Note, the callback function prototype must be:-
jocis 1:ac6b7b1bf6c5 226 * @code
jocis 1:ac6b7b1bf6c5 227 * void myCallbackFunction(int);
jocis 1:ac6b7b1bf6c5 228 * @endcode
jocis 1:ac6b7b1bf6c5 229 * @param A C function pointer to call.
jocis 1:ac6b7b1bf6c5 230 */
jocis 1:ac6b7b1bf6c5 231 void attachDirectionChange(void (*function)(int) = 0) {
jocis 1:ac6b7b1bf6c5 232 fPointerDirectionChange.attach (function);
jocis 1:ac6b7b1bf6c5 233 }
jocis 1:ac6b7b1bf6c5 234
jocis 1:ac6b7b1bf6c5 235 /** attachDirectionChange - Overloaded attachment function.
jocis 1:ac6b7b1bf6c5 236 *
jocis 1:ac6b7b1bf6c5 237 * Attach a C++ type object/method pointer as the callback.
jocis 1:ac6b7b1bf6c5 238 *
jocis 1:ac6b7b1bf6c5 239 * Note, the callback method prototype must be:-
jocis 1:ac6b7b1bf6c5 240 * @code
jocis 1:ac6b7b1bf6c5 241 * public:
jocis 1:ac6b7b1bf6c5 242 * static void myCallbackFunction(int);
jocis 1:ac6b7b1bf6c5 243 * @endcode
jocis 1:ac6b7b1bf6c5 244 * @param A C++ object pointer.
jocis 1:ac6b7b1bf6c5 245 * @param A C++ method within the object to call.
jocis 1:ac6b7b1bf6c5 246 */
jocis 1:ac6b7b1bf6c5 247 template<class T>
jocis 1:ac6b7b1bf6c5 248 void attachDirectionChange(T* item, void (T::*method)(int)) {
jocis 1:ac6b7b1bf6c5 249 fPointerDirectionChange.attach( item, method);
jocis 1:ac6b7b1bf6c5 250 }
jocis 1:ac6b7b1bf6c5 251
jocis 2:c0b87b11b9cd 252 /** attachIndexTrigger - Overloaded attachment function.
jocis 2:c0b87b11b9cd 253 *
jocis 2:c0b87b11b9cd 254 * Attach a C type function pointer as the callback.
jocis 2:c0b87b11b9cd 255 *
jocis 2:c0b87b11b9cd 256 * Note, the callback function prototype must be:-
jocis 2:c0b87b11b9cd 257 * @code
jocis 2:c0b87b11b9cd 258 * void myCallbackFunction(int);
jocis 2:c0b87b11b9cd 259 * @endcode
jocis 2:c0b87b11b9cd 260 * @param A C function pointer to call.
jocis 2:c0b87b11b9cd 261 */
jocis 2:c0b87b11b9cd 262 void attachIndexTrigger(void (*function)(int) = 0) {
jocis 2:c0b87b11b9cd 263 fPointerIndexTrigger.attach (function);
jocis 2:c0b87b11b9cd 264 }
jocis 2:c0b87b11b9cd 265
jocis 2:c0b87b11b9cd 266 /** attachIndexTrigger - Overloaded attachment function.
jocis 2:c0b87b11b9cd 267 *
jocis 2:c0b87b11b9cd 268 * Attach a C++ type object/method pointer as the callback.
jocis 2:c0b87b11b9cd 269 *
jocis 2:c0b87b11b9cd 270 * Note, the callback method prototype must be:-
jocis 2:c0b87b11b9cd 271 * @code
jocis 2:c0b87b11b9cd 272 * public:
jocis 2:c0b87b11b9cd 273 * static void myCallbackFunction(int);
jocis 2:c0b87b11b9cd 274 * @endcode
jocis 2:c0b87b11b9cd 275 * @param A C++ object pointer.
jocis 2:c0b87b11b9cd 276 * @param A C++ method within the object to call.
jocis 2:c0b87b11b9cd 277 */
jocis 2:c0b87b11b9cd 278 template<class T>
jocis 2:c0b87b11b9cd 279 void attachIndexTrigger(T* item, void (T::*method)(int)) {
jocis 2:c0b87b11b9cd 280 fPointerIndexTrigger.attach( item, method);
jocis 2:c0b87b11b9cd 281 }
jocis 2:c0b87b11b9cd 282
jocis 1:ac6b7b1bf6c5 283 /** Sets the factor for the getter-functions to convert in another unit (1.0=Hz, 1/(4*CPR)=rps, 1/(60*4*CPR)=rpm, 360/(4*CPR)=°/s, ...)
jocis 1:ac6b7b1bf6c5 284 *
jocis 1:ac6b7b1bf6c5 285 * @param fSpeedFactor - factor to scale from Hz (edges per second = 4 * CPS) to user units
jocis 1:ac6b7b1bf6c5 286 */
jocis 1:ac6b7b1bf6c5 287 void setSpeedFactor(float fSpeedFactor) {
jocis 1:ac6b7b1bf6c5 288 _fSpeedFactor = fSpeedFactor;
jocis 1:ac6b7b1bf6c5 289 }
jocis 1:ac6b7b1bf6c5 290
jocis 1:ac6b7b1bf6c5 291 /** Gets the actual speed as float value. The value is scales by the facor set by setPositionFactor()
jocis 1:ac6b7b1bf6c5 292 *
jocis 1:ac6b7b1bf6c5 293 * @return Actual encoder speed as float
jocis 1:ac6b7b1bf6c5 294 */
jocis 1:ac6b7b1bf6c5 295 float getSpeed();
jocis 1:ac6b7b1bf6c5 296
jocis 1:ac6b7b1bf6c5 297 /** Sets the factor for the getter-functions to convert in another unit (e.g. CPR (cycles per rotation) * 4.0 to get 1.0 for a full rotation)
jocis 1:ac6b7b1bf6c5 298 *
jocis 1:ac6b7b1bf6c5 299 * @param fPositionFactor Factor to scale from counts to user unit
jocis 1:ac6b7b1bf6c5 300 */
jocis 1:ac6b7b1bf6c5 301 void setPositionFactor ( float fPositionFactor ) {
jocis 1:ac6b7b1bf6c5 302 _fPositionFactor = fPositionFactor;
jocis 1:ac6b7b1bf6c5 303 }
jocis 1:ac6b7b1bf6c5 304
jocis 1:ac6b7b1bf6c5 305 /** Gets the actual counter value as float value. The value is scales by the facor set by setSpeedFactor()
jocis 1:ac6b7b1bf6c5 306 *
jocis 1:ac6b7b1bf6c5 307 * @return Actual encoder position as float
jocis 1:ac6b7b1bf6c5 308 */
jocis 1:ac6b7b1bf6c5 309 float getPosition () {
jocis 1:ac6b7b1bf6c5 310 return (float)_counter * _fPositionFactor;
jocis 1:ac6b7b1bf6c5 311 }
jocis 1:ac6b7b1bf6c5 312
jocis 1:ac6b7b1bf6c5 313
jocis 0:46b8d5680f66 314 protected:
jocis 0:46b8d5680f66 315 InterruptIn _pinA, _pinB;
jocis 0:46b8d5680f66 316 DigitalIn _pinI;
jocis 1:ac6b7b1bf6c5 317 FPointer_vi fPointerCounterChange;
jocis 1:ac6b7b1bf6c5 318 FPointer_vi fPointerDirectionChange;
jocis 2:c0b87b11b9cd 319 FPointer_vi fPointerIndexTrigger;
jocis 1:ac6b7b1bf6c5 320
jocis 0:46b8d5680f66 321 int _counter;
jocis 1:ac6b7b1bf6c5 322 short _state;
jocis 1:ac6b7b1bf6c5 323 short _eMode;
jocis 2:c0b87b11b9cd 324 bool _bIndexTrigger;
jocis 1:ac6b7b1bf6c5 325
jocis 1:ac6b7b1bf6c5 326 Timer _SpeedTimer;
jocis 1:ac6b7b1bf6c5 327
jocis 1:ac6b7b1bf6c5 328 unsigned int _nSpeedLastTimer;
jocis 1:ac6b7b1bf6c5 329 unsigned int _nSpeedTimeoutMax;
jocis 1:ac6b7b1bf6c5 330 unsigned int _nSpeedTimeoutCount;
jocis 1:ac6b7b1bf6c5 331 int _nSpeedAvrTimeSum;
jocis 1:ac6b7b1bf6c5 332 int _nSpeedAvrTimeCount;
jocis 1:ac6b7b1bf6c5 333 float _fLastSpeed;
jocis 0:46b8d5680f66 334
jocis 1:ac6b7b1bf6c5 335 void ProcessISR ( void );
jocis 1:ac6b7b1bf6c5 336 void callback_timeout();
jocis 1:ac6b7b1bf6c5 337
jocis 1:ac6b7b1bf6c5 338 float _fPositionFactor;
jocis 1:ac6b7b1bf6c5 339 float _fSpeedFactor;
jocis 1:ac6b7b1bf6c5 340
jocis 1:ac6b7b1bf6c5 341 private:
jocis 1:ac6b7b1bf6c5 342 static short _modeLUT[32];
jocis 0:46b8d5680f66 343 };