Here's an example of using the 16-bit timer in "Fast PWM mode" to drive a single servo on D10, this runs automagically in the background independently of any interrupts or loop() code other than you need to update OCR1B if you want a new servo position. In the example I've used a pot on A2 to set the servo positon.
Note that at 16mhz and with a divide by 8 prescaler, the resolution is 0.5uS and consequently
the timing value for the required servo position in OCR1B is between 2000 to 4000 which is 1000uS to 2000uS, doubled for the .5uS clock.
The framelength value of 40000 in OCR1A (20ms doubled for .5uS clock) is left alone.
// Using the 16-bit timer in "Fast PWM mode" to drive a single servo on D10
// Runs independently of any loop() code or interrupts
// Servo position OCR1B=2000 to 4000 (1000 to 2000 doubled for .5uS clock)
// Framelength is OCR1A=40000 (20ms doubled for .5uS clock)
void setup() {
TCCR1A = 0;
TCCR1B = 0;
TIFR1 |= (1 << OCF1A); // clear any pending interrupts;
TCCR1A |= (1 << COM1B1); // Toggle on B compare
TCCR1A |= (1 << WGM10) | (1 << WGM11); // Fast PWM mode, TOP = OCR1A
TCCR1B |= (1 << WGM12) | (1 << WGM13); // Fast PWM mode, TOP = OCR1A
TCCR1B |= (1 << CS11); // 8 prescaler
DDRB |= (1 << DDB2); //turn on output pin 10 = OC1B
OCR1A = 40000; // Frame rate 20ms - doubled for /8 prescaler
OCR1B = 3000; // initial servo pulse of 1500us - doubled for /8 prescaler
}
void loop(){
// in loop, all you need to do is to set OCR1B to double the required servo position,
// ie neutral=3000 for 1500uS. For example:
OCR1B=map(analogRead(2),0,1023,2000,4000);
}
Have fun
Cheers
Phil