|
| 1 | +/* |
| 2 | + Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 |
| 3 | + Copyright (c) 2009 Michael Margolis. All right reserved. |
| 4 | +
|
| 5 | + This library is free software; you can redistribute it and/or |
| 6 | + modify it under the terms of the GNU Lesser General Public |
| 7 | + License as published by the Free Software Foundation; either |
| 8 | + version 2.1 of the License, or (at your option) any later version. |
| 9 | +
|
| 10 | + This library is distributed in the hope that it will be useful, |
| 11 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | + Lesser General Public License for more details. |
| 14 | +
|
| 15 | + You should have received a copy of the GNU Lesser General Public |
| 16 | + License along with this library; if not, write to the Free Software |
| 17 | + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 18 | +*/ |
| 19 | + |
| 20 | +/* |
| 21 | + A servo is activated by creating an instance of the Servo class passing |
| 22 | + the desired pin to the attach() method. |
| 23 | + The servos are pulsed in the background using the value most recently |
| 24 | + written using the write() method. |
| 25 | +
|
| 26 | + Note that analogWrite of PWM on pins associated with the timer are |
| 27 | + disabled when the first servo is attached. |
| 28 | + Timers are seized as needed in groups of 12 servos - 24 servos use two |
| 29 | + timers, 48 servos will use four. |
| 30 | + The sequence used to sieze timers is defined in timers.h |
| 31 | +
|
| 32 | + The methods are: |
| 33 | +
|
| 34 | + Servo - Class for manipulating servo motors connected to Arduino pins. |
| 35 | +
|
| 36 | + attach(pin ) - Attaches a servo motor to an i/o pin. |
| 37 | + attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds |
| 38 | + default min is 544, max is 2400 |
| 39 | +
|
| 40 | + write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) |
| 41 | + writeMicroseconds() - Sets the servo pulse width in microseconds |
| 42 | + read() - Gets the last written servo pulse width as an angle between 0 and 180. |
| 43 | + readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release) |
| 44 | + attached() - Returns true if there is a servo attached. |
| 45 | + detach() - Stops an attached servos from pulsing its i/o pin. |
| 46 | + */ |
| 47 | + |
| 48 | +#ifndef Servo_h |
| 49 | +#define Servo_h |
| 50 | + |
| 51 | +#include <inttypes.h> |
| 52 | + |
| 53 | +/* |
| 54 | + * Defines for 16 bit timers used with Servo library |
| 55 | + * |
| 56 | + * If _useTimerX is defined then TimerX is a 16 bit timer on the current board |
| 57 | + * timer16_Sequence_t enumerates the sequence that the timers should be allocated |
| 58 | + * _Nbr_16timers indicates how many 16 bit timers are available. |
| 59 | + */ |
| 60 | + |
| 61 | +// Architecture specific include |
| 62 | +#if defined(ARDUINO_ARCH_AVR) |
| 63 | +#include "avr/ServoTimers.h" |
| 64 | +#elif defined(ARDUINO_ARCH_SAM) |
| 65 | +#include "sam/ServoTimers.h" |
| 66 | +#elif defined(ARDUINO_ARCH_SAMD) |
| 67 | +#include "samd/ServoTimers.h" |
| 68 | +#elif defined(ARDUINO_ARCH_STM32F4) |
| 69 | +#include "stm32f4/ServoTimers.h" |
| 70 | +#elif defined(ARDUINO_ARCH_NRF52) |
| 71 | +#include "nrf52/ServoTimers.h" |
| 72 | +#elif defined(ARDUINO_ARCH_STM32) |
| 73 | +#include "stm32/ServoTimers.h" |
| 74 | +#else |
| 75 | +#error "This library only supports boards with an AVR, SAM, SAMD, NRF52, STM32F4 or STM32 processor." |
| 76 | +#endif |
| 77 | + |
| 78 | +#define Servo_VERSION 2 // software version of this library |
| 79 | + |
| 80 | +#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo |
| 81 | +#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo |
| 82 | +#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached |
| 83 | +#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds |
| 84 | + |
| 85 | +#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer |
| 86 | +#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER) |
| 87 | + |
| 88 | +#define INVALID_SERVO 255 // flag indicating an invalid servo index |
| 89 | + |
| 90 | +#if !defined(ARDUINO_ARCH_STM32F4) |
| 91 | + |
| 92 | +typedef struct { |
| 93 | + uint8_t nbr :6 ; // a pin number from 0 to 63 |
| 94 | + uint8_t isActive :1 ; // true if this channel is enabled, pin not pulsed if false |
| 95 | +} ServoPin_t ; |
| 96 | + |
| 97 | +typedef struct { |
| 98 | + ServoPin_t Pin; |
| 99 | + volatile unsigned int ticks; |
| 100 | +} servo_t; |
| 101 | + |
| 102 | +class Servo |
| 103 | +{ |
| 104 | +public: |
| 105 | + Servo(); |
| 106 | + uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure |
| 107 | + uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. |
| 108 | + void detach(); |
| 109 | + void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds |
| 110 | + void writeMicroseconds(int value); // Write pulse width in microseconds |
| 111 | + int read(); // returns current pulse width as an angle between 0 and 180 degrees |
| 112 | + int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release) |
| 113 | + bool attached(); // return true if this servo is attached, otherwise false |
| 114 | +private: |
| 115 | + uint8_t servoIndex; // index into the channel data for this servo |
| 116 | + int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH |
| 117 | + int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH |
| 118 | +}; |
| 119 | + |
| 120 | +#endif |
| 121 | +#endif |
0 commit comments