Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of QEI by
QEI.h
00001 /** 00002 * @author Aaron Berk 00003 * 00004 * @section LICENSE 00005 * 00006 * Copyright (c) 2010 ARM Limited 00007 * 00008 * Permission is hereby granted, free of charge, to any person obtaining a copy 00009 * of this software and associated documentation files (the "Software"), to deal 00010 * in the Software without restriction, including without limitation the rights 00011 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00012 * copies of the Software, and to permit persons to whom the Software is 00013 * furnished to do so, subject to the following conditions: 00014 * 00015 * The above copyright notice and this permission notice shall be included in 00016 * all copies or substantial portions of the Software. 00017 * 00018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00019 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00020 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00021 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00022 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00023 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00024 * THE SOFTWARE. 00025 * 00026 * @section DESCRIPTION 00027 * 00028 * Quadrature Encoder Interface. 00029 * 00030 * A quadrature encoder consists of two code tracks on a disc which are 90 00031 * degrees out of phase. It can be used to determine how far a wheel has 00032 * rotated, relative to a known starting position. 00033 * 00034 * Only one code track changes at a time leading to a more robust system than 00035 * a single track, because any jitter around any edge won't cause a state 00036 * change as the other track will remain constant. 00037 * 00038 * Encoders can be a homebrew affair, consisting of infrared emitters/receivers 00039 * and paper code tracks consisting of alternating black and white sections; 00040 * alternatively, complete disk and PCB emitter/receiver encoder systems can 00041 * be bought, but the interface, regardless of implementation is the same. 00042 * 00043 * +-----+ +-----+ +-----+ 00044 * Channel A | ^ | | | | | 00045 * ---+ ^ +-----+ +-----+ +----- 00046 * ^ ^ 00047 * ^ +-----+ +-----+ +-----+ 00048 * Channel B ^ | | | | | | 00049 * ------+ +-----+ +-----+ +----- 00050 * ^ ^ 00051 * ^ ^ 00052 * 90deg 00053 * 00054 * The interface uses X2 encoding by default which calculates the pulse count 00055 * based on reading the current state after each rising and falling edge of 00056 * channel A. 00057 * 00058 * +-----+ +-----+ +-----+ 00059 * Channel A | | | | | | 00060 * ---+ +-----+ +-----+ +----- 00061 * ^ ^ ^ ^ ^ 00062 * ^ +-----+ ^ +-----+ ^ +-----+ 00063 * Channel B ^ | ^ | ^ | ^ | ^ | | 00064 * ------+ ^ +-----+ ^ +-----+ +-- 00065 * ^ ^ ^ ^ ^ 00066 * ^ ^ ^ ^ ^ 00067 * Pulse count 0 1 2 3 4 5 ... 00068 * 00069 * This interface can also use X4 encoding which calculates the pulse count 00070 * based on reading the current state after each rising and falling edge of 00071 * either channel. 00072 * 00073 * +-----+ +-----+ +-----+ 00074 * Channel A | | | | | | 00075 * ---+ +-----+ +-----+ +----- 00076 * ^ ^ ^ ^ ^ 00077 * ^ +-----+ ^ +-----+ ^ +-----+ 00078 * Channel B ^ | ^ | ^ | ^ | ^ | | 00079 * ------+ ^ +-----+ ^ +-----+ +-- 00080 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 00081 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 00082 * Pulse count 0 1 2 3 4 5 6 7 8 9 ... 00083 * 00084 * It defaults 00085 * 00086 * An optional index channel can be used which determines when a full 00087 * revolution has occured. 00088 * 00089 * If a 4 pules per revolution encoder was used, with X4 encoding, 00090 * the following would be observed. 00091 * 00092 * +-----+ +-----+ +-----+ 00093 * Channel A | | | | | | 00094 * ---+ +-----+ +-----+ +----- 00095 * ^ ^ ^ ^ ^ 00096 * ^ +-----+ ^ +-----+ ^ +-----+ 00097 * Channel B ^ | ^ | ^ | ^ | ^ | | 00098 * ------+ ^ +-----+ ^ +-----+ +-- 00099 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 00100 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 00101 * ^ ^ ^ +--+ ^ ^ +--+ ^ 00102 * ^ ^ ^ | | ^ ^ | | ^ 00103 * Index ------------+ +--------+ +----------- 00104 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 00105 * Pulse count 0 1 2 3 4 5 6 7 8 9 ... 00106 * Rev. count 0 1 2 00107 * 00108 * Rotational position in degrees can be calculated by: 00109 * 00110 * (pulse count / X * N) * 360 00111 * 00112 * Where X is the encoding type [e.g. X4 encoding => X=4], and N is the number 00113 * of pulses per revolution. 00114 * 00115 * Linear position can be calculated by: 00116 * 00117 * (pulse count / X * N) * (1 / PPI) 00118 * 00119 * Where X is encoding type [e.g. X4 encoding => X=44], N is the number of 00120 * pulses per revolution, and PPI is pulses per inch, or the equivalent for 00121 * any other unit of displacement. PPI can be calculated by taking the 00122 * circumference of the wheel or encoder disk and dividing it by the number 00123 * of pulses per revolution. 00124 */ 00125 00126 #ifndef QEI_H 00127 #define QEI_H 00128 00129 /** 00130 * Includes 00131 */ 00132 #include "mbed.h" 00133 00134 /** 00135 * Defines 00136 */ 00137 #define PREV_MASK 0x1 //Mask for the previous state in determining direction 00138 //of rotation. 00139 #define CURR_MASK 0x2 //Mask for the current state in determining direction 00140 //of rotation. 00141 #define INVALID 0x3 //XORing two states where both bits have changed. 00142 00143 /** 00144 * Quadrature Encoder Interface. 00145 */ 00146 class QEI { 00147 00148 public: 00149 00150 typedef enum Encoding { 00151 00152 X2_ENCODING, 00153 X4_ENCODING 00154 00155 } Encoding; 00156 00157 /** 00158 * Constructor. 00159 * 00160 * Reads the current values on channel A and channel B to determine the 00161 * initial state. 00162 * 00163 * Attaches the encode function to the rise/fall interrupt edges of 00164 * channels A and B to perform X4 encoding. 00165 * 00166 * Attaches the index function to the rise interrupt edge of channel index 00167 * (if it is used) to count revolutions. 00168 * 00169 * @param channelA mbed pin for channel A input. 00170 * @param channelB mbed pin for channel B input. 00171 * @param index mbed pin for optional index channel input, 00172 * (pass NC if not needed). 00173 * @param pulsesPerRev Number of pulses in one revolution. 00174 * @param encoding The encoding to use. Uses X2 encoding by default. X2 00175 * encoding uses interrupts on the rising and falling edges 00176 * of only channel A where as X4 uses them on both 00177 * channels. 00178 */ 00179 QEI(PinName channelA, PinName channelB, PinName index, int pulsesPerRev, Encoding encoding = X2_ENCODING); 00180 00181 /** 00182 * Reset the encoder. 00183 * 00184 * Sets the pulses and revolutions count to zero. 00185 */ 00186 void reset(void); 00187 00188 /** 00189 * Read the state of the encoder. 00190 * 00191 * @return The current state of the encoder as a 2-bit number, where: 00192 * bit 1 = The reading from channel B 00193 * bit 2 = The reading from channel A 00194 */ 00195 int getCurrentState(void); 00196 00197 /** 00198 * Read the number of pulses recorded by the encoder. 00199 * 00200 * @return Number of pulses which have occured. 00201 */ 00202 int getPulses(void); 00203 00204 /** 00205 * Read the number of revolutions recorded by the encoder on the index channel. 00206 * 00207 * @return Number of revolutions which have occured on the index channel. 00208 */ 00209 int getRevolutions(void); 00210 00211 private: 00212 00213 /** 00214 * Update the pulse count. 00215 * 00216 * Called on every rising/falling edge of channels A/B. 00217 * 00218 * Reads the state of the channels and determines whether a pulse forward 00219 * or backward has occured, updating the count appropriately. 00220 */ 00221 void encode(void); 00222 00223 /** 00224 * Called on every rising edge of channel index to update revolution 00225 * count by one. 00226 */ 00227 void index(void); 00228 00229 Encoding encoding_; 00230 00231 InterruptIn channelA_; 00232 InterruptIn channelB_; 00233 InterruptIn index_; 00234 00235 bool firstZ; 00236 00237 int pulsesPerRev_; 00238 int prevState_; 00239 int currState_; 00240 00241 volatile int pulses_; 00242 volatile int revolutions_; 00243 00244 volatile int Zshift; 00245 00246 }; 00247 00248 #endif /* QEI_H */
Generated on Mon Aug 22 2022 06:14:15 by
