MPU6050 angle drifts over time: gyro offset, calibration and filtering

A gyroscope has a small offset that adds up when you integrate it. Measure the offset at rest and subtract it.

What the message means

The angle is the sum of rate readings over time. A tiny constant error in each reading becomes a steady drift.

Fix it in this order

  1. Keep the sensor still at start-up and average a few hundred gyro readings as the offset.
  2. Subtract that offset from each reading.
  3. Use the accelerometer to correct slow drift in tilt, with a complementary filter.
  4. Keep a fixed time step, measured with micros().
  5. Let the sensor warm up for a minute, since the offset changes with temperature.
  6. Yaw cannot be corrected by the accelerometer. Add a magnetometer or accept the drift.

Why it happens

A gyroscope reports a small non-zero reading even when still, and integrating that offset makes the angle drift. The offset also changes with temperature.

Average many readings while the sensor is still at start-up and subtract that offset. To stop slow drift you also need another reference, for example a complementary filter that blends in the accelerometer angle.

If you see this, do this

You seeDo this
Tilt drifts slowlyAdd accelerometer correction.
Yaw drifts alwaysNormal without a magnetometer.

MPU6050 returns zeros, I2C address conflict.

Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.

Why this happens

A gyroscope reports angular rate. To get an angle, the code adds up rate multiplied by the time step. A tiny constant error in the rate, the offset, is added every step, so it grows steadily. At the default plus or minus 250 degrees per second range the MPU6050 gives 131 counts per degree per second. An offset of 120 counts is 120 / 131 = 0.92 degrees per second, which makes the angle drift by about 55 degrees in a minute.

The accelerometer measures the direction of gravity, so it gives a tilt that does not drift but is noisy and wrong when the robot accelerates. A complementary filter takes the smooth short-term angle from the gyro and slowly pulls it toward the accelerometer angle. Yaw has no gravity reference, so it keeps drifting.

How to confirm the cause

  • Keep the board still and print the raw gyro values for ten seconds. The average is the offset.
  • Check that it is constant; warm the board and look at whether the offset moves.
  • Print the time step. A fixed value when the loop time varies causes errors.
  • Tilt the board slowly and check that the accelerometer angle matches reality.

Worked example

The filter below uses 0.98 of the gyro estimate and 0.02 of the accelerometer; tune the split for your loop speed.

// offsetX measured at rest; dt in seconds from micros()
float rate     = (gx_raw - offsetX) / 131.0;      // deg/s at +/-250
float accAngle = atan2(ay, az) * 180.0 / PI;
angle = 0.98 * (angle + rate * dt) + 0.02 * accAngle;

Common mistakes

  • Calibrating while the board is moving.
  • Using a fixed dt while the loop time changes.
  • Mixing the units of gyro counts and degrees.
  • Expecting yaw to be corrected by the accelerometer.

If this did not fix it

  • Check I2C read errors and the supply.
  • Check vibration; enable the sensor’s low-pass filter setting.
  • Check the sign of each axis for your mounting.
  • Check whether your chip is a clone with different behaviour.