Jump to content

Accelerometer

From cognifront

Interfacing MPU-6500 Accelerometer and Gyroscope with ESP32

Interfacing MPU-6500 Accelerometer and Gyroscope with ESP32 demonstrates how an MPU-6500 motion sensor can be interfaced with an ESP32 board using the I²C communication protocol.

The MPU-6500 contains a 3-axis accelerometer and a 3-axis gyroscope. It can be used to measure acceleration, angular velocity and sensor temperature.

The ESP32 communicates with the MPU-6500 through the I²C bus.

ESP32 → I²C → MPU-6500 → Acceleration / Gyroscope / Temperature

Objectives

  • To study the working of the MPU-6500 sensor.
  • To interface the MPU-6500 with the ESP32 using I²C communication.
  • To read acceleration values along the X, Y and Z axes.
  • To read gyroscope values along the X, Y and Z axes.
  • To read the temperature value from the MPU-6500.
  • To verify the identity of the connected MPU-6500 sensor.

Hardware Modules

  • ESP32 Board
  • MPU-6500 Accelerometer and Gyroscope Module
  • PC / Laptop
  • USB Cable
  • Connecting wires

Software

  • Arduino IDE
  • ESP32 Board Package

Theory

MPU-6500

The MPU-6500 is a motion-tracking sensor that contains:

  • 3-axis accelerometer
  • 3-axis gyroscope
  • Temperature sensor

The sensor communicates with the ESP32 using the I²C communication protocol.

The MPU-6500 provides measurements along three axes:

Axis Accelerometer Gyroscope
X-axis Acceleration along X-axis Angular velocity around X-axis
Y-axis Acceleration along Y-axis Angular velocity around Y-axis
Z-axis Acceleration along Z-axis Angular velocity around Z-axis

MPU-6500 → X, Y, Z Axis Measurements

Accelerometer

An accelerometer measures acceleration along the three axes.

The accelerometer values are represented as:

  • AX – X-axis acceleration
  • AY – Y-axis acceleration
  • AZ – Z-axis acceleration

In the program, the default accelerometer range is:

±2g

For the ±2g range, the sensitivity is approximately:

16384 LSB/g

Therefore, the raw accelerometer values are converted into acceleration in units of g using:

Acceleration = Raw Value / 16384.0

For example:

Accel X = ax / 16384.0

Gyroscope

The gyroscope measures angular velocity around the three axes.

The gyroscope values are represented as:

  • GX – angular velocity around X-axis
  • GY – angular velocity around Y-axis
  • GZ – angular velocity around Z-axis

In the program, the default gyroscope range is:

±250 degrees/second

The sensitivity for this range is approximately:

131 LSB/(degrees/second)

The raw gyroscope values are converted using:

Angular Velocity = Raw Value / 131.0

For example:

Gyro X = gx / 131.0

Temperature Sensor

The MPU-6500 also contains an internal temperature sensor.

The raw temperature value is read from the temperature registers and converted into degrees Celsius using the formula:

Temperature = (Raw Temperature / 333.87) + 21.0

The calculated temperature is displayed on the Serial Monitor.

I²C Communication

The MPU-6500 communicates with the ESP32 using the I²C protocol.

The I²C bus uses two communication lines:

  • SDA – Serial Data
  • SCL – Serial Clock

In this program, the ESP32 uses:

I²C Signal ESP32 GPIO Function
SDA GPIO 21 Serial data
SCL GPIO 22 Serial clock

The I²C communication is initialized using:

Wire.begin(21, 22);

MPU-6500 I²C Address

The MPU-6500 is accessed using the I²C address:

0x68

The address is defined in the program using:

#define MPU_ADDR 0x68

The ESP32 uses this address when reading from and writing to the MPU-6500 registers.

MPU-6500 Registers

The program communicates directly with the MPU-6500 registers.

Important registers used in this practical are:

Register Address Function
PWR_MGMT_1 0x6B Power management / wake-up
ACCEL_XOUT_H 0x3B Accelerometer X-axis data
GYRO_XOUT_H 0x43 Gyroscope X-axis data
WHO_AM_I 0x75 Sensor identification

The sensor data registers contain high and low bytes that are combined to form a signed 16-bit value.

Sensor Wake-Up

After starting communication, the program writes:

writeRegister(PWR_MGMT_1, 0x01);

This configures the power management register and wakes the sensor for operation.

A short delay is provided after this operation before reading sensor data.

WHO_AM_I Identification

The MPU-6500 contains a WHO_AM_I register at address 0x75.

