Main Page   Data Structures   File List   Data Fields   Globals  

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

Generated on Fri Aug 1 10:42:41 2003 for Procyon AVRlib by doxygen1.2.18