MPU6050 with arduino complementary filter

Hi, I know I can get pith, roll and yaw angles from MPU6050 using the DMP. It's good and very reliable but I want to learn a bit more and I decided to get the angles from the raw data from the mpu6050.

I will use the gyro and accel. I know gyro drifts at long term and accel is really realiable but it's too noisy. So there are filters like kalman filter, complementary filter... I decided to go by complementary filter. So I can the pitch like this:

pitch_angle = 0.98 (pitch_angle + gyrotime_interval) + 0.02accel_angle

It's an iterative process, the last value pitch_angle is used in the new calculation. Great, I get this. BUT CHECK THIS: if "gyro*time_interval" drifts as the time goes by, why the pitch_angle will not drift? I see many tutorials in the internet and they say clearly that PITCH AND ROLL WILL NOT DRIFT using gyro and accel data. Why?? Gyro will always drift, and if you take a look at the formula above you will see that if gyro drifts, the pitch_angle result should drift too! But does it drift?

I already spent 2 days studying this, I read maaaany tutorials and academic papers and they are all very repeatitive but they dont explain the reason why the PITCH and ROLL does not drift even if in it's calculattion 98% of the value is related to gyro*time_interval which drifts, A LOT. In a single minute GYRO of mpu6050 will drift about 18 degree!

This is the Arduino Kalman filter guide : Guide to gyro and accelerometer with Arduino including Kalman filtering - Sensors - Arduino Forum
If you follow the links at the bottom of the first post, you find code for the MPU-6050 as well.

I always need a picture to know what pitch, roll and yaw is. I write this down for myself:
Pitch : Tilting front up or down (a plane is climbing or descending).
Roll : Wobbling (a wing of a plane is going down and the other wing is going up).
Yaw : Direction (compass)

The accelerator measures the earth gravity. That is the vector (the 'acceleration' of 1G) pointing down. Because of that, it knows the pitch and roll and they won't drift. There should be an initial calibration when the object is horizontal, and after that the vector pointing downwards is known.

If a filter does not use the initial value, and only the changes of the acceleromter and gyro, then the pitch will not be stable if a plane is climbing for a long time.

The gyro will drift, so the yaw will also drift. A compass (magnetometer) or GPS is needed to prevent that. That is why the newest sensors have all three : accelerometer, gyro, magnetometer.

This is the Arduino Kalman filter guide : Guide to gyro and accelerometer with Arduino including Kalman filtering - Sensors - Arduino Forum

Sadly, the posted code is not a Kalman filter, and has never worked properly. Many people have been misled and simply wasted their time.

Save yourself the trouble and buy the BNO055 absolute orientations sensor instead. It works rather well, but be sure to follow the calibration instructions.

@Koepel sorry but everything you said I already know. I just want to know is this: I know for sure gyro for pitch and gyro for roll will drift, that's 100% sure. Why when I use it with accel the resulted angle does not drift anymore when using the complementary filter?

@batata004, I'm sorry as well, but I can only repeat what I already told. The earth gravity will not change, so the accelerator knows what is down (and what is up). It depends of course on the filter to use that.

Sorry for replying an old post, but have you found an answer?, if I plug that equation in to a calculator it does, in fact, drift, and it's driving me crazy.

If for example, you take a 1º/s drift and a 0º angle, the equation transforms into:

pitch_angle = 0.98 (pitch_angle + 1)

And it drifts

Yes, the 6DOF MPU-6050 drifts.

Use a 9DOF sensor instead.

If anyone is wondering, I've found out why it does not drift.
It has to do with how fast the program runs, if it runs, for example, every 4ms and you have a gyro drift of 5º/s, that means that every run, the gyro reading drifts 0.02º.

Now, if you replace this 0.02 in the equation, and if we imagine a 5º accel_angle:

pitch_angle = 0.98 (pitch_angle + gyrotime_interval) + 0.02accel_angle ->

pitch_angle = 0.98 (pitch_angle + 0.02) + 0.02*5 -> Converges to 5.97º

So you have approximately one degree of error, but no drift (in reality you will see that it drift just one degree, pretty much nothing).

On the other hand, if you run your program every 100ms, the pitch angle becomes 29.5º, so you have a lot of error (or it will drift until it hits that angle, it's the same).