1

I have been trying to figure out this MPU6050 for a bit but the RAW readings are confusing me. It seems to me that the accelerometer readings and the gyro readings are getting swapped... and I don't really see how.

Here is the code reading the raw data in:

#include "Wire.h" 

const int MPU_ADDR = 0x68; // I2C address of the MPU-6050. 
const int ACCEL_XOUT_H = 0x3B; // starting register: high byte to accelerometer X High

int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
int16_t temperature; // variables for temperature data

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
  Wire.write(0x6B); // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
}

void loop() {
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(ACCEL_XOUT_H); // starting with register 0x3B (ACCEL_XOUT_H) 
  Wire.endTransmission(false); // connection is kept active.
  Wire.requestFrom(MPU_ADDR, 7*2, true); // request a total of 7*2=14 registers

  // Read high byte, shift up one byte then OR with low byte
  accelerometer_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
  accelerometer_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
  accelerometer_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
  temperature = Wire.read()<<8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
  gyro_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
  gyro_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
  gyro_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)


  // print out data
  Serial.print(""); Serial.print(accelerometer_x, DEC);
  Serial.print("|"); Serial.print(accelerometer_y, DEC);
  Serial.print("|"); Serial.print(accelerometer_z, DEC);
  Serial.print("|"); Serial.print(temperature/340.00+36.53, DEC);
  Serial.print("|"); Serial.print(gyro_x, DEC);
  Serial.print("|"); Serial.print(gyro_y, DEC);
  Serial.print("|"); Serial.print(gyro_z, DEC);
  // the following equation was taken from the documentation [MPU-6000/MPU-6050 Register Map and Description, p.30]

  Serial.println();

  // delay
  delay(100);
}

I am expecting some pipe-delimited data in the format: 'aX|aY|aZ|T|gX|gY|gZ'

and indeed looking at the serial data that is what I thought I had:

%matplotlib notebook
import serial
from collections import deque
import pandas as pd
import matplotlib.pyplot as plt
ser= serial.Serial('COM6', 115200, timeout=2.5)
ser.readline()

gives me a good line of data: b'4008|-1792|18376|26.3182334899|-1084|274|-380\r\n'

This certainly looks plausible -- but I was confused by why the accelerometer values were so high at rest... maybe that is just how it is. But when I moved things around I was more and more confused - I have to see this. So I plotted all the values in Jupyter/matplotlib and it made sense -- the first three numbers are not accelerometer data but gyro data:

fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()

fig.show()
fig.canvas.draw()

ser.reset_input_buffer()
ser.readline()
data = deque(maxlen = 100)
try:
    while True:
        line_of_data = [float(x.strip()) for x in (ser.readline().decode("utf-8")).split("|")]
        data.append(line_of_data)
        ax.clear()
        for n in range(7):
            ax.plot([x[n] for x in data], label='x['+str(n)+']')
        ax.legend(loc='upper left')
        fig.canvas.draw()
except KeyboardInter

plot of mpu6050 data

I slowly turned the robot chassis and the x[0] and x[2] (should have labeled those better) values changed and then held their values as I held the rotation. This is what I expected to see from the gyroX and gyroZ (the MPU6050 is at the top of the chassis so as I rotate the body about the wheels the X axis changes the most but the Z does as well).

I don't see how the code could be swapping to two sets of data. I have looked at a number of other examples of reading the raw values and their numbers look similar to mine (i.e. they show the first three values as rather large, and the last three as rather small).

When the MPU is not moving I would expect the accelerometer values to be small.

Do I just not understand how the MPU6050 is working or am I somehow swapping the values in my code?

  • The accelerometer measures the earth gravity and the gyro measures a change in rotation. Can you try to tilt the object in all 6 directions and check if you can see the accel_x,y,z values from a large negative to a large positive value for each axis. To get gyro values, you have to rotate the object fast, and only during a change of the rotation, the gyro values get larger. – Jot Feb 24 at 0:50
  • So... if I think of the three accelerometer values as a vector with Z pointing towards the center of the earth (which is why it initially the highest value when the chip is laying flat) then as I flip the chip over I will see the Z value flip... this is making much more sense to me. So the values are not swapped I just didn't know what I was looking at! (i.e. all is right in the world again). – nickdmax Feb 24 at 1:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.