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