I'd just like to share some code to read a PPM signal and move a servo without jitter like other methods do. In this all signal processing is done with hardware interrupts and the result is a clean servo movement like it's soupposed to be. The pulseIn() and servo library don't produce such good results. My solution combines two codes, one I found here http://diydrones.com/profiles/blogs/705844:BlogPost:39393?id=705844%3ABlogPost%3A39393, and some from Arducopter source code. I made it for atmega328. The downside is we can use only one servo on pin 10 due to the limitations of atmega328.
unsigned int serinp[8]; //servo positions
int pulse = 0;
void setup_timer1(){
//WGM -> Fast PWM
//Prescaler -> 1/8
//Compare Output Mode - > non-inverting mode
//Input capture interrupt enable
TIMSK1 &= ~( _BV(TOIE1) | _BV(ICIE1) | _BV(OCIE1A) | _BV(OCIE1B));
TCCR1B &= ~(_BV(ICNC1));
TCCR1A |= _BV(WGM11) | _BV(WGM10) | _BV(COM1A1) | _BV(COM1B1);
TCCR1B |= _BV(WGM12) | _BV(WGM13) | _BV(ICES1);
TCCR1B |= _BV(CS11);
TCCR1B &= ~( _BV(CS12) | _BV(CS10) );
TCCR1A &= ~( _BV(COM1A0) | _BV(COM1B0));
TIMSK1 |= (1<<ICIE1);
OCR1A = 0xFFFF;
OCR1B = 0x0;
}
void setup()
{
pinMode(8, INPUT); //ppm input
pinMode(10, OUTPUT); //servo output
setup_timer1();
Serial.begin(38400);
}
void loop()
{
pulse = serinp[2]/2; //PPM channel2. divide by 2 to get real pulsewidth
setServoPulse(pulse);
for(int i = 0; i < 8; i++) //display all channels
{
Serial.print((serinp[i]/2));
Serial.print(" ");
}
Serial.println();
}
void setServoPulse(int pulseWidth)
{
pulseWidth *= 2;
if(pulseWidth > 1800 && pulseWidth < 4200) //servo pulse 900-2100
{
OCR1B = pulseWidth; //pin D10(PB2)
}
}
ISR(TIMER1_CAPT_vect){
static unsigned int lasticr; //icr at last caputre
static unsigned char cserinp; //current input servo
unsigned int licr;
licr = ICR1 - lasticr;
lasticr = ICR1;
if(licr > 5000)
{ //pulse too long, means start of new frame
cserinp=0;
}
else if(licr > 1000)
{
//pulse good, take reading, go to next channel
serinp[cserinp]=licr;
if(cserinp < 8)
{
cserinp++;
}
}
else{
//too short, nothing to see here
}
}