Simple PID example for LabVIEW

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers QEI.h Source File

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 */