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