Reading MPU6050 sensors with Arduino

  • avatar
  • 2.2K Views
  • 5 Likes
  • 10 mins read

The MPU-60X0 is the world's first integrated 6-axis MotionTracking device that combines a 3-axis gyroscope, 3-axis accelerometer and a Digital Motion Processor (DMP) all in a small package. It helps to measure velocity, orientation, acceleration, displacement and other motion like features

MPU6050 sensors

The MPU-6050 features three 16-bit analog-to-digital converters (ADCs) for digitizing the gyroscope outputs and three 16-bit ADCs for digitizing the accelerometer outputs. For precision tracking of both fast and slow motions, the parts feature a user-programmable gyroscope full-scale range and a user-programmable accelerometer full-scale range.

Gyroscope

A gyroscope is a device used for measuring or maintaining orientation and angular velocity. Measured in degrees (or radian) per second, angular velocity is the change in the rotational angle of the object per unit of time.

Depending on the direction there are three types of angular rate measurements:

  • Yaw: the horizontal rotation on a flat surface when seen the object from above.

  • Pitch: vertical rotation as seen the object from front.

  • Roll: horizontal rotation when seen the object from front.

Acceletometer

Accelerometer sensors are integrated circuits (ICs) that measure acceleration, which is the change in speed per unit time. Measuring acceleration makes it possible to obtain information such as object inclination and vibration.

Commonly, g is used as a unit for acceleration, relative to standard gravity (1g = 9.80665m/s2).

Components

arduino-nano

1x Arduino Nano (or another Arduino module)

Buy now

mini-breadboard

1x Mini Breadboard

Buy now

mpu6050

1x MPU6050

Buy now

dupont

Dupont wires

Buy now

github

I2C library

Download here

Wiring schema

MPU6050 module has 10 pins but for basic usage we will only need 4.

PIN

Description

VCC

Power supply pin

GND

Ground pin

SCL

I2C Serial Clock/SPI Serial Clock pin

SDA

I2C Serial Data/SPI Serial Data pin

XDA

I2C Serial Data input for external sensors connection pin

XCL

I2C Master Serial Clock for external sensors connection pin

AD0

I2C Address/Serial data out pin

INT

Interrupt pin

As mentioned, for basic usage connect the power supply pins and SDA, SCL pins according to the connection diagram shown below:

arduino_mpu6050.png

Interpreting data

We have the official MPU6050 datasheet and register map available in our official repository. It describes the function and contents of each register within the MPU-6050. We recommend you to read Decimal, binary and hex representations post to easily identify a register and understand the meaning of the content inside it.

mpu6050_register_map.png

The first two columns of the register map represent the address in HEX and decimal formats followed by the register name. Some of the registers are read-only (marked with R) and others allow us to write (marked with R/W). The content of the register is represented using 8-bits. In various cases, register's value may represent more than one thing, in other words, every bit or group of bits may have a different meaning, e.g., CONFIG (register 26).

The MPU-6050 has 16-bits precision for each of the sensors. That means that two 8-bits registers are used to represent the output. We will read 8-bits data separately from each register and then concatenate them to form 16-bits.

Install Arduino library for I2C

We will use I2C protocol to interact with registers and read/write data. The I2C library provides a very simple interface for that purpose and can be reused in other projects that use I2C protocol. It can be downloaded from our official repository.

To import a library, open the Arduino IDE, go to Sketch > Include Library > Add .ZIP Library and select the library file downloaded from our GitHub repository.

arduino_import_library.png

Then you can simply use include statement:

#include "I2C.h"

It will include the library with predefined functions to interact with registers.

Arduino code

We've defined a separate struct for each raw sensor data: gyroscope_raw, accelerometer_raw and temperature_raw. Every raw struct has a data normalizer function based on the current configuration. Human readable normalized values are stored in another struct called normalized.

Make sure to follow the previous step and import I2C library in order to use it with the include statement:

#include "Wire.h"
#include "I2C.h"

#define MPU6050_IMU_ADDRESS 0x68

#define GYRO_FULL_SCALE_250_DPS 0x00
#define GYRO_FULL_SCALE_500_DPS 0x08
#define GYRO_FULL_SCALE_1000_DPS 0x10
#define GYRO_FULL_SCALE_2000_DPS 0x18

#define ACC_FULL_SCALE_2G 0x00
#define ACC_FULL_SCALE_4G 0x08
#define ACC_FULL_SCALE_8G 0x10
#define ACC_FULL_SCALE_16G 0x18

#define TEMPERATURE_OFFSET 21 // As defined in documentation

#define INTERVAL_MS_PRINT 1000

#define G 9.80665

struct gyroscope_raw {
int16_t x, y, z;
} gyroscope;

struct accelerometer_raw {
int16_t x, y, z;
} accelerometer;

struct temperature_raw {
int16_t value;
} temperature;

struct {
struct {
float x, y, z;
} accelerometer, gyroscope;

float temperature;
} normalized;

unsigned long lastPrintMillis = 0;

void setup()
{
Wire.begin();
Serial.begin(115200);

I2CwriteByte(MPU6050_IMU_ADDRESS, 27, GYRO_FULL_SCALE_1000_DPS); // Configure gyroscope range
I2CwriteByte(MPU6050_IMU_ADDRESS, 28, ACC_FULL_SCALE_2G); // Configure accelerometer range
I2CwriteByte(MPU6050_IMU_ADDRESS, 56, 0x01); // Enable interrupt pin for raw data
}

void loop()
{
unsigned long currentMillis = millis();

if (isImuReady()) {
readRawImu();

normalize(gyroscope);
normalize(accelerometer);
normalize(temperature);
}

if (currentMillis - lastPrintMillis > INTERVAL_MS_PRINT) {
Serial.print("TEMP:\\t");
Serial.print(normalized.temperature, 2);
Serial.print("\\xC2\\xB0"); //Print degree symbol
Serial.print("C");
Serial.println();

Serial.print("GYR (");
Serial.print("\\xC2\\xB0"); //Print degree symbol
Serial.print("/s):\\t");
Serial.print(normalized.gyroscope.x, 3);
Serial.print("\\t\\t");
Serial.print(normalized.gyroscope.y, 3);
Serial.print("\\t\\t");
Serial.print(normalized.gyroscope.z, 3);
Serial.println();

Serial.print("ACC (m/s^2):\\t");
Serial.print(normalized.accelerometer.x, 3);
Serial.print("\\t\\t");
Serial.print(normalized.accelerometer.y, 3);
Serial.print("\\t\\t");
Serial.print(normalized.accelerometer.z, 3);
Serial.println();

Serial.println();

lastPrintMillis = currentMillis;
}
}

Note: the snippet is part of Arduino project located in our GitHub repository with the code separated in different logical files.

Testing

The serial monitor will print last available sensors data every INTERVAL_MS_PRINT milliseconds (in the example above, once per second) and it should be similar to:

mpu6050_testing_output.png

Usually the orientation is drawn on the physical module so you can easily detect X, Y and Z axes.

Credits

Official GitHub: https://github.com/hibit-dev/mpu6050

 Join Our Monthly Newsletter

Get the latest news and popular articles to your inbox every month

We never send SPAM nor unsolicited emails

0 Comments

Leave a Reply

Your email address will not be published.

Replying to the message: View original

Hey visitor! Unlock access to featured articles, remove ads and much more - it's free.