This guide will teach you how to use the MPU-6050 accelerometer and gyroscope module with the ESP32. The MPU-6050 IMU (Inertial Measurement Unit) features a 3-axis accelerometer and a 3-axis gyroscope. The accelerometer measures gravitational acceleration, while the gyroscope measures rotational velocity. Additionally, the module can measure temperature. This sensor is perfect for determining the orientation of a moving object.
Introducing the MPU-6050 Gyroscope and Accelerometer Sensor
The MPU-6050 module features a 3-axis accelerometer and a 3-axis gyroscope.
The gyroscope measures rotational velocity (rad/s), which is the change in angular position over time along the X, Y, and Z axes (roll, pitch, and yaw). This helps determine an object’s orientation.
The accelerometer measures acceleration, the rate of change of an object’s velocity. It detects static forces like gravity (9.8m/s²) and dynamic forces such as vibrations or movement. The MPU-6050 measures acceleration along the X, Y, and Z axes. For a static object, the acceleration along the Z axis equals the gravitational force, while it should be zero along the X and Y axes.
Using the accelerometer’s values, you can calculate the roll and pitch angles with trigonometry. However, it is not possible to calculate yaw this way.
By combining data from both the accelerometer and gyroscope, you can obtain more accurate information about the sensor’s orientation.
Parts Required
Component Name | Buy Now |
ESP32-WROOM-32 Development | Amazon |
MPU6050 3 Axis Accelerometer Gyroscope Module 6 DOF 6-axis | Amazon |
0.96 Inch OLED I2C IIC Display Module | Amazon |
MPU-6050 Pinout
Here’s the pinout for the MPU-6050 sensor module.
VCC | Power the sensor (3.3V or 5V) |
GND | Common GND |
SCL | SCL pin for I2C communication (GPIO 22) |
SDA | SDA pin for I2C communication (GPIO 21) |
XDA | Used to interface other I2C sensors with the MPU-6050 |
XCL | Used to interface other I2C sensors with the MPU-6050 |
AD0 | Use this pin to change the I2C address |
INT | Interrupt pin – can be used to indicate that new measurement data is available |
Preparing Arduino IDE
Installing Libraries
To read data from the sensor, we will use the Adafruit MPU6050 library. Additionally, you’ll need to install the Adafruit Unified Sensor library and the Adafruit Bus IO library.
Open your Arduino IDE and navigate to Sketch > Include Library > Manage Libraries. This will open the Library Manager.
In the search box, type “adafruit mpu6050” and install the corresponding library.
Next, search for “Adafruit Unified Sensor”. Scroll down to locate and install this library.
Finally, search for “Adafruit Bus IO” and install it as well.
After installing all the required libraries, restart your Arduino IDE.
If you are using VS Code with PlatformIO, add the following lines to your platformio.ini
file:
lib_deps = adafruit/Adafruit MPU6050 @ ^2.0.3 adafruit/Adafruit Unified Sensor @ ^1.1.4
Obtaining MPU-6050 Sensor Readings: Accelerometer, Gyroscope, and Temperature
In this section, you’ll learn how to read data from the MPU-6050 sensor, including acceleration (x, y, z), angular velocity (x, y, z), and temperature.
Schematic Diagram – Connecting ESP32 with MPU-6050
Connect the ESP32 to the MPU-6050 sensor according to the schematic: attach the SCL pin to GPIO 22
and the SDA pin to GPIO 21
.
Code – Reading MPU-6050 Sensor Data: Accelerometer, Gyroscope, and Temperature
The Adafruit library includes several examples for the MPU-6050 sensor. Here, we’ll use the basic example that displays sensor readings in the Serial Monitor.
Navigate to File > Examples > Adafruit MPU6050 > basic_readings. The following code will load, which retrieves angular velocity (gyroscope) on the x, y, and z axes, acceleration on the x, y, and z axes, and temperature.
#include <Adafruit_MPU6050.h> #include <Adafruit_Sensor.h> #include <Wire.h> Adafruit_MPU6050 mpu; void setup(void) { Serial.begin(115200); while (!Serial) delay(10); // will pause Zero, Leonardo, etc until serial console opens Serial.println("Adafruit MPU6050 test!"); // Try to initialize! if (!mpu.begin()) { Serial.println("Failed to find MPU6050 chip"); while (1) { delay(10); } } Serial.println("MPU6050 Found!"); mpu.setAccelerometerRange(MPU6050_RANGE_8_G); Serial.print("Accelerometer range set to: "); switch (mpu.getAccelerometerRange()) { case MPU6050_RANGE_2_G: Serial.println("+-2G"); break; case MPU6050_RANGE_4_G: Serial.println("+-4G"); break; case MPU6050_RANGE_8_G: Serial.println("+-8G"); break; case MPU6050_RANGE_16_G: Serial.println("+-16G"); break; } mpu.setGyroRange(MPU6050_RANGE_500_DEG); Serial.print("Gyro range set to: "); switch (mpu.getGyroRange()) { case MPU6050_RANGE_250_DEG: Serial.println("+- 250 deg/s"); break; case MPU6050_RANGE_500_DEG: Serial.println("+- 500 deg/s"); break; case MPU6050_RANGE_1000_DEG: Serial.println("+- 1000 deg/s"); break; case MPU6050_RANGE_2000_DEG: Serial.println("+- 2000 deg/s"); break; } mpu.setFilterBandwidth(MPU6050_BAND_5_HZ); Serial.print("Filter bandwidth set to: "); switch (mpu.getFilterBandwidth()) { case MPU6050_BAND_260_HZ: Serial.println("260 Hz"); break; case MPU6050_BAND_184_HZ: Serial.println("184 Hz"); break; case MPU6050_BAND_94_HZ: Serial.println("94 Hz"); break; case MPU6050_BAND_44_HZ: Serial.println("44 Hz"); break; case MPU6050_BAND_21_HZ: Serial.println("21 Hz"); break; case MPU6050_BAND_10_HZ: Serial.println("10 Hz"); break; case MPU6050_BAND_5_HZ: Serial.println("5 Hz"); break; } Serial.println(""); delay(100); } void loop() { /* Get new sensor events with the readings */ sensors_event_t a, g, temp; mpu.getEvent(&a, &g, &temp); /* Print out the values */ Serial.print("Acceleration X: "); Serial.print(a.acceleration.x); Serial.print(", Y: "); Serial.print(a.acceleration.y); Serial.print(", Z: "); Serial.print(a.acceleration.z); Serial.println(" m/s^2"); Serial.print("Rotation X: "); Serial.print(g.gyro.x); Serial.print(", Y: "); Serial.print(g.gyro.y); Serial.print(", Z: "); Serial.print(g.gyro.z); Serial.println(" rad/s"); Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degC"); Serial.println(""); delay(500); }
Code Explanation
Including Libraries
First, include the necessary libraries for the MPU-6050 sensor:
#include <Adafruit_MPU6050.h> #include <Adafruit_Sensor.h>
Creating the MPU Object
Create an Adafruit_MPU6050
object named mpu
to interact with the sensor:
Adafruit_MPU6050 mpu;
Setup Function
In the setup()
, start the serial monitor at a baud rate of 115200:
Serial.begin(115200);
Initialize the MPU-6050 sensor.
if (!mpu.begin()) { Serial.println("Sensor init failed"); while (1) yield(); }
Set the accelerometer measurement range:
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
Set the gyroscope measurement range:
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
Set the filter bandwidth:
mpu.setFilterBandwidth(MPU6050_BAND_5_HZ);
Loop Function
In the loop()
, read sensor data and display it on the Serial Monitor.
First, retrieve the current sensor events:
sensors_event_t a, g, temp; mpu.getEvent(&a, &g, &temp);
Print the acceleration readings (measured in meters per second squared, m/s²):
Serial.print("Acceleration X: "); Serial.print(a.acceleration.x); Serial.print(", Y: "); Serial.print(a.acceleration.y); Serial.print(", Z: "); Serial.print(a.acceleration.z); Serial.println(" m/s^2");
Print the gyroscope readings (measured in radians per second, rad/s):
Serial.print("Rotation X: "); Serial.print(g.gyro.x); Serial.print(", Y: "); Serial.print(g.gyro.y); Serial.print(", Z: "); Serial.print(g.gyro.z); Serial.println(" rad/s");
Print the temperature reading (measured in degrees Celsius):
Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degC");
Update the sensor readings every 500 milliseconds:
delay(500);
Demonstration
Upload the code to your ESP32 board. To do this, go to Tools > Board and select the appropriate ESP32 board you are using. Then, go to Tools > Port and select the port your board is connected to. Click the Upload button to upload the code.
Open the Serial Monitor with a baud rate of 115200 and press the on-board RST button. The sensor readings will be displayed in the Serial Monitor.
Move the sensor to see how the values change with its orientation.
Sensor Calibration
When the sensor is stationary, the gyroscope readings should ideally be zero on all axes. However, this isn’t the case with our sensor. When stationary, the gyroscope provides the following readings:
- x: 0.06 rad/s
- y: -0.02 rad/s
- z: 0.00 rad/s
In practical applications, it’s important to account for these errors and adjust the values in the code for more accurate readings.
The same applies to the accelerometer values. The acceleration on the z-axis should be close to the gravitational force (9.8 m/s²), and close to zero on the x and y axes. When the sensor is static, we get approximately:
- x: 0.71 m/s²
- y: 0.28 m/s²
- z: 9.43 m/s²
Display MPU-6050 Readings on OLED Display
The Adafruit MPU6050 library includes an example that shows how to display the gyroscope and accelerometer readings on an OLED display.
Schematic Diagram – Connecting ESP32 with MPU-6050 and OLED Display
Connect all components as shown in the schematic diagram. Since the OLED display and the MPU-6050 sensor use different I2C addresses, they can share the same I2C bus and connect to the same pins on the ESP32.
Code – Displaying MPU-6050 Sensor Readings on OLED
To run this example, ensure you have the Adafruit SSD1306 library installed. You can install this library via the Arduino Library Manager.
- Go to Sketch > Include Library > Manage Libraries.
- Search for “SSD1306” and install the Adafruit SSD1306 library.
Then, either copy the following code or go to File > Examples > Adafruit MPU6050 > MPU6050_oled.
#include <Adafruit_MPU6050.h> #include <Adafruit_SSD1306.h> #include <Adafruit_Sensor.h> Adafruit_MPU6050 mpu; Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire); void setup() { Serial.begin(115200); // while (!Serial); Serial.println("MPU6050 OLED demo"); if (!mpu.begin()) { Serial.println("Sensor init failed"); while (1) yield(); } Serial.println("Found a MPU-6050 sensor"); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64 Serial.println(F("SSD1306 allocation failed")); for (;;) ; // Don't proceed, loop forever } display.display(); delay(500); // Pause for 2 seconds display.setTextSize(1); display.setTextColor(WHITE); display.setRotation(0); } void loop() { sensors_event_t a, g, temp; mpu.getEvent(&a, &g, &temp); display.clearDisplay(); display.setCursor(0, 0); Serial.print("Accelerometer "); Serial.print("X: "); Serial.print(a.acceleration.x, 1); Serial.print(" m/s^2, "); Serial.print("Y: "); Serial.print(a.acceleration.y, 1); Serial.print(" m/s^2, "); Serial.print("Z: "); Serial.print(a.acceleration.z, 1); Serial.println(" m/s^2"); display.println("Accelerometer - m/s^2"); display.print(a.acceleration.x, 1); display.print(", "); display.print(a.acceleration.y, 1); display.print(", "); display.print(a.acceleration.z, 1); display.println(""); Serial.print("Gyroscope "); Serial.print("X: "); Serial.print(g.gyro.x, 1); Serial.print(" rps, "); Serial.print("Y: "); Serial.print(g.gyro.y, 1); Serial.print(" rps, "); Serial.print("Z: "); Serial.print(g.gyro.z, 1); Serial.println(" rps"); display.println("Gyroscope - rps"); display.print(g.gyro.x, 1); display.print(", "); display.print(g.gyro.y, 1); display.print(", "); display.print(g.gyro.z, 1); display.println(""); display.display(); delay(100); }
This code initializes the MPU-6050 and OLED display, reads the sensor data, and displays the accelerometer, gyroscope, and temperature readings on the OLED screen.
Code Explanation
Including Libraries
First, include the necessary libraries for the MPU-6050 sensor and the OLED display:
#include <Adafruit_MPU6050.h> #include <Adafruit_SSD1306.h> #include <Adafruit_Sensor.h>
Creating Objects
Create an Adafruit_MPU6050
object named mpu
to interact with the sensor:
Adafruit_MPU6050 mpu;
Create an Adafruit_SSD1306
object named display
for the OLED display with 128×64 pixels:
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
Setup Function
In the setup()
, initialize the serial monitor at a baud rate of 115200:
Serial.begin(115200);
Initialize the MPU-6050 sensor.
if (!mpu.begin()) { Serial.println("Sensor init failed"); while (1) yield(); }
Initialize the OLED display.
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64 Serial.println(F("SSD1306 allocation failed")); for (;;) ; // Don't proceed, loop forever } display.display();
Set the font size and color for the display.
display.setTextSize(1); display.setTextColor(WHITE); display.setRotation(0);
Loop Function
In the loop()
, read sensor data and display it on the OLED.
Start by creating events for the accelerometer, gyroscope, and temperature:
sensors_event_t a, g, temp;
Get new sensor readings.
mpu.getEvent(&a, &g, &temp);
Clear the display in each loop() to write new readings.
display.clearDisplay();
Set the display cursor to (0,0) – the upper left corner. It will start writing text from that location.
display.setCursor(0, 0);
The following lines print the accelerometer readings in the Serial Monitor.
Serial.print("Accelerometer "); Serial.print("X: "); Serial.print(a.acceleration.x, 1); Serial.print(" m/s^2, "); Serial.print("Y: "); Serial.print(a.acceleration.y, 1); Serial.print(" m/s^2, "); Serial.print("Z: "); Serial.print(a.acceleration.z, 1); Serial.println(" m/s^2");
The following lines display the acceleration x, y an z values on the OLED display.
display.println("Accelerometer - m/s^2"); display.print(a.acceleration.x, 1); display.print(", "); display.print(a.acceleration.y, 1); display.print(", "); display.print(a.acceleration.z, 1); display.println("");
Display the gyroscope readings on the Serial Monitor.
Serial.print("Gyroscope "); Serial.print("X: "); Serial.print(g.gyro.x, 1); Serial.print(" rps, "); Serial.print("Y: "); Serial.print(g.gyro.y, 1); Serial.print(" rps, "); Serial.print("Z: "); Serial.print(g.gyro.z, 1); Serial.println(" rps");
Finally, print the gyroscope readings on the display.
display.println("Gyroscope - rps"); display.print(g.gyro.x, 1); display.print(", "); display.print(g.gyro.y, 1); display.print(", "); display.print(g.gyro.z, 1); display.println("");
Lastly, call display.display() to actually show the readings on the OLED.
display.display();
New readings are displayed every 100 milliseconds.
delay(100);
Demonstration
To demonstrate, upload the code to your ESP32 board:
- Go to Tools > Board and select your ESP32 board.
- Go to Tools > Port and choose the port your board is connected to.
- Click the upload button.
Once the code is uploaded, open the Serial Monitor at a baud rate of 115200 and press the on-board RST button. The sensor measurements will be displayed on both the Serial Monitor and the OLED display.
Move the sensor to observe the changing values.
Wrapping Up
The MPU-6050 is a sensor module that measures acceleration along the x, y, and z axes, as well as angular velocity. It also includes a temperature sensor.
This module uses the I2C communication protocol, making the wiring straightforward. Simply connect the sensor to the default I2C pins on the ESP32.
In this tutorial, you learned how to wire the MPU-6050 sensor to the ESP32 and read its data. We hope you found this getting started guide helpful. Check out our other guides for more popular sensors.