calculating offsets for mpu6050 gyro

Hello,
I was planning to make a gimbal for my final project. But while using a calibration program for calibrating the gyro I found some lines I didn’t understand. Why was the mean accelerometer value that was calculated divided by 8 and take its negative to get the offset value for x and y offset and subtract from 16384 to get the z axis offset. The calibration function is at the end of the code .

calibration_servo_real.ino (7.64 KB)

I didn't really know anything about gyro stuff, but I thought it would be interesting to research your question. All information without guarantee.

To understand what is happening, you need the appropriate datasheet, which would be MPU-6000 and MPU-6050Register Map and Descriptions.
However, there seems to be a lack of consistency in the datasheets and the required information is not in that one, so we need to do a bit of hand waving and use a similar datasheet and cross our fingers. We'll use MPU-6500 Register Map and Descriptions instead.
There is also a bit of potentially relevant information in MPU Hardware Offset Registers App Note, particularly on page 5, but also some contradictory information. Ultimately, without the information for exactly the MPU6050, I cannot make any definitive claims.

In the sketch, the MPU6050 is initialised like so: accelgyro.initialize();. Which is implemented as follows:

void MPU6050::initialize() {
    setClockSource(MPU6050_CLOCK_PLL_XGYRO);
    setFullScaleGyroRange(MPU6050_GYRO_FS_250);
    setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
    setSleepEnabled(false); // thanks to Jack Elston for pointing this one out!
}

The important bits are the two range lines, where the full scale is set to the most sensitive settings (see registers 27 and 28). These are ±250dps and ±2g respectively.

So you are querying the meaning of the following code in the sketch:

  ax_offset=-mean_ax/8;
  ay_offset=-mean_ay/8;
  az_offset=(16384-mean_az)/8;

  gx_offset=-mean_gx/4;
  gy_offset=-mean_gy/4;
  gz_offset=-mean_gz/4;
...
    accelgyro.setXAccelOffset(ax_offset);
    accelgyro.setYAccelOffset(ay_offset);
    accelgyro.setZAccelOffset(az_offset);

    accelgyro.setXGyroOffset(gx_offset);
    accelgyro.setYGyroOffset(gy_offset);
    accelgyro.setZGyroOffset(gz_offset);

The calibration proceeds with the device in a static horizontal position with the writing on the MPU6050 package pointing upwards. In that position we expect the device to show 0 for all three gyro positions. We also expect the X and Y acceleration to be 0 as the device is at rest. The Z offset however will measure 1G from the acceleration of gravity. Since the MPU is in the most sensitive mode, it can only read a maximum of 2G. So the number 16384 is the expected amount of 1G. If you multiple 16384 by 2 you get 32768. An int can hold a value between -32,768 to 32,767, so you can see the relationship.

If you now look at the registers datasheet again, on pages 45-46, you can see the description of the acceleration offset cancellation registers. There you can see that the acceleration registers want to contain values in the mode 16G. Unfortunately the required information is not stated for the gyro registers on page 11, though page 5 of the App Note does hint at it, so we will just have to assume the fact that the registers expect +-1000dps. So 1000dps/4 is 250dps and 16G/8 is 2G.
So, effectively the mean values are being rescaled to match the expectations of the offset registers.

HTH.

PS. It always amazes me how people put comments in code for the most banal sh*t, yet crucial information like the above is left to the imagination. That said, other things in that sketch lead me to believe that it was not written by an elite programmer.
PPS. Why can't the vendors just put all the available information in one datasheet and be done with it. Grrr.