In this tutorial, we will learn how to use MPU-6050 module which is one of the best IMU (Inertia Measurement Unit) sensors, compatible with Arduino. IMU sensors like the MPU-6050 are used in self balancing robots, UAVs, smart phones, etc.
(1)x Elegoo ESP32
(2) x 400 Tie Points Breadboard
(1) x MPU-6050 module
(4) x F-M wires
The InvenSense MPU-6050 sensor contains a MEMS accelerometer and a MEMS gyro in a single chip. It is very accurate, as it contains 16-bits analog to digital conversion hardware for each channel.
Therefore it captures the x, y, and z channel at the same time. The sensor uses the I2C-bus to interface with the Arduino.
The MPU-6050 is not expensive, especially given the fact that it combines both an accelerometer and a gyro.
IMU sensors are one of the most inevitable type of sensors used today in all kinds of electronic gadgets. They are seen in smart phones, wearables, game controllers, etc. IMU sensors help us in getting the attitude of an object, attached to the sensor in three dimensional space. These values usually in angles, thus help us to determine its attitude. Thus, they are used in smart phones to detect its orientation. And also in wearable gadgets like the nike fuel band or fit bit, which use IMU sensors to track movement.
IMU sensors usually consists of two or more parts. Listing them by priority, they are : accelerometer, gyroscope, magnetometer and altimeter. The MPU-6050 is a 6 DOF (Degrees of Freedom) or a six axis IMU sensor, which means that it gives six values as output. Three values from the accelerometer and three from the gyroscope. The MPU-6050 is a sensor based on MEMS (Micro Electro Mechanical Systems) technology. Both the accelerometer and the gyroscope is embedded inside a single chip. This chip uses I2C (Inter Integrated Circuit) protocol for communication.
An accelerometer works on the principle of piezo electric effect. Here, imagine a cuboidal box, having a small ball inside it, like in the picture above. The walls of this box are made with piezo electric crystals. Whenever you tilt the box, the ball is forced to move in the direction of the inclination, due to gravity.
The wall with which the ball collides, creates tiny piezo electric currents. There are totally, three pairs of opposite walls in a cuboid. Each pair corresponds to an axis in 3D space: X, Y and Z axes. Depending on the current produced from the piezo electric walls, we can determine the direction of inclination and its magnitude. For more information check this.
Gyroscopes work on the principle of Coriolis acceleration. Imagine that there is a fork- like structure, which is in constant back- and- forth motion. It is held in place using piezo electric crystals. Whenever you try to tilt this arrangement, the crystals experience a force in the direction of inclination. This is caused as a result of the inertia of the moving fork. The crystals thus produce a current in consensus with the piezo electric effect, and this current is amplified. The values are then refined by the host microcontroller.
You can click the blue text link to download the program file to your local device, and double-click the file to open it after the download is complete. Please note: Before opening the file, ensure that you have installed the Arduino IDE development environment and completed the installation of relevant components such as the board support package and driver corresponding to the ESP32 development board. If you have any questions about this operation process, you can refer to the "part 1" chapter of the document for detailed guidance mpu-6050.zip
#include<Wire.h>
const int MPU_addr=0x68; // I2C address of the MPU-6050int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
Library and Sensor Configuration:
#include<Wire.h>: Includes the Wire library for I2C communicationconst int MPU_addr=0x68: Defines the I2C address of the MPU-6050 sensor (default address: 0x68)int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ: Declares 16-bit integer variables to store sensor data:
16-bit Integer Data Type:
The int16_t type is a signed 16-bit integer that can represent values from -32768 to 32767. This is used because the MPU-6050 outputs data in 16-bit resolution, providing a good balance between precision and memory usage.
I2C Communication:
The MPU-6050 uses I2C (Inter-Integrated Circuit) communication protocol, which allows multiple devices to communicate using just two wires (SDA for data and SCL for clock).
void setup(){
Wire.begin(21,22);
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
Serial.begin(9600);
}
setup() Function:Initializes the system and configures the MPU-6050 sensor.
Wire.begin(21,22): Initializes the I2C bus with SDA pin 21 and SCL pin 22 (ESP32-specific I2C pins)Wire.beginTransmission(MPU_addr): Starts communication with the MPU-6050 sensorWire.write(0x6B): Selects the PWR_MGMT_1 register (address 0x6B)Wire.write(0): Writes 0 to wake up the MPU-6050 (default is in sleep mode)Wire.endTransmission(true): Ends transmission and releases the busSerial.begin(9600): Initializes serial communication at 9600 baud rate for data outputloop() Function Overview:The main loop that continuously reads sensor data and displays it on the serial monitor. This function can be divided into several key functional modules:
1. Sensor Data Request Module:
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers
false parameter in endTransmission(false) keeps the I2C bus active for subsequent communication2. Data Reading and Assembly Module:
AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
<<8 (shift left by 8 bits) to move the high byte to the correct position, then | (bitwise OR) to combine with the low byte3. Data Display Module:
Serial.print("AcX = "); Serial.print(AcX);
Serial.print(" | AcY = "); Serial.print(AcY);
Serial.print(" | AcZ = "); Serial.print(AcZ);
Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53); //From the datasheet of MPU6050, we can know the temperature formula
Serial.print(" | GyX = "); Serial.print(GyX);
Serial.print(" | GyY = "); Serial.print(GyY);
Serial.print(" | GyZ = "); Serial.println(GyZ);
Serial.print() for continuous output and Serial.println() for the final value to move to the next line4. Delay Module:
delay(500);
Open the monitor then you can see the data as blow:Click the Serial Monitor button to turn on the serial monitor. The basics about the serial monitor are introduced in details in part 2 Lesson 4.
MPU-6050 Register Map:
Serial Monitor Output:
I2C Pin Configuration (ESP32):
MPU-6050 Power Management:
Data Resolution:
Calibration Considerations:
Applications: