00001 /* 00002 MegaServo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 0.1 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 This library uses 16 bit timers to drive up to 12 servos on each timer. 00022 It uses interrupts so no explicit refresh activity is required. 00023 The usage and method naming is similar to the Arduino servo library http://www.arduino.cc/en/Reference/Servo 00024 except that it support up to 48 servos on a Mega (12 on a standard Arduino). 00025 Also pulse widths can be in microseconds or degrees - 00026 write() treats parameters less than 200 as degrees, larger values are treated as milliseconds. 00027 00028 00029 A servo is activated by creating an instance of the Servo class passing the desired pin to the attach() method. 00030 The servos are pulsed in the background using the value most recently written using the write() method 00031 00032 Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached. 00033 Timers are siezed as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four. 00034 00035 The methods are: 00036 00037 MegaServo - Class for manipulating servo motors connected to Arduino pins. 00038 00039 attach(pin ) - Attaches a servo motor to an i/o pin. 00040 attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds 00041 default min is 544, max is 2400 00042 00043 write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) 00044 writeMicroseconds() - Sets the servo pulse width in microseconds 00045 read() - Gets the last written servo pulse width as an angle between 0 and 180. 00046 readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release) 00047 attached() - Returns true if there is a servo attached. 00048 detach() - Stops an attached servos from pulsing its i/o pin. 00049 */ 00050 00051 #ifndef MegaServo_h 00052 #define MegaServo_h 00053 00054 #include <inttypes.h> 00055 00056 #define MegaServo_VERSION 2 // software version of this library 00057 00058 #define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo 00059 #define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo 00060 #define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached 00061 #define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds 00062 00063 #if defined(__AVR_ATmega1280__) 00064 #define MAX_SERVOS 48 // the maximum number of servos (valid range is from 1 to 48) 00065 #else 00066 #define MAX_SERVOS 12 // this library supports up to 12 on a standard Arduino 00067 #endif 00068 00069 #define INVALID_SERVO 255 // flag indicating an invalid servo index 00070 00071 typedef struct { 00072 uint8_t nbr :6 ; // a pin number from 0 to 63 00073 uint8_t isActive :1 ; // true if this channel is enabled, pin not pulsed if false 00074 } ServoPin_t ; 00075 00076 typedef struct { 00077 ServoPin_t Pin; 00078 unsigned int ticks; 00079 int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH 00080 int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH 00081 } servo_t; 00082 00083 class MegaServo 00084 { 00085 public: 00086 // constructor: 00087 MegaServo(); 00088 00089 uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure 00090 uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. 00091 void detach(); 00092 void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds 00093 void writeMicroseconds(int value);// Write pulse width in microseconds 00094 int read(); // returns current pulse width as an angle between 0 and 180 degrees 00095 int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release) 00096 bool attached(); // return true if this servo is attached, otherwise false 00097 private: 00098 uint8_t servoIndex; // index into the channel data for this servo 00099 }; 00100 00101 #endif