# MPU6050 Sending Bad values for Angular Velocity

The mpu gives me perfectly fine values for the yaw, pitch, and roll position of the chip, but when I use `mpu.getRotation(&gx, &gy, &gz)` to obtain the current angular velocity of the chip, the values returned are awful. I wrote a program in Processing to graph the data from my Arduino, and this is what it looks like: I suggest you click on the picture and zoom in a bit because it's difficult to see. The green line represents zero (0), the Pink line represents the angular position of the mpu6050 chip, obtained from `mpu.getYawPitchRoll...`, and the Blue line represents the angular velocity on the same rotational axis.

A few extra things to note:

• The scale between the Pink and the Blue lines is slightly off, but that shouldn't matter for this purpose.
• The time-frame for this graph is about 16s.
• Before being graphed, the raw gx value is divided by the gyro's sensitivity scale factor, 131, and then converted from radians to degrees. In addition to this, it is also put through a complementary filter, so the whole formula looks like this: `rollRate = (0.7*rollRate) + (0.3*(-180 * gx / 131 / M_PI));`

As you can see, the measurements for angular velocity (Blue) make almost no sense when graphed next to the angular position (Pink).

My question is this: What can I do to clean-up/filter these angular velocities and get rid of all the errors? I need these values to be accurate enough to be used in something like a drone PID.

Things I have tried:

• Complementary filters of various proportions.
• Adjusting the MPU's built in low-pass filter.

Thanks for any suggestions.

Quick Solution for those who don't like reading: Amend the previous `rollRate` formula to `rollRate = (0.7 * rollRate) + (-0.3 * gx / 16.4);`. Or, if you don't want the filter, `rollRate = -1 * gx / 16.4;`
The problem starts with the function `mpu.getRotation(&gx, &gy, &gz)` which accepts `int16_t` types for `gx`, `gy`, and `gz`. Since `int16_t` is a 16 bit integer, it has a maximum range of -32,768...+32767. The reason this integer type is used is because the output range for the gyro is -32750...+32750, which fits nicely into the 16-bit integer's range.
The problem was that when I converted these values to a readable angular velocity (and complementarily filtered) using `rollRate = (0.7*rollRate) + (0.3*(-180 * gx / 131 / M_PI));` , the `gx` value was multiplied by -180 in part of the calculation. This means that if `gx` was high enough initially, it would have rolled over to -32786 and ruined the whole calculation, causing the horrible spikes in the graph.
At the same time I discovered this problem, I also realized that converting from radians to degrees was unnecessary, as the gyro output was already in units of degrees (just scaled by a sensitivity factor). After that big face-palm, I revised my rate formula to the following: `rollRate = (0.7 * rollRate) + (-0.3 * gx / 16.4);`. You will notice the scale factor has changed from 131 to 16.4. That is because the gyro range is actually +/-2000 deg/s by default, not 250 deg/s. I tried to change it back to +/-250 with `mpu.setFullScaleGyroRange(MPU6050_GYRO_FS_250);`, but after examining the graph, it appeares that `mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);` does not account for this setting change, and resulted in the ypr overshooting and then leveling out to its correct value after a delay. I decided not to mess around with the quaternion container, `q`, and just accepted the lower sensitivity. Like the previous image, I suggest zooming in.