![](/media/cache/profiles/1688692e577cac3d17b703f2a3b3c097.50x50_q85.jpg)
A quadcopter control Software (Still in development). achieved single axis stability!!!!! released for others benefit. if you'd like to help co-develop this code, then please let me know
Dependencies: MovingAverageFilter MyI2C PID RC mbed-rtos mbed
Currently on hold, due to the fact that i don't own a RX/TX system
MPU.h
- Committer:
- KarimAzzouz
- Date:
- 2012-12-23
- Revision:
- 0:54b67cd15a5b
File content as of revision 0:54b67cd15a5b:
// Contains all Sensor related functions : initializing the sensor, calibrating sensors, getting data , accelerometer angles , and filtering gyro/acc data #define MPU_ADDRESS 0x68 #define GyroScale 16.4 #define AccScale 4096 I2C i2c(p9,p10); float filtered_AccX[4],filtered_AccY[4],filtered_AccZ[4],filtered_GyroX[4],filtered_GyroY[4],filtered_GyroZ[4]; float Scaled_GyroX,Scaled_GyroY,Scaled_GyroZ; float Scaled_AccX,Scaled_AccY,Scaled_AccZ; float GyroOffset[3],AccOffset[3]; float accangle[2]; void write(char reg,char data){ char tx[2]={reg,data}; i2c.write((MPU_ADDRESS << 1)&0xFE, tx, 2); } int read (char reg){ char tx = reg; char rx[2]; i2c.write((MPU_ADDRESS << 1)&0xFE , &tx,1); i2c.read((MPU_ADDRESS << 1)|0x01, rx, 2); int16_t output = ((int) rx[0] << 8) | ((int) rx[1]); return output; } void MPU_Setup(){ write(0x6B,0x80); // Restart wait_ms(5); write(0x6B,0x03); //PWR_MGMT_1 -- SLEEP 0; CYCLE 0; TEMP_DIS 0; CLKSEL 1 (PLL with Z Gyro reference) write(0x1B,0x18); //GYRO_CONFIG -- FS_SEL = 2 : Scale = +/-2000 deg/sec write(0x1C,0x10); //ACCEL_CONFIG -- AFS_SEL=2 : Scale = +/-8G write(0x1A,0x03); //DLPF Settings -- 44Hz Accelerometer Bandwidth 42Hz Gyroscope Bandwidth wait_ms(60); } void ScaledGyro(){ Scaled_GyroX = -read(0x45)/GyroScale; Scaled_GyroY = read(0x43)/GyroScale; Scaled_GyroZ = read(0x47)/GyroScale; } void ScaledAcc(){ Scaled_AccX = (float)read(0x3B)/AccScale; Scaled_AccY = (float)read(0x3D)/AccScale; Scaled_AccZ = (float)read(0x3F)/AccScale; } void CalibrateGyro(){ for(int k=0;k<200;k++){ ScaledGyro(); GyroOffset[0]+=Scaled_GyroX; GyroOffset[1]+=Scaled_GyroY; GyroOffset[2]+=Scaled_GyroZ; wait_ms(1); } GyroOffset[0]/=200; GyroOffset[1]/=200; GyroOffset[2]/=200; } void CalibrateAcc(){ for(int k=0;k<200;k++){ ScaledAcc(); AccOffset[0]+=Scaled_AccX; AccOffset[1]+=Scaled_AccY; AccOffset[2]+=Scaled_AccZ; wait_ms(1); } AccOffset[0]/=200; AccOffset[1]/=200; AccOffset[2]/=200; AccOffset[2]-=1; } void GyroRate(){ ScaledGyro(); Scaled_GyroX-=GyroOffset[0]; Scaled_GyroY-=GyroOffset[1]; Scaled_GyroZ-=GyroOffset[2]; } void Acc(){ ScaledAcc(); Scaled_AccX-=AccOffset[0]; Scaled_AccY-=AccOffset[1]; Scaled_AccZ-=AccOffset[2]; } void filterGyro(void){ GyroRate(); //////////////////////////////////////// Filter X Axis //////////////////////////////////////////////////////////////// filtered_GyroX[0] = Scaled_GyroX; Scaled_GyroX = filtered_GyroX[0]*0.25 + filtered_GyroX[1]*0.25 + filtered_GyroX[2]*0.25 + filtered_GyroX[3]*0.25; filtered_GyroX[3] = filtered_GyroX[2]; filtered_GyroX[2] = filtered_GyroX[1]; filtered_GyroX[1] = filtered_GyroX[0]; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////// Filter Y Axis //////////////////////////////////////////////////////////////// filtered_GyroY[0] = Scaled_GyroY; Scaled_GyroY = filtered_GyroY[0]*0.25 + filtered_GyroY[1]*0.25 + filtered_GyroY[2]*0.25 + filtered_GyroY[3]*0.25; filtered_GyroY[3] = filtered_GyroY[2]; filtered_GyroY[2] = filtered_GyroY[1]; filtered_GyroY[1] = filtered_GyroY[0]; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////// Filter Z Axis //////////////////////////////////////////////////////////////// filtered_GyroZ[0] = Scaled_GyroZ; Scaled_GyroZ = filtered_GyroZ[0]*0.25 + filtered_GyroZ[1]*0.25 + filtered_GyroZ[2]*0.25 + filtered_GyroZ[3]*0.25; filtered_GyroZ[3] = filtered_GyroZ[2]; filtered_GyroZ[2] = filtered_GyroZ[1]; filtered_GyroZ[1] = filtered_GyroZ[0]; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } void filterAcc(void){ Acc(); //////////////////////////////////////// Filter X Axis/////////////////////////////////////////////////////////// filtered_AccX[0] = Scaled_AccX; Scaled_AccX = filtered_AccX[0]*0.25 + filtered_AccX[1]*0.25 + filtered_AccX[2]*0.25 + filtered_AccX[3]*0.25; filtered_AccX[3] = filtered_AccX[2]; filtered_AccX[2] = filtered_AccX[1]; filtered_AccX[1] = filtered_AccX[0]; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// Filter Y Axis ////////////////////////////////////////////////////////// filtered_AccY[0] = Scaled_AccY; Scaled_AccY = filtered_AccY[0]*0.25 + filtered_AccY[1]*0.25 + filtered_AccY[2]*0.25 + filtered_AccY[3]*0.25; filtered_AccY[3] = filtered_AccY[2]; filtered_AccY[2] = filtered_AccY[1]; filtered_AccY[1] = filtered_AccY[0]; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// Filter Z Axis////////////////////////////////////////////////////////// filtered_AccZ[0] = Scaled_AccZ; Scaled_AccZ = filtered_AccZ[0]*0.25 + filtered_AccZ[1]*0.25 + filtered_AccZ[2]*0.25 + filtered_AccZ[3]*0.25; filtered_AccZ[3] = filtered_AccZ[2]; filtered_AccZ[2] = filtered_AccZ[1]; filtered_AccZ[1] = filtered_AccZ[0]; //////////////////////////////////////////////////////////////////////////////////////////////////////////////// } void AccAngle(){ filterAcc(); accangle[0] = ToDeg(atan2(Scaled_AccX,sqrt(Scaled_AccY*Scaled_AccY+Scaled_AccZ*Scaled_AccZ))); accangle[1] = ToDeg(atan2(Scaled_AccY,sqrt(Scaled_AccX*Scaled_AccX+Scaled_AccZ*Scaled_AccZ))); }