UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:ground_control

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
code:ground_control [2008/04/24 09:05] laurencebcode:ground_control [2008/11/13 09:50] (current) laurenceb
Line 1: Line 1:
- This AVR code constantly checks the PWM input for pulse lenghtIf 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 guidanceUseful for UAVs, allowing control to be regained from the ground in the event of a faulty control algorthym.+===== Input capture based version ===== 
 +This uses the input capture function on timer1 (atmega168)The ICNC1 bit in the TCCR1B register need to be set to enable oversampling to give more noise tolerance. A second function running approx every 20ms is needed to decrement counter by two and check if counter>=30If this is the case there is a valid pwm stream and the diff variable can be used to set the pwm output
  
 +==== Header ====
 +<code c>
 +void enable_ground_control(); //enables the input capture interrupt
 +void disable_ground_control(); //disables input capture interrupt
 +#define PULSE_MIN (s16)(0.001*(float)F_CPU/16.0) //pwm must be in the range 1 to 2 ms
 +#define PULSE_MAX (s16)(0.002*(float)F_CPU/16.0) //due to the bit shift we divide by 16
 +#define GROUND_LED_ON PORTD|=(1<<3)
 +#define GROUND_LED_OFF PORTD&=~(1<<3)
 +#define GROUND_LED_SET PORTD&(1<<3)
 +void run_ground_control();
 +</code>
 +
 +
 +====Main code===
 +
 +<code c>
 +#ifdef GROUND
 +#include "main.h"
 +extern volatile u08 counter; //globals
 +extern volatile u16 diff;
 + 
 + 
 +ISR(TIMER1_CAPT_vect)
 +{
 + static u16 start;
 + if(TCCR1B&0x40) //start of a pulse
 + {
 + TCCR1B&=~0x40; //set to trigger on falling edge
 + start=ICR1; //record start of the pulse
 + }
 + else
 + {
 + TCCR1B|=0x40; //set to trigger on rising edge
 + if(!(counter&0x80)) //the lock bit isn't set, so we are free to run
 + {
 + diff=ICR1; //set the global volatile s16 diff
 + if(start>diff) //our pwm pulse spans a timer overflow
 + {
 + diff+=TOP_COUNT;
 + }
 + diff-=start;
 + if(diff>PULSE_MIN && diff<PULSE_MAX) //test against criterion
 + {
 + if((counter&(~0x80))<30) //30 consecutive  pulses
 + {
 + counter+=3; //the 20ms timer1 overflow subtracts 2 from counter
 + }
 + }
 + else
 + {
 + counter&=0x80; //set the last 7 bits to zero
 + }
 + }
 + }
 +}
 +
 +void run_ground_control()
 +{
 + if((~0x80&counter)>=28)
 + {
 + counter|=0x80; //lock the diff variable using the counter flag bit
 + OCR1B=diff;
 + counter&=~0x80;
 + GROUND_LED_ON;
 + }
 + else
 + {
 + GROUND_LED_OFF;
 + }
 + if(counter&~0x80) //if the counter variable >0, decrement by 2
 + counter-=2;
 +}
 +
 +void enable_ground_control()
 +{
 + TIMSK1|=(1<<ICIE1);
 + counter=0;
 +}
 +
 +void disable_ground_control()
 +{
 + TIMSK1&=~(1<<ICIE1);
 + GROUND_LED_OFF;
 + counter=0;
 + diff=0;
 +}
 +#endif
 +</code>
 +
 +
 +
 +===== Pin change based version =====
 +
 +
 + 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 is 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 ===== ===== ground.h =====
-<code c>#define pwm_record_factor (u08)F_CPU/500.0/256.0 +<code c>#define pwm_record_factor ((float)F_CPU*0.0005/256.0) //500us 
-#define lower_pwm_bound pwm_record_factor*4.25 //valid pwm limits +#define lower_pwm_bound (u08)(pwm_record_factor*4.25) //valid pwm limits 
-#define upper_pwm_bound pwm_record_factor*1.75+#define upper_pwm_bound (u08)(pwm_record_factor*1.75)
 #define GROUND #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 enable_ground_control();
 void disable_ground_control(); void disable_ground_control();
 </code> </code>
- 
  
 ===== ground.c ===== ===== ground.c =====
  
-<code c> +<code c>#include "main.h"
-#include "main.h"+
 #include "ground.h" #include "ground.h"
 + 
 volatile u08 pwm_counter=0x00; volatile u08 pwm_counter=0x00;
 volatile u08 pwm_period=0x00; volatile u08 pwm_period=0x00;
 + 
 ISR(PCINT1_vect) 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;  static u08 pulse;
- if(PORTC & 0x01) //start of C.0 pulse+ if(check_input) //start of pulse
  {  {
  TCNT0=0x00; //reset timer at start of C.0 pulse  TCNT0=0x00; //reset timer at start of C.0 pulse
Line 49: Line 150:
  pwm_counter=0x00;  pwm_counter=0x00;
  }  }
- } 
- if(pwm_counter==0x0A) //a stream of valid pwm 
- { 
- cbi(TCCR1A,COM1A1); //turn off PWM output to servo 
- PORTB=(PORTB & ~0x03)|(PORTC & 0x03); //move PORTC 0,1 to PORTB 0,1 
  }  }
 } }
 + 
 ISR(TIMER0_OVF_vect) ISR(TIMER0_OVF_vect)
 { {
Line 62: Line 158:
  pwm_counter=0x00; //with valid pwm, there will be no overflows  pwm_counter=0x00; //with valid pwm, there will be no overflows
 } }
 + 
 void enable_ground_control() void enable_ground_control()
 { {
Line 68: Line 164:
  sbi(PCICR, PCIE1); //Pin change interrupts on  sbi(PCICR, PCIE1); //Pin change interrupts on
 } }
 + 
 void disable_ground_control() void disable_ground_control()
 { {
code/ground_control.1209027932.txt.gz · Last modified: 2008/07/19 23:31 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki