Quadcopter control - WIP
Dependencies: ADXL345_I2C2 ITG32003 USBDevice mbed
main.cpp
- Committer:
- SED9008
- Date:
- 2013-10-22
- Revision:
- 1:939b3a2453a6
- Parent:
- 0:b888fb67c9cf
File content as of revision 1:939b3a2453a6:
#include "mbed.h" #include "ADXL345_I2C.h" #include "ITG3200.h" #define PI 3.14159265358979f #define FILTER_FREQ 800 #define FILTER_SPLIT 0.95 #define ANGLE_SAMPLES 8 //Pin Defines DigitalOut led(LED1); Serial pc(USBTX,USBRX); PwmOut m0(p21); PwmOut m1(p22); PwmOut m2(p23); PwmOut m3(p24); ADXL345_I2C accelerometer(p9, p10); ITG3200 gyroscope(p9, p10); Ticker filter_tick; Ticker debug_tick; //Prototypes void accelSetup(void); void accelSample(void); void accelCal(int samples); void accelAngle(void); void gyroSetup(void); void gyroSample(void); void gyroCal(int samples); void angleIni(void); //Vars float accel[3]; float accel_offset[3]; float gyro[3]; float gyro_offset[3]; float angle[2]; float angle_buf[2]; float angle_sam[2][ANGLE_SAMPLES]; float last_sample[2]; int buf_cnt = 0; void filter(void){ gyroSample(); accelSample(); accelAngle(); for(int h=0;h<2;h++){ float tmpf = (float)FILTER_SPLIT*(angle[h]+(gyro[h]/(float)FILTER_FREQ))+(1-(float)FILTER_SPLIT)*accel[h]; angle_buf[h] += tmpf - angle_sam[h][buf_cnt]; angle_sam[h][buf_cnt] = tmpf; angle[h] = angle_buf[h]/ANGLE_SAMPLES; } if(buf_cnt++ >= ANGLE_SAMPLES-1) buf_cnt = 0; led = !led; } void debug(void){ pc.printf("x:%6.3f y:%6.3f\n\r",angle[0],angle[1]); } int main() { accelSetup(); gyroSetup(); gyroCal(100); pc.printf("Calibrated\n\r"); while(1) if(pc.readable()) break; angleIni(); pc.printf("x:%5.3f y:%5.3f\n\r",angle[0],angle[1]); wait(0.5); pc.printf("%d - %d\n\r",(int)(1000000/FILTER_FREQ),ANGLE_SAMPLES); wait(0.5); debug_tick.attach(&debug, 0.1); filter_tick.attach_us(&filter, (int)(1000000/FILTER_FREQ)); while(1) { // pc.printf("x:%5.3f y:%5.3f \n\r",angle[0],angle[1]); // wait_us(1000); } } void accelSetup(void) { accelerometer.setPowerControl(0x00); //Go into standby mode to configure the device. accelerometer.setDataFormatControl(0x0B); //Full resolution, +/-16g, 4mg/LSB. accelerometer.setDataRate(ADXL345_200HZ); //200Hz data rate. accelerometer.setPowerControl(0x08); //Measurement mode. wait_ms(22); //See http://www.analog.com/static/imported-files/application_notes/AN-1077.pdf } void accelSample(void){ int readings[3]; accelerometer.getOutput(readings); for(int h=0;h<3;h++) accel[h] = ((float)(int16_t)readings[h]/256)-accel_offset[h]; } void accelCal(int samples){ float temp[3] = {0,0,0}; for(int h=0;h<=samples;h++){ accelSample(); for(int j=0;j<=2;j++) temp[j] += accel[j]; } for(int h=0;h<=2;h++) accel_offset[h] = temp[h]/samples; accel_offset[2] -= 1; } void accelAngle(void){ accel[0] = atan2(accel[2],accel[0])*(180/(float)PI)-90; accel[1] = atan2(accel[2],accel[1])*(180/(float)PI)-90; } void gyroSetup(void){ gyroscope.setLpBandwidth(LPFBW_42HZ); //Set highest bandwidth. wait_ms(100); } void gyroSample(void){ gyro[0] = (gyroscope.getGyroX()-gyro_offset[0])/14.375; gyro[1] = (gyroscope.getGyroY()-gyro_offset[1])/14.375; gyro[2] = (gyroscope.getGyroZ()-gyro_offset[2])/14.375; } void gyroCal(int samples){ int temp[3] = {0,0,0}; for(int h=0;h<=samples;h++){ temp[0] += gyroscope.getGyroX(); temp[1] += gyroscope.getGyroY(); temp[2] += gyroscope.getGyroZ(); } for(int h=0;h<=2;h++) gyro_offset[h] = temp[h]/samples; } void angleIni(void){ for(int h=0;h<2;h++) angle_buf[h] = 0; for(int h=0;h<ANGLE_SAMPLES;h++){ accelSample(); accelAngle(); for(int j=0;j<2;j++){ angle_buf[j] += accel[j]; angle_sam[j][h] = accel[j]; } } for(int h=0;h<2;h++) angle[h] = angle_buf[h]/ANGLE_SAMPLES; }