The program reads this register to check whether the expected sensor is connected.

The expected identification value in the program is:

WHO_AM_I = 0x70

If the value is 0x70, the Serial Monitor displays:

MPU-6500 Found!

Otherwise, the program displays:

Unknown sensor!

Connections

Device Pin ESP32 Function
MPU-6500 VCC 3.3V Power supply
MPU-6500 GND GND Ground
MPU-6500 SDA GPIO 21 I²C data
MPU-6500 SCL GPIO 22 I²C clock

Note: Use the appropriate supply voltage specified for the MPU-6500 module being used. While connecting to Vcc of Accelerometer, try 3.3V first, if it doesn't work then try 5V


Accelerometer with ESP32 user I2C Pins

Steps for Assembling the Circuit

  1. Connect the VCC pin of the MPU-6500 module to the appropriate supply of the ESP32.
  2. Connect the GND pin of the MPU-6500 module to GND of the ESP32.
  3. Connect the SDA pin of the MPU-6500 to GPIO 21 of the ESP32.
  4. Connect the SCL pin of the MPU-6500 to GPIO 22 of the ESP32.
  5. Check all connections before applying power.
  6. Connect the ESP32 to the PC/Laptop using a USB cable.

Safety Precautions

  • First, make all connections according to the circuit diagram.
  • Check the MPU-6500 supply voltage before connecting it to the ESP32.
  • Ensure that SDA and SCL are connected to the correct GPIO pins.
  • Ensure that the I²C connections are properly connected.
  • Check the ground connection between the ESP32 and MPU-6500.
  • Do not apply an incorrect voltage to the sensor module.
  • Then connect the ESP32 board to the PC/Laptop.

Schematic Diagram

The MPU-6500 is connected to the ESP32 using the I²C interface.

ESP32 GPIO 21 (SDA) → MPU-6500 SDA

ESP32 GPIO 22 (SCL) → MPU-6500 SCL

The ESP32 communicates with the MPU-6500 at I²C address 0x68.

Interfacing Diagram Using Breadboard

The MPU-6500 module can be connected to the ESP32 using a breadboard and jumper wires.

The required connections are:

MPU-6500 ESP32
VCC 3.3V
GND GND
SDA GPIO 21
SCL GPIO 22

Procedure

  1. Start the Arduino IDE.
  2. Connect the MPU-6500 to the ESP32 according to the connection table.
  3. Write or enter the program.
  4. Save and compile the program.
  5. Connect the ESP32 to the PC/Laptop using a USB cable.
  6. Upload the program to the ESP32.
  7. Open the Serial Monitor.
  8. Set the Serial Monitor baud rate to 115200.
  9. Observe the MPU-6500 identification message.
  10. Observe the accelerometer, gyroscope and temperature values.

Algorithm

The following algorithm is used to interface the MPU-6500 with the ESP32:

  1. Start the Arduino IDE.
  2. Include the Wire library for I²C communication.
  3. Define the MPU-6500 I²C address as 0x68.
  4. Define the required MPU-6500 register addresses.
  5. Start Serial communication at 115200 baud.
  6. Initialize I²C communication using GPIO 21 as SDA and GPIO 22 as SCL.
  7. Wake up the MPU-6500 by writing to the power management register.
  8. Read the WHO_AM_I register.
  9. Check whether the returned identification value is 0x70.
  10. Read the raw accelerometer values for the X, Y and Z axes.
  11. Read the raw gyroscope values for the X, Y and Z axes.
  12. Read the raw temperature value.
  13. Convert the accelerometer values into g.
  14. Convert the gyroscope values into degrees/second.
  15. Convert the raw temperature value into degrees Celsius.
  16. Display all values on the Serial Monitor.
  17. Wait for 200 ms.
  18. Repeat the process continuously.

The overall operation is:

MPU-6500 → I²C → ESP32 → Sensor Data Processing → Serial Monitor

Working

The ESP32 communicates with the MPU-6500 using the I²C protocol.

The I²C communication is initialized with:

Wire.begin(21, 22);

GPIO 21 is used as the SDA line and GPIO 22 is used as the SCL line.

The MPU-6500 is accessed at I²C address 0x68.

First, the ESP32 wakes the sensor by writing to the PWR_MGMT_1 register.

The ESP32 then reads the WHO_AM_I register to verify the sensor identity.

After the sensor is verified, the ESP32 reads the raw accelerometer, gyroscope and temperature data.

The raw accelerometer values are converted into g.

