|  |  |  | @ -44,6 +44,7 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #include "Configuration.h"  | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #ifdef NUM_SERVOS | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #include <avr/interrupt.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <Arduino.h> | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -52,7 +53,6 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #define usToTicks(_us)    (( clockCyclesPerMicrosecond()* _us) / 8)     // converts microseconds to tick (assumes prescale of 8)  // 12 Aug 2009
 | 
			
		
	
		
			
				
					|  |  |  |  | #define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #define TRIM_DURATION       2                               // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | //#define NBR_TIMERS        (MAX_SERVOS / SERVOS_PER_TIMER)
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -74,19 +74,18 @@ uint8_t ServoCount = 0;                                     // the total number | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /************ static functions common to all instances ***********************/ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t *TCNTn, volatile uint16_t* OCRnA) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t *TCNTn, volatile uint16_t* OCRnA) { | 
			
		
	
		
			
				
					|  |  |  |  |   if (Channel[timer] < 0) | 
			
		
	
		
			
				
					|  |  |  |  |     *TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
 | 
			
		
	
		
			
				
					|  |  |  |  |   else { | 
			
		
	
		
			
				
					|  |  |  |  |     if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true ) | 
			
		
	
		
			
				
					|  |  |  |  |     if (SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive) | 
			
		
	
		
			
				
					|  |  |  |  |       digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,LOW); // pulse this channel low if activated
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   Channel[timer]++;    // increment to the next channel
 | 
			
		
	
		
			
				
					|  |  |  |  |   if (SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { | 
			
		
	
		
			
				
					|  |  |  |  |     *OCRnA = *TCNTn + SERVO(timer,Channel[timer]).ticks; | 
			
		
	
		
			
				
					|  |  |  |  |     if(SERVO(timer,Channel[timer]).Pin.isActive == true)     // check if activated
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (SERVO(timer,Channel[timer]).Pin.isActive)     // check if activated
 | 
			
		
	
		
			
				
					|  |  |  |  |       digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  |   else { | 
			
		
	
	
		
			
				
					|  |  |  | @ -100,54 +99,38 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // Interrupt handlers for Arduino
 | 
			
		
	
		
			
				
					|  |  |  |  |   #if defined(_useTimer1) | 
			
		
	
		
			
				
					|  |  |  |  | SIGNAL (TIMER1_COMPA_vect) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   handle_interrupts(_timer1, &TCNT1, &OCR1A); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  |     SIGNAL (TIMER1_COMPA_vect) { handle_interrupts(_timer1, &TCNT1, &OCR1A); } | 
			
		
	
		
			
				
					|  |  |  |  |   #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   #if defined(_useTimer3) | 
			
		
	
		
			
				
					|  |  |  |  | SIGNAL (TIMER3_COMPA_vect) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   handle_interrupts(_timer3, &TCNT3, &OCR3A); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  |     SIGNAL (TIMER3_COMPA_vect) { handle_interrupts(_timer3, &TCNT3, &OCR3A); } | 
			
		
	
		
			
				
					|  |  |  |  |   #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   #if defined(_useTimer4) | 
			
		
	
		
			
				
					|  |  |  |  | SIGNAL (TIMER4_COMPA_vect) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   handle_interrupts(_timer4, &TCNT4, &OCR4A); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  |     SIGNAL (TIMER4_COMPA_vect) { handle_interrupts(_timer4, &TCNT4, &OCR4A); } | 
			
		
	
		
			
				
					|  |  |  |  |   #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   #if defined(_useTimer5) | 
			
		
	
		
			
				
					|  |  |  |  | SIGNAL (TIMER5_COMPA_vect) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   handle_interrupts(_timer5, &TCNT5, &OCR5A); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  |     SIGNAL (TIMER5_COMPA_vect) { handle_interrupts(_timer5, &TCNT5, &OCR5A); } | 
			
		
	
		
			
				
					|  |  |  |  |   #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #elif defined WIRING | 
			
		
	
		
			
				
					|  |  |  |  | #else //!WIRING
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   // Interrupt handlers for Wiring
 | 
			
		
	
		
			
				
					|  |  |  |  |   #if defined(_useTimer1) | 
			
		
	
		
			
				
					|  |  |  |  | void Timer1Service() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   handle_interrupts(_timer1, &TCNT1, &OCR1A); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  |     void Timer1Service() { handle_interrupts(_timer1, &TCNT1, &OCR1A); } | 
			
		
	
		
			
				
					|  |  |  |  |   #endif | 
			
		
	
		
			
				
					|  |  |  |  |   #if defined(_useTimer3) | 
			
		
	
		
			
				
					|  |  |  |  | void Timer3Service() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   handle_interrupts(_timer3, &TCNT3, &OCR3A); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  |     void Timer3Service() { handle_interrupts(_timer3, &TCNT3, &OCR3A); } | 
			
		
	
		
			
				
					|  |  |  |  |   #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #endif //!WIRING
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void initISR(timer16_Sequence_t timer) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | static void initISR(timer16_Sequence_t timer) { | 
			
		
	
		
			
				
					|  |  |  |  |   #if defined(_useTimer1) | 
			
		
	
		
			
				
					|  |  |  |  |     if (timer == _timer1) { | 
			
		
	
		
			
				
					|  |  |  |  |       TCCR1A = 0;             // normal counting mode
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -206,36 +189,36 @@ static void initISR(timer16_Sequence_t timer) | 
			
		
	
		
			
				
					|  |  |  |  |   #endif | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void finISR(timer16_Sequence_t timer) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     //disable use of the given timer
 | 
			
		
	
		
			
				
					|  |  |  |  | #if defined WIRING   // Wiring
 | 
			
		
	
		
			
				
					|  |  |  |  | static void finISR(timer16_Sequence_t timer) { | 
			
		
	
		
			
				
					|  |  |  |  |   // Disable use of the given timer
 | 
			
		
	
		
			
				
					|  |  |  |  |   #if defined(WIRING) | 
			
		
	
		
			
				
					|  |  |  |  |     if (timer == _timer1) { | 
			
		
	
		
			
				
					|  |  |  |  |       #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) | 
			
		
	
		
			
				
					|  |  |  |  |     TIMSK1 &=  ~_BV(OCIE1A) ;  // disable timer 1 output compare interrupt
 | 
			
		
	
		
			
				
					|  |  |  |  |         TIMSK1 | 
			
		
	
		
			
				
					|  |  |  |  |       #else | 
			
		
	
		
			
				
					|  |  |  |  |     TIMSK &=  ~_BV(OCIE1A) ;  // disable timer 1 output compare interrupt
 | 
			
		
	
		
			
				
					|  |  |  |  |         TIMSK | 
			
		
	
		
			
				
					|  |  |  |  |       #endif | 
			
		
	
		
			
				
					|  |  |  |  |           &= ~_BV(OCIE1A);    // disable timer 1 output compare interrupt
 | 
			
		
	
		
			
				
					|  |  |  |  |       timerDetach(TIMER1OUTCOMPAREA_INT); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     else if (timer == _timer3) { | 
			
		
	
		
			
				
					|  |  |  |  |       #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) | 
			
		
	
		
			
				
					|  |  |  |  |     TIMSK3 &= ~_BV(OCIE3A);    // disable the timer3 output compare A interrupt
 | 
			
		
	
		
			
				
					|  |  |  |  |         TIMSK3 | 
			
		
	
		
			
				
					|  |  |  |  |       #else | 
			
		
	
		
			
				
					|  |  |  |  |     ETIMSK &= ~_BV(OCIE3A);    // disable the timer3 output compare A interrupt
 | 
			
		
	
		
			
				
					|  |  |  |  |         ETIMSK | 
			
		
	
		
			
				
					|  |  |  |  |       #endif | 
			
		
	
		
			
				
					|  |  |  |  |           &= ~_BV(OCIE3A);    // disable the timer3 output compare A interrupt
 | 
			
		
	
		
			
				
					|  |  |  |  |       timerDetach(TIMER3OUTCOMPAREA_INT); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | #else | 
			
		
	
		
			
				
					|  |  |  |  |   #else //!WIRING
 | 
			
		
	
		
			
				
					|  |  |  |  |     // For arduino - in future: call here to a currently undefined function to reset the timer
 | 
			
		
	
		
			
				
					|  |  |  |  |   #endif | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static boolean isTimerActive(timer16_Sequence_t timer) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | static boolean isTimerActive(timer16_Sequence_t timer) { | 
			
		
	
		
			
				
					|  |  |  |  |   // returns true if any servo is active on this timer
 | 
			
		
	
		
			
				
					|  |  |  |  |   for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { | 
			
		
	
		
			
				
					|  |  |  |  |     if(SERVO(timer,channel).Pin.isActive == true) | 
			
		
	
		
			
				
					|  |  |  |  |     if (SERVO(timer,channel).Pin.isActive) | 
			
		
	
		
			
				
					|  |  |  |  |       return true; | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  |   return false; | 
			
		
	
	
		
			
				
					|  |  |  | @ -244,8 +227,7 @@ static boolean isTimerActive(timer16_Sequence_t timer) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /****************** end of static functions ******************************/ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | Servo::Servo() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | Servo::Servo() { | 
			
		
	
		
			
				
					|  |  |  |  |   if ( ServoCount < MAX_SERVOS) { | 
			
		
	
		
			
				
					|  |  |  |  |     this->servoIndex = ServoCount++;                    // assign a servo index to this instance
 | 
			
		
	
		
			
				
					|  |  |  |  |     servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH);   // store default values  - 12 Aug 2009
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -254,13 +236,11 @@ Servo::Servo() | 
			
		
	
		
			
				
					|  |  |  |  |     this->servoIndex = INVALID_SERVO;  // too many servos
 | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | uint8_t Servo::attach(int pin) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | uint8_t Servo::attach(int pin) { | 
			
		
	
		
			
				
					|  |  |  |  |   return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | uint8_t Servo::attach(int pin, int min, int max) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | uint8_t Servo::attach(int pin, int min, int max) { | 
			
		
	
		
			
				
					|  |  |  |  |   if (this->servoIndex < MAX_SERVOS ) { | 
			
		
	
		
			
				
					|  |  |  |  |   #if defined(ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) | 
			
		
	
		
			
				
					|  |  |  |  |     if (pin > 0) this->pin = pin; else pin = this->pin; | 
			
		
	
	
		
			
				
					|  |  |  | @ -272,26 +252,20 @@ uint8_t Servo::attach(int pin, int min, int max) | 
			
		
	
		
			
				
					|  |  |  |  |     this->max = (MAX_PULSE_WIDTH - max) / 4; | 
			
		
	
		
			
				
					|  |  |  |  |     // initialize the timer if it has not already been initialized
 | 
			
		
	
		
			
				
					|  |  |  |  |     timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); | 
			
		
	
		
			
				
					|  |  |  |  |     if(isTimerActive(timer) == false) | 
			
		
	
		
			
				
					|  |  |  |  |       initISR(timer); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!isTimerActive(timer)) initISR(timer); | 
			
		
	
		
			
				
					|  |  |  |  |     servos[this->servoIndex].Pin.isActive = true;  // this must be set after the check for isTimerActive
 | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  |   return this->servoIndex; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void Servo::detach() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | void Servo::detach() { | 
			
		
	
		
			
				
					|  |  |  |  |   servos[this->servoIndex].Pin.isActive = false; | 
			
		
	
		
			
				
					|  |  |  |  |   timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); | 
			
		
	
		
			
				
					|  |  |  |  |   if(isTimerActive(timer) == false) { | 
			
		
	
		
			
				
					|  |  |  |  |     finISR(timer); | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  |   if (!isTimerActive(timer)) finISR(timer); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void Servo::write(int value) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   if(value < MIN_PULSE_WIDTH) | 
			
		
	
		
			
				
					|  |  |  |  |   {  // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
 | 
			
		
	
		
			
				
					|  |  |  |  | void Servo::write(int value) { | 
			
		
	
		
			
				
					|  |  |  |  |   if (value < MIN_PULSE_WIDTH) { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (value < 0) value = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     if (value > 180) value = 180; | 
			
		
	
		
			
				
					|  |  |  |  |     value = map(value, 0, 180, SERVO_MIN(),  SERVO_MAX()); | 
			
		
	
	
		
			
				
					|  |  |  | @ -299,12 +273,10 @@ void Servo::write(int value) | 
			
		
	
		
			
				
					|  |  |  |  |   this->writeMicroseconds(value); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void Servo::writeMicroseconds(int value) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | void Servo::writeMicroseconds(int value) { | 
			
		
	
		
			
				
					|  |  |  |  |   // calculate and store the values for the given channel
 | 
			
		
	
		
			
				
					|  |  |  |  |   byte channel = this->servoIndex; | 
			
		
	
		
			
				
					|  |  |  |  |   if( (channel < MAX_SERVOS) )   // ensure channel is valid
 | 
			
		
	
		
			
				
					|  |  |  |  |   { | 
			
		
	
		
			
				
					|  |  |  |  |   if (channel < MAX_SERVOS) {  // ensure channel is valid
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (value < SERVO_MIN())   // ensure pulse width is valid
 | 
			
		
	
		
			
				
					|  |  |  |  |       value = SERVO_MIN(); | 
			
		
	
		
			
				
					|  |  |  |  |     else if (value > SERVO_MAX()) | 
			
		
	
	
		
			
				
					|  |  |  | @ -320,25 +292,13 @@ void Servo::writeMicroseconds(int value) | 
			
		
	
		
			
				
					|  |  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | int Servo::read() // return the value as degrees
 | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   return  map( this->readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | int Servo::readMicroseconds() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   unsigned int pulsewidth; | 
			
		
	
		
			
				
					|  |  |  |  |   if( this->servoIndex != INVALID_SERVO ) | 
			
		
	
		
			
				
					|  |  |  |  |     pulsewidth = ticksToUs(servos[this->servoIndex].ticks)  + TRIM_DURATION ;   // 12 aug 2009
 | 
			
		
	
		
			
				
					|  |  |  |  |   else | 
			
		
	
		
			
				
					|  |  |  |  |     pulsewidth  = 0; | 
			
		
	
		
			
				
					|  |  |  |  | // return the value as degrees
 | 
			
		
	
		
			
				
					|  |  |  |  | int Servo::read() { return map( this->readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   return pulsewidth; | 
			
		
	
		
			
				
					|  |  |  |  | int Servo::readMicroseconds() { | 
			
		
	
		
			
				
					|  |  |  |  |   return (this->servoIndex == INVALID_SERVO) ? 0 : ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | bool Servo::attached() | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |   return servos[this->servoIndex].Pin.isActive ; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | bool Servo::attached() { return servos[this->servoIndex].Pin.isActive; } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
	
		
			
				
					|  |  |  | 
 |