Electrical – MPU6050 showing inconsistent angle values

accelerometerarduinogyrogyroscopeimu

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.

Best Answer

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.