00001 /* 00002 Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 00003 Copyright (c) 2009 Michael Margolis. All right reserved. 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 00020 /* 00021 00022 A servo is activated by creating an instance of the Servo class passing the desired pin to the attach() method. 00023 The servos are pulsed in the background using the value most recently written using the write() method 00024 00025 Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached. 00026 Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four. 00027 The sequence used to sieze timers is defined in timers.h 00028 00029 The methods are: 00030 00031 Servo - Class for manipulating servo motors connected to Arduino pins. 00032 00033 attach(pin ) - Attaches a servo motor to an i/o pin. 00034 attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds 00035 default min is 544, max is 2400 00036 00037 write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) 00038 writeMicroseconds() - Sets the servo pulse width in microseconds 00039 read() - Gets the last written servo pulse width as an angle between 0 and 180. 00040 readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release) 00041 attached() - Returns true if there is a servo attached. 00042 detach() - Stops an attached servos from pulsing its i/o pin. 00043 */ 00044 00045 #ifndef Servo_h 00046 #define Servo_h 00047 00048 #include <inttypes.h> 00049 00050 /* 00051 * Defines for 16 bit timers used with Servo library 00052 * 00053 * If _useTimerX is defined then TimerX is a 16 bit timer on the curent board 00054 * timer16_Sequence_t enumerates the sequence that the timers should be allocated 00055 * _Nbr_16timers indicates how many 16 bit timers are available. 00056 * 00057 */ 00058 00059 // Say which 16 bit timers can be used and in what order 00060 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 00061 #define _useTimer5 00062 #define _useTimer1 00063 #define _useTimer3 00064 #define _useTimer4 00065 typedef enum { _timer5, _timer1, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t ; 00066 00067 #elif defined(__AVR_ATmega32U4__) 00068 #define _useTimer3 00069 #define _useTimer1 00070 typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ; 00071 00072 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 00073 #define _useTimer3 00074 #define _useTimer1 00075 typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ; 00076 00077 #elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__) 00078 #define _useTimer3 00079 #define _useTimer1 00080 typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ; 00081 00082 #else // everything else 00083 #define _useTimer1 00084 typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t ; 00085 #endif 00086 00087 #define Servo_VERSION 2 // software version of this library 00088 00089 #define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo 00090 #define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo 00091 #define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached 00092 #define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds 00093 00094 #define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer 00095 #define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER) 00096 00097 #define INVALID_SERVO 255 // flag indicating an invalid servo index 00098 00099 typedef struct { 00100 uint8_t nbr :6 ; // a pin number from 0 to 63 00101 uint8_t isActive :1 ; // true if this channel is enabled, pin not pulsed if false 00102 } ServoPin_t ; 00103 00104 typedef struct { 00105 ServoPin_t Pin; 00106 unsigned int ticks; 00107 } servo_t; 00108 00109 class Servo 00110 { 00111 public: 00112 Servo(); 00113 uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure 00114 uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. 00115 void detach(); 00116 void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds 00117 void writeMicroseconds(int value); // Write pulse width in microseconds 00118 int read(); // returns current pulse width as an angle between 0 and 180 degrees 00119 int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release) 00120 bool attached(); // return true if this servo is attached, otherwise false 00121 private: 00122 uint8_t servoIndex; // index into the channel data for this servo 00123 int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH 00124 int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH 00125 }; 00126 00127 #endif