Showing posts with label mpu6050. Show all posts
Showing posts with label mpu6050. Show all posts

Saturday, 29 September 2018

Custom Flight Controller using Arduino Uno

Hi,

I tried to build my own custom flight controller using Arduino Uno.
You can find all the source code at my github repo: https://github.com/anilkunchalaece/arduQuad

Following are the few test flights i tried :





I also developed my own GUI using Python (PyQt4 and PyQt Graph) for debugging and tuning


This is the one of the many problems i had to tackle to get above flight performance


The problem in the above video is using only Angle PID loop. to get minimum takeoff we have to use cascaded PID loops i.e Angular Rate followed by Angle PID loop.

The code i used to achieve take off is https://github.com/anilkunchalaece/arduQuad/blob/master/ArduinoCode/ksrmQuadLevelModePlusConfig/ksrmQuadLevelModePlusConfig.ino

Source code for python GUI
https://github.com/anilkunchalaece/arduQuad/blob/master/PythonCode/GUI/graphGUI_v2.py

Following are the few references i used

https://blog.owenson.me/build-your-own-quadcopter-flight-controller/

This is me flying APM2.7 with the same build.
I suck at flying, still lot to learn.
This is how it ended up, crashing on a tree.
and luckily nothing broken :)


Btw i used complementary filter to get the angles from MPU 6050. Drop a comment if are doing the same, i am very happy to join with you to continue this.

Wednesday, 30 May 2018

Reading Accelerometer Angles


/*
 * Author : kunchala Anil
 * Email : anilkunchalaece@gmail.com
 * Date : 22 May 2018
 * 
 * This sketch is used to calculate angle from MPU6050 Accelerometer values
 * crust of the sketch is 
 *        float pitch = atan(accX/sqrt(pow(accY,2) + pow(accZ,2)));
 *         float roll = atan(accY/sqrt(pow(accX,2) + pow(accZ,2)));
 * 
 * Check following https://cache.freescale.com/files/sensors/doc/app_note/AN3461.pdf
 * i didnt understand the math behind it
 */
 
#include <Wire.h>
#include <math.h>

const long ACCR_SENSITIVITY_SCALE_FACTOR = 16384.0; // for 2g
const int MPU6050_ADDR = 0b1101000;

const byte PWR_REG_ADDR = 0x6B;

const byte ACCR_CONFIG_REG_ADDR = 0x1C;
const byte ACCR_READ_START_ADDR = 0x3B;

int16_t accX,accY,accZ;
double angleX,angleY; 
double aX,aY,aZ;

void setup() {
 Wire.begin();
 Serial.begin(115200);
 configureMPU();
}//end of setup

void loop() {
  readAccrX();
// apply trigonometry to get the pitch and roll:
float pitch = atan(accX/sqrt(pow(accY,2) + pow(accZ,2)));
float roll = atan(accY/sqrt(pow(accX,2) + pow(accZ,2)));
//convert radians into degrees
pitch = pitch * (180.0/PI);
roll = roll * (180.0/PI);
  

  Serial.print(pitch);
  Serial.print("   ");
  Serial.println(roll);
  delay(100);
}//end of loop

void readAccrX(){
   Wire.beginTransmission(MPU6050_ADDR);
  Wire.write(ACCR_READ_START_ADDR);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU6050_ADDR,6,true);  
  accX=Wire.read()<<8|Wire.read(); 
  accY=Wire.read()<<8|Wire.read(); 
  accZ=Wire.read()<<8|Wire.read(); 
//  Serial.println(accX);   
//  aX = accX / ACCR_SENSITIVITY_SCALE_FACTOR;
//  aY = accY / ACCR_SENSITIVITY_SCALE_FACTOR;
//  aZ = accZ / ACCR_SENSITIVITY_SCALE_FACTOR;

}//end of readGyroX Fcn

void configureMPU(){
  //Power Register
  Wire.beginTransmission(MPU6050_ADDR);
  Wire.write(PWR_REG_ADDR);//Access the power register
  Wire.write(0b00000000);
  Wire.endTransmission();

  //Gyro Config
  Wire.beginTransmission(MPU6050_ADDR);
  Wire.write(ACCR_CONFIG_REG_ADDR);
  Wire.write(0b00000000);
  Wire.endTransmission();
}//end of setUpMPU Fcn