I'm using this Arduino code to calibrate and read from an MPU6050 accel/gyro sensor from an Arduino Mega.

The calibration and reading of values seemed to go well. However, I'm seeing some inconsistent values reported from the gyroscope. When my apparatus is placed flat, it correctly read a pitch of 0 degrees. When I tilt it forward by 90 degrees, it reads a fairly accurate -89.6 degrees. However, when I tilt it backward at -90 degrees...it reads -26 degrees.

Why is this? Could this be caused by mis-calibration, interference, or is it possible my MPU6050 is damaged or defective?

The default orientation of the board is with it flat, so the z-axis points "up". However, I've mounted the sensor with the y-axis pointing "up" and the z-axis points forward/backward. Would this effect calibration? Other than having to remap, my axis when reading data (which I'm doing), I haven't read any warnings about needing to explicitly enter this re-orientation into the MPU6050 code.

  • \$\begingroup\$ Idk but that link doesn't open for me. How do concert the readings to angle? May be your issue lies there? \$\endgroup\$
    – MaNyYaCk
    Commented Mar 27, 2018 at 15:32
  • \$\begingroup\$ You seem to incorrectly refer to the "gyroscope" when discussing angles determined by inverse trig functions from the accelerometers. While the chip also contains three rate gyros, these gives you angular rates, not angles. \$\endgroup\$ Commented Mar 27, 2018 at 18:28
  • \$\begingroup\$ @ChrisStratton Noted. \$\endgroup\$
    – Cerin
    Commented Mar 27, 2018 at 19:26

1 Answer 1


Turns out that calibration requires the sensor to be in the default "z-up" position, and that even if you adjust the trig functions later, the values will still be off if you use a different orientation. I tried removing the MPU6050 from my apparatus, placing it flat, and re-running the calibration. That improved the values, but the ranges still weren't aligning correctly with my custom orientation, so I added this function to flip the X and Z axis based on the code provided in this comment:

uint8_t MPU6050::dmpGetYawPitchRollOnEnd(float *data, Quaternion *q, VectorFloat *gravity) {
    // yaw: (about X axis)
    data[0] = atan2(2*q->z * q->y - 2 * q->w * q->x, 2 * q->w * q->w + 2 * q->z * q->z - 1);
    // pitch: (nose up/down, about Y axis)
    data[1] = atan(gravity->z / sqrt(gravity->y * gravity->y + gravity->x * gravity->x));
    // roll: (tilt left/right, about Z axis)
    data[2] = atan(gravity->y / sqrt(gravity->z * gravity->z + gravity->x * gravity->x));
    return 0;

And then, with that and the proper calibration values, it now returns the correct 90 to -90 degree range when I change pitch by 180 degrees.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.