Raw Accelerometer → Acceleration in g

The raw gyroscope values are converted into degrees/second.

Raw Gyroscope → Angular Velocity in °/s

The raw temperature value is converted into degrees Celsius.

Raw Temperature → Temperature in °C

All calculated values are displayed on the Serial Monitor every 200 ms.

Data Conversion

The program uses the following conversion formulas:

Parameter Conversion Unit
Accelerometer X ax / 16384.0 g
Accelerometer Y ay / 16384.0 g
Accelerometer Z az / 16384.0 g
Gyroscope X gx / 131.0 degrees/second
Gyroscope Y gy / 131.0 degrees/second
Gyroscope Z gz / 131.0 degrees/second
Temperature (tempRaw / 333.87) + 21.0 °C

Program

#include <Wire.h>

#define MPU_ADDR 0x68

// MPU-6500 registers
#define PWR_MGMT_1   0x6B
#define ACCEL_XOUT_H 0x3B
#define GYRO_XOUT_H  0x43
#define WHO_AM_I     0x75

void writeRegister(byte reg, byte value)
{
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(reg);
  Wire.write(value);
  Wire.endTransmission();
}

int16_t read16(byte reg)
{
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(reg);
  Wire.endTransmission(false);

  Wire.requestFrom(MPU_ADDR, 2);

  int16_t value = 0;

  if (Wire.available() >= 2)
  {
    value = (Wire.read() << 8) | Wire.read();
  }

  return value;
}

void setup()
{
  Serial.begin(115200);
  delay(1000);

  Wire.begin(21, 22);

  Serial.println("MPU-6500 Test");

  // Wake up sensor
  writeRegister(PWR_MGMT_1, 0x01);

  delay(100);

  // Check identity
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(WHO_AM_I);
  Wire.endTransmission(false);

  Wire.requestFrom(MPU_ADDR, 1);

  if (Wire.available())
  {
    byte id = Wire.read();

    Serial.print("WHO_AM_I: 0x");
    Serial.println(id, HEX);

    if (id == 0x70)
      Serial.println("MPU-6500 Found!");
    else
      Serial.println("Unknown sensor!");
  }
}

void loop()
{
  int16_t ax = read16(0x3B);
  int16_t ay = read16(0x3D);
  int16_t az = read16(0x3F);

  int16_t gx = read16(0x43);
  int16_t gy = read16(0x45);
  int16_t gz = read16(0x47);

  int16_t tempRaw = read16(0x41);

  // Default ranges:
  // Accelerometer = ±2g
  // Gyroscope = ±250 deg/s

  float accelX = ax / 16384.0;
  float accelY = ay / 16384.0;
  float accelZ = az / 16384.0;

  float gyroX = gx / 131.0;
  float gyroY = gy / 131.0;
  float gyroZ = gz / 131.0;

  // MPU-6500 temperature formula
  float temperature = (tempRaw / 333.87) + 21.0;

  Serial.print("AX: ");
  Serial.print(accelX, 2);

  Serial.print("  AY: ");
  Serial.print(accelY, 2);

  Serial.print("  AZ: ");
  Serial.print(accelZ, 2);

  Serial.print("  GX: ");
  Serial.print(gyroX, 2);

  Serial.print("  GY: ");
  Serial.print(gyroY, 2);

  Serial.print("  GZ: ");
  Serial.print(gyroZ, 2);

  Serial.print("  Temp: ");
  Serial.println(temperature, 2);

  delay(200);
}

Observation

Open the Serial Monitor and set the baud rate to 115200.

Initially, the program displays the MPU-6500 test message and checks the sensor identity.

A valid sensor produces:

WHO_AM_I: 0x70
MPU-6500 Found!

The Serial Monitor then displays the sensor measurements in the following format:

AX: x.xx  AY: x.xx  AZ: x.xx  GX: x.xx  GY: x.xx  GZ: x.xx  Temp: xx.xx

When the sensor is moved or rotated, the accelerometer and gyroscope values change accordingly.

The temperature value is also displayed continuously.

The readings are updated every 200 ms.

Result

The ESP32 successfully interfaces with the MPU-6500 using I²C communication.

The ESP32 successfully reads and displays:

  • X-axis acceleration
  • Y-axis acceleration
  • Z-axis acceleration
  • X-axis angular velocity
  • Y-axis angular velocity
  • Z-axis angular velocity
  • Sensor temperature

The MPU-6500 identity is also verified using the WHO_AM_I register before sensor measurements are displayed.