Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

encoder.h

Go to the documentation of this file.
00001 /*! \file encoder.h \brief Quadrature Encoder reader/driver. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'encoder.h'
00005 // Title        : Quadrature Encoder reader/driver
00006 // Author       : Pascal Stang - Copyright (C) 2003-2004
00007 // Created      : 2003.01.26
00008 // Revised      : 2004.06.25
00009 // Version      : 0.3
00010 // Target MCU   : Atmel AVR Series
00011 // Editor Tabs  : 4
00012 //
00013 /// \ingroup driver_hw
00014 /// \defgroup encoder Quadrature Encoder Driver (encoder.c)
00015 /// \code #include "encoder.h" \endcode
00016 /// \par Overview
00017 ///     This library allows easy interfacing of standard quadrature encoders
00018 ///     (used for sensing shaft rotational position and speed) to the Atmel
00019 ///     AVR-series processors. The library uses external interrupts to sense
00020 ///     and keep track of the encoder's movements. The library is extendable
00021 ///     with the maximum number of encoders equal to the total number of
00022 ///     external interrupts available on the target AVR processor.
00023 ///     
00024 ///     \note Due to the wide range of external interrupt capability on
00025 ///     AVR processors, it is difficult for this library to automatically
00026 ///     adapt to different processors.  For this reason, much of the
00027 ///     configuration responsibility has been left with the user.  See
00028 ///     the encoderconf.h configuration file.
00029 //
00030 /// \par Operation:
00031 ///     Quadrature encoders have two digital outputs usually called PhaseA and
00032 /// PhaseB.  When the encoder rotates, PhaseA and PhaseB produce square wave
00033 /// pulses where each pulse represents a fraction of a turn of the encoder
00034 /// shaft.  Encoders are rated for a certain number of pulses (or counts) per
00035 /// complete revolution of the shaft.  Common counts/revolution specs are 50,
00036 /// 100,128,200,250,256,500,etc.  By counting the number of pulses output on
00037 /// one of the phases starting from time0, you can calculate the total
00038 /// rotational distance the encoder has traveled.
00039 /// 
00040 /// Often, however, we want current position not just total distance traveled.
00041 /// For this it is necessary to know not only how far the encoder has traveled,
00042 /// but also which direction it was going at each step of the way.  To do this
00043 /// we need to use both outputs (or phases) of the quadrature encoder.
00044 ///
00045 /// The pulses from PhaseA and PhaseB on quadrature encoders are always aligned
00046 /// 90 degrees out-of-phase (otherwise said: 1/4 wavelength apart).  This
00047 /// special phase relationship lets us extract both the distance and direction
00048 /// the encoder has rotated from the outputs.
00049 ///
00050 /// To do this, consider Phase A to be the distance counter.  On each rising
00051 /// edge of PhaseA we will count 1 "tic" of distance, but we need to know the
00052 /// direction.  Look at the quadrature waveform plot below.  Notice that when
00053 /// we travel forward in time (left->right), PhaseB is always low (logic 0) at
00054 /// the rising edge of PhaseA.  When we travel backwards in time (right->left),
00055 /// PhaseB is always high (logic 1) at the rising edge of PhaseA.  Note that
00056 /// traveling forward or backwards in time is the same thing as rotating
00057 /// forwards or bardwards. Thus, if PhaseA is our counter, PhaseB indicates
00058 /// direction.
00059 ///
00060 /// Here is an example waveform from a quadrature encoder:
00061 /*
00062 ///                /---\   /---\   /---\   /---\   /---\   /---\
00063 ///  Phase A:      |   |   |   |   |   |   |   |   |   |   |   |
00064 ///             ---/   \---/   \---/   \---/   \---/   \---/   \-
00065 ///             -\   /---\   /---\   /---\   /---\   /---\   /---
00066 ///  Phase B:    |   |   |   |   |   |   |   |   |   |   |   |
00067 ///              \---/   \---/   \---/   \---/   \---/   \---/
00068 ///  Time:    <--------------------------------------------------->
00069 ///  Rotate FWD: >----------------------------------------------> 
00070 ///  Rotate REV: <----------------------------------------------<
00071 */
00072 /// To keep track of the encoder position in software, we connect PhaseA to an
00073 /// external processor interrupt line, and PhaseB to any I/O pin.  We set up
00074 /// the external interrupt to trigger whenever PhaseA produces a rising edge.
00075 /// When a rising edge is detected, our interrupt handler function is executed.
00076 /// Inside the handler function, we quickly check the PhaseB line to see if it
00077 /// is high or low.  If it is high, we increment the encoder's position
00078 /// counter, otherwise we decrement it.  The encoder position counter can be
00079 /// read at any time to find out the current position.
00080 //
00081 // NOTE: This code is currently below version 1.0, and therefore is considered
00082 // to be lacking in some functionality or documentation, or may not be fully
00083 // tested.  Nonetheless, you can expect most functions to work.
00084 //
00085 // This code is distributed under the GNU Public License
00086 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00087 //
00088 //*****************************************************************************
00089 
00090 #ifndef ENCODER_H
00091 #define ENCODER_H
00092 
00093 #include "global.h"
00094 
00095 // include encoder configuration file
00096 #include "encoderconf.h"
00097 
00098 // constants/macros/typdefs
00099 
00100 // defines for processor compatibility
00101 // chose proper Interrupt Mask (IMSK)
00102 #ifdef EIMSK
00103     #define IMSK    EIMSK   // for processors mega128, mega64
00104 #endif
00105 #ifdef GICR
00106     #define IMSK    GICR    // for mega16,32,etc
00107 #endif
00108 // default
00109 #ifndef IMSK
00110     #define IMSK    GIMSK   // for other processors 90s8515, mega163, etc
00111 #endif
00112 
00113 
00114 //! Encoder state structure
00115 //   stores the position and other information from each encoder
00116 typedef struct struct_EncoderState
00117 {   
00118     s32 position;       ///< position
00119 } EncoderStateType;
00120 
00121 
00122 // functions
00123 
00124 //! encoderInit() initializes hardware and encoder position readings
00125 //      Run this init routine once before using any other encoder function.
00126 void encoderInit(void);
00127 
00128 //! encoderOff() disables hardware and stops encoder position updates
00129 void encoderOff(void);
00130 
00131 //! encoderGetPosition() reads the current position of the encoder 
00132 s32 encoderGetPosition(u08 encoderNum);
00133 
00134 //! encoderSetPosition() sets the current position of the encoder
00135 void encoderSetPosition(u08 encoderNum, s32 position);
00136 
00137 #endif

Generated on Sun Oct 29 03:41:06 2006 for Procyon AVRlib by  doxygen 1.4.2