code:ground_control
This is an old revision of the document!
This AVR code constantly checks the PWM input for pulse lenght. If a stream of 10 pulses are detected that match the criterion, the input PWM in routed to the output. A single failing PWM pulse will cause control to revert back to internal guidance. Useful for UAVs, allowing control to be regained from the ground in the event of a faulty control algorthym.
ground.h
#define pwm_record_factor ((float)F_CPU*0.0005/256.0) //500us #define lower_pwm_bound (u08)(pwm_record_factor*4.25) //valid pwm limits #define upper_pwm_bound (u08)(pwm_record_factor*1.75) #define GROUND #define check_input PORTC & 0x01 #define copy_pwm PORTB=(PORTB & ~0x03)|(PORTC & 0x03); //move PORTC 0,1 to PORTB 0,1 void enable_ground_control(); void disable_ground_control();
ground.c
#include "main.h" #include "ground.h" volatile u08 pwm_counter=0x00; volatile u08 pwm_period=0x00; ISR(PCINT1_vect) { if(pwm_counter==0x0A) //a stream of valid pwm { cbi(TCCR1A,COM1A1); //turn off PWM output to servo copy_pwm; } static u08 pulse; if(check_input) //start of pulse { TCNT0=0x00; //reset timer at start of C.0 pulse pulse=TRUE; } else if(pulse) //end of C.0 pulse { pulse=FALSE; if(TCNT0>upper_pwm_bound && TCNT0<lower_pwm_bound) //valid pwm { if(pwm_counter<0x0A) { pwm_counter++; } else { pwm_period=TCNT0; //store the pwm period, the kalman filter will like it! } } else { sbi(TCCR1A,COM1A1); //reenable the PWM pwm_counter=0x00; } } } ISR(TIMER0_OVF_vect) { sbi(TCCR1A,COM1A1); //reenable the PWM pwm_counter=0x00; //with valid pwm, there will be no overflows } void enable_ground_control() { sbi(TIMSK0, TOIE0); //Timer0 interrupts on sbi(PCICR, PCIE1); //Pin change interrupts on } void disable_ground_control() { cbi(TIMSK0, TOIE0); //Timer0 interrupts on cbi(PCICR, PCIE1); pwm_counter=0x00; //Pin change interrupts on }
code/ground_control.1216510405.txt.gz · Last modified: 2008/10/30 05:18 (external edit)