Getting the exact orientation from sensor


I am using a MPU6050 to get the yaw/pitch/roll values of my airplane. However, the problem is that the values this sensor provides are relative to its initial position. For example, those values are only correct If I boot my flight computer in an absolutely straight position. This is a huge problem for me because I can not get that kind of accuracy every time I go on a test flight since the areas I test on are rough have irregular terrain.

So the question is, How can I get the exact yaw pitch roll value of my aircraft independent from the starting position and such dependencies.

Thank you and all input are appreciated

The MPU-6050 can measure only pitch and roll. Yaw is determined relative to the starting orientation using the gyro, and it will drift.

To measure the yaw angle, you need a magnetometer or other external reference. Any 9DOF sensor will do.

Of course, these angles are only estimates and their accuracy depends very strongly on how carefully you calibrate all the sensors.

I really dont care much about the yaw angle. My MPU6050 is giving the pitch and roll values relative to its starting position as well. As much as I understand from your reply, thanks btw, it should not do that. I am leaving the code that I used maybe you can help me figure out why?

Here is a very simple MPU-6050 program to measure pitch and roll about the sensor Y and X axes, respectively. The sensor must be held still while measuring, so that gravity (and not other accelerations) determines the “down” direction.

// minimal MPU-6050 tilt and roll
// works perfectly with GY-521, pitch and roll signs agree with arrows on sensor module 7/2019
// tested with eBay Pro Mini, **no external pullups on SDA and SCL** (works with internal pullups!)
const int MPU_addr1 = 0x68;
float xa, ya, za, roll, pitch;

void setup() {

  Wire.begin();                                      //begin the wire communication
  Wire.beginTransmission(MPU_addr1);                 //begin, send the slave adress (in this case 68)
  Wire.write(0x6B);                                  //make the reset (place a 0 into the 6B register)
  Wire.endTransmission(true);                        //end the transmission

void loop() {

  Wire.write(0x3B);  //send starting register address
  Wire.endTransmission(false); //restart for read
  Wire.requestFrom(MPU_addr1, 6, true); //get six bytes accelerometer data

  xa = << 8 |;
  ya = << 8 |;
  za = << 8 |;
// formula from
  roll = atan2(ya , za) * 180.0 / PI;
  pitch = atan2(-xa , sqrt(ya * ya + za * za)) * 180.0 / PI; //account for roll already applied

  Serial.print("roll = ");
  Serial.print(", pitch = ");

Perhaps you are confused about “body” and “world” coordinate systems. If so, here is a good overview: Library |