# Understanding values from an MPU6050

I'm trying to understand the values that I'm getting from my MPU6050. I believe that there is a problem with my code. I'm not entirely sure how the code is supposed to look like. There doesn't seem to be very many examples on the MPU6050.

What is wrong?

After taking a look at the system print I found that the numbers that are written out is the time and not the values of the MPU6050. Why am I getting the zeros and nan for?

I also had a library problem thats fixed now.

I got the code from a site and I've modified it because it didn't run for me.

This is my code:

``````// collect readings
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

// apply gyro scale from datasheet
gsx = gx/gyroScale;   gsy = gy/gyroScale;   gsz = gz/gyroScale;

// calculate accelerometer angles
ary = -(180/3.141592) * atan(ax / sqrt(square(ay) + square(az)));
arx =  (180/3.141592) * atan(ay / sqrt(square(ax) + square(az)));
arz = (180/3.141592) * atan(sqrt(square(ay) + square(ax)) / az);

// set initial values equal to accel values
if (i == 1) {
grx = arx;
gry = ary;
grz = arz;
}
// integrate to find the gyro angle
else{
grx = grx + (timeStep * gsx);
gry = gry + (timeStep * gsy);
grz = grz + (timeStep * gsz);
}

// apply filter
rx = (0.1 * arx) + (0.9 * grx);
ry = (0.1 * ary) + (0.9 * gry);
rz = (0.1 * arz) + (0.9 * grz);

Serial.print(ax);   Serial.print("\t");
Serial.print(ay);   Serial.print("\t");
Serial.print(az);   Serial.print("\t\t");
Serial.print(gx);   Serial.print("\t");
Serial.print(gy);   Serial.print("\t");
Serial.print(gz);   Serial.print("\t\t");
Serial.print(arx);   Serial.print("\t");
Serial.print(ary);   Serial.print("\t");
Serial.print(arz);   Serial.print("\t\t");
Serial.print(grx);   Serial.print("\t");
Serial.print(gry);   Serial.print("\t");
Serial.print(grz);   Serial.print("\t\t");
Serial.print(rx);   Serial.print("\t");
Serial.print(ry);   Serial.print("\t");
Serial.println(rz);
``````

This is the output im getting

``````2   1.00    61.00   0.06000     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
3   61.00   139.00  0.07800     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
4   139.00  219.00  0.08000     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
5   219.00  300.00  0.08100     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
6   300.00  380.00  0.08000     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
7   380.00  462.00  0.08200     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
8   462.00  543.00  0.08100     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
9   543.00  624.00  0.08100     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
10  624.00  705.00  0.08100     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
11  705.00  788.00  0.08300     0   0   0       0   0   0       nan nan nan
``````

...

``````41  3223.00 3307.00 0.08400     0   0   0       0   0   0       nan nan nan nan nan nan     nan nan nan
42  3307.00 3392.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
43  3392.00 3476.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
44  3476.00 3560.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
45  3560.00 3645.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
46  3645.00 3729.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
47  3729.00 3813.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
48  3813.00 3897.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
49  3897.00 3982.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
50  3982.00 4066.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
51  4066.00 4150.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
52  4150.00 4234.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
53  4234.00 4319.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
54  4319.00 4403.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
55  4403.00 4487.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
56  4487.00 4571.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
57  4571.00 4656.00 0.08500     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
58  4656.00 4740.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
59  4740.00 4824.00 0.08400     0   0   0       0   0   0       nan nan nan     nan nan nan     nan nan nan
``````
• Ever increasing values suggest code which is trying to integrate an acceleration measurement to determine velocity, something that it not realistically workable with a budget sensor. Your question is insufficiently specified to ask here, as you neglect to include the code generating the output columns, so no one can have any idea beyond guesses as to what they represent. Dec 13, 2015 at 17:30
• "After taking a look at the system print i found that the numbers that are written out is the time and not the values of the MPU6050. Why am i getting the zeros and nan for?"
– Marc
Dec 14, 2015 at 8:00
• @ChrisStratton I have added the entire output + the print.
– Marc
Dec 14, 2015 at 8:51
• @ChrisStratton Chris?
– Marc
Dec 19, 2015 at 19:32
• Your data is clearly flawed - look how the values in ax, ay, az turn up in a different position in the next row. Are you passing the correct type of pointer? Remove all the rest of the code and just focus on getting valid values for those as a start. Or maybe you should go back to the original code and figure out why exactly it didn't run. Dec 19, 2015 at 20:47

I think the best choice for you is to read raw data from the sensor using Wire library.

1. First of all, you have to include the "Wire.h" library:

``````#include "Wire.h"
``````
2. Next step is to start the I2C communication by calling the following function in `setup()`

``````Wire.begin();
``````
3. Now that the master joined the I2C bus, all you have to do is to set the power mode of the module by setting the register `0x6B` to `0x0`. You can use the following function:

``````int sendCommand(int8_t register_address, int8_t register_value) {
Wire.write(register_value);
int statusCommand = Wire.endTransmission(true);
Serial.print(" Register value: "); Serial.print(register_value, HEX);
Serial.print(" Status command: "); Serial.println(statusCommand);

return statusCommand;
}
``````

Please note that the default I2C address for the MPU6050 is `0x68`. You can use the I2C Scanner to find its address.

To actually set the register `0x6B` to `0x0` you have to call the `sendCommand` like below:

``````sendCommand(0x6B,0x0);
``````
1. Request the raw data from the MPU6050. You can check the MPU6050 Register Map for additional information. Accelerometer can be found from `0x3B` to `0x40`, temperature from `0x41` and `0x42`, and finally, the gyro from `0x43` to `0x48`. IMPORTANT!!! Every register's value occupy 1 byte (int8_t), so you have to get the values of two registers (2 bytes) and store them in an int16_t.

Here is the full code to get the angles from the sensor:

``````#include "Wire.h"

int sendCommand(int8_t register_address, int8_t register_value) {
Wire.write(register_value);
int statusCommand = Wire.endTransmission(true);
Serial.print(" Register value: "); Serial.print(register_value, HEX);
Serial.print(" Status command: "); Serial.println(statusCommand);

return statusCommand;
}

void setup() {
//join the I2C bus
Wire.begin();
//start serial communication
Serial.begin(115200);
delay(1000);

/* sendCommand can return 5 possile values:
* -> 0:success
* -> 1:data too long to fit in transmit buffer
* -> 3:received NACK on transmit of data
* -> 4:other error
*/
while(sendCommand(0x6B,0x0) != 0){
delay(1000);
}

Serial.println("MPU6050 started");
}

void convertRawDataToAngle(int16_t AcX, int16_t AcY, int16_t AcZ) {
int minVal = 265; int maxVal = 402;
int xAng = map(AcX, minVal, maxVal, -90, 90);
int yAng = map(AcY, minVal, maxVal, -90, 90);
int zAng = map(AcZ, minVal, maxVal, -90, 90);

int x = RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
int y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
int z = RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

Serial.print("X angle: "); Serial.print(x);
Serial.print(" Y angle: "); Serial.print(y);
Serial.print(" Z angle: "); Serial.print(z);
}

int statusCommand = -1;
do {
statusCommand = Wire.endTransmission(false);
Serial.print(" Status command: "); Serial.print(statusCommand);
} while (statusCommand != 0 && bytesReceived != 6);
//check if MPU6050 sent all the requested data
//in total 6 bytes, 2 bytes for each axis
if (Wire.available() == 6) {
int16_t AcX = Wire.read() << 8 ;
int16_t AcY = Wire.read() << 8 ;
int16_t AcZ = Wire.read() << 8 ;
convertRawDataToAngle(AcX, AcY, AcZ);
}
}
void loop() {
//put your main code here, to run repeatedly:
delay(100);
}
``````
• In `Wire.read() << 8 | Wire.read()`, it is unspecified which `Wire.read()` is executed first. You may get lucky with a particular version of the compiler, but the only safe way of getting the bytes in the right order is to do the reads in two separate statements. Feb 29, 2020 at 16:21
• Well, I did it that way because I request 6 bytes of data, starting from register 0x3B. I expect to receive them in the order I requested. Am I right? If not, can you provide me tips how to replicate what you said, to get the bytes in the wrong order? Feb 29, 2020 at 18:19
• I cannot, as I likely use a compiler version not too far from yours. My point is that the fact that it does work with the compiler we are using now does not mean the code is correct. The correct version would be `AcX = Wire.read() << 8; AcX |= Wire.read();` Feb 29, 2020 at 19:11
• Oh, I get now what you mean. Thank you for the suggestion. I will update it soon! If there is anything that might go wrong, I am open to fix them. I still have a lot to learn! Feb 29, 2020 at 19:33

The output MPU 6050 does need filtering/processing before you can get any sense from it. I have used the library "MPU6050_6Axis_MotionApps20.h" with success, it is located here: MPU6050_6Axis_MotionApps20.h

I have written an example here: MPU 6050 for MicroView.

• Does your code also get the values?
– Marc
Nov 2, 2015 at 11:04
• The library does its magic, and you can get Euler angles simple and reliable (these are orientation angles). Other measurements such as acceleration are also easy to obtain. Nov 3, 2015 at 8:30
• Im getting a ton of errors from the library. Ive added the errors to the code above. Ive been busy thats why it took so long.
– Marc
Nov 13, 2015 at 12:57