Professional Documents
Culture Documents
Measuring Rotation
Measuring Temperature
The I2C Interface
As kids, the gyroscopes at the science fair never failed to amaze us because they moved in
strange ways and even seemed to defy gravity. Their unique properties make them crucial in
everything from small RC helicopters to the advanced navigation system on the space
shuttle.
Without a doubt, the gyroscope and accelerometer are each exceptional in their own way.
However, when we put them together, we can obtain incredibly precise data about an
object’s orientation. This is where the MPU6050 enters the picture. The MPU6050 includes a
gyroscope and an accelerometer, allowing us to measure rotation along all three axes, static
acceleration due to gravity, and dynamic acceleration due to motion.
Before we use the MPU6050 in our Arduino project, it’s a good idea to understand how
accelerometers and gyroscopes work.
The Russian Mir space station relied on 11 gyroscopes to keep its orientation to
the sun. The Hubble Space Telescope is equipped with six navigational gyros that
ensure accurate pointing during observations.
Assuming that the cube is in outer space, where everything is weightless, the ball will simply
float in the center of the cube.
If we suddenly move the box to the left with acceleration 1g (a single G-force 1g is equivalent
to gravitational acceleration 9.8 m/s2), the ball will undoubtedly hit the wall X. If we measure
the force the ball exerts on wall X, we can obtain an output value of 1g along the X axis.
Let’s see what happens when we place that cube on Earth. The ball will simply fall on the wall
Z, exerting a force of 1g as shown in the diagram below:
In this case, the box isn’t moving, but we still get a 1g reading on the Z axis. This is because
gravity (which is actually a form of acceleration) is pulling the ball downward with a force of
1g.
While this model does not exactly represent how a real-world accelerometer sensor is built, it
is often useful in understanding why an accelerometer’s output signal is typically specified in
±g, or why an accelerometer reads 1g in the z-axis at rest, or what accelerometer readings
you can expect at different orientations.
This structure is suspended by polysilicon springs. It allows the structure to deflect when
accelerated along the X, Y, and/or Z axes.
As a result of deflection, the capacitance between fixed plates and plates attached to the
suspended structure changes. This change in capacitance is proportional to the acceleration
along that axis.
The sensor processes this change in capacitance and converts it into an analog output
voltage.
Coriolis Effect
The Coriolis Effect states that when a mass (m) moves in a specific direction with a velocity (v)
and an external angular rate (Ω) is applied (Red arrow), the Coriolis Effect generates a force
(Yellow arrow) that causes the mass to move perpendicularly. The value of this displacement
is directly related to the angular rate applied.
When we begin to rotate the structure, the Coriolis force acting on the moving proof mass
causes the vibration to change from horizontal to vertical.
There are three modes depending on the axis along which the angular rotation is applied.
Roll Mode:
When an angular rate is applied along the X-axis, M1 and M3 will move up and down out of
the plane due to the coriolis effect. This causes a change in the roll angle, hence the name
Roll Mode.
Pitch Mode:
When an angular rate is applied along the Y-axis, M2 and M4 will move up and down out of
the plane. This causes a change in the pitch angle, hence the name Pitch Mode.
Yaw Mode:
When an angular rate is applied along the Z-axis, M2 and M4 will move horizontally in
opposite directions. This causes a change in the yaw angle, hence the name Yaw Mode.
Whenever the coriolis effect is detected, the constant motion of the driving mass will cause a
change in capacitance (∆C) that is detected by the sensing structure and converted into a
voltage signal.
For your information, this is what the MEMS structure die of a 3-axis digital gyroscope looks
like. Thanks to Adam McCombs for sharing this image of a decaped L3GD20HTR MEMS
gyroscope.
It can measure angular momentum or rotation along all three axes, static acceleration caused
by gravity, and dynamic acceleration caused by motion, shock, or vibration.
The module includes an on-board LD3985 3.3V regulator, so you can safely use it with a 5V
logic microcontroller like Arduino.
The MPU6050 consumes less than 3.6mA during measurements and only 5μA when idle.
Because of its low power consumption, it can be used in battery-powered devices.
Additionally, the module has a Power LED that illuminates when the module is powered on.
Measuring Acceleration
The MPU6050 has an on-chip accelerometer that can measure acceleration over four
programmable full scale ranges of ±2g, ±4g, ±8g, and ±16g.
The MPU6050 is equipped with three 16-bit analog-to-digital converters that simultaneously
sample the three axes of movement (along the X, Y, and Z axes).
Measuring Rotation
The MPU6050 has an on-chip gyroscope that can measure angular rotation over four
programmable full scale ranges of ±250°/s, ±500°/s, ±1000°/s, and ±2000°/s.
The MPU6050 is equipped with three more 16-bit analog-to-digital converters that
simultaneously sample the three axes of rotation (along the X, Y, and Z axes). The sampling
rate can be adjusted from 3.9 to 8000 samples per second.
Measuring Temperature
The MPU6050 includes an embedded temperature sensor that can measure temperatures
from -40 to 85°C with a ±1°C accuracy.
Note that this temperature measurement is of the silicon die itself, not the ambient
temperature. These measurements are typically used to compensate for accelerometer and
gyroscope calibration or to detect temperature changes rather than measuring absolute
temperatures.
The ADO pin determines the I2C address of the module. This pin is pulled down with a 4.7K
resistor. Therefore, when you leave the ADO pin unconnected, the default I2C address is
0x68HEX; when you connect it to 3.3V, the line is pulled HIGH, and the I2C address becomes
0x69HEX.
This external connection is usually used to attach a magnetometer, which can measure
magnetic fields along three axes. The MPU6050 has six Degrees of Freedom (DOF), three for
the accelerometer and three for the gyroscope combined. The addition of a magnetometer
increases the sensor’s degree of freedom from 6 to 9 DOF.
Technical Specifications
Here are the specifications:
MPU6050 Datasheet
XDA is the external I2C data line. The external I2C bus is for connecting external sensors,
such as a magnetometer.
AD0 allows you to change the I2C address of the MPU6050 module. It can be used to avoid
conflicts between the module and other I2C devices or to connect two MPU6050s to the
same I2C bus. When you leave the ADO pin unconnected, the default I2C address is 0x68HEX;
when you connect it to 3.3V, the I2C address changes to 0x69HEX.
INT is the Interrupt Output pin. The MPU6050 can be programmed to generate an interrupt
upon detection of gestures, panning, zooming, scrolling, tap detection, and shake detection.
Connections are straightforward. Begin by connecting the VCC pin to the Arduino’s 5V
output and the GND pin to ground.
Now we are left with the pins that are used for I2C communication. Note that each Arduino
board has different I2C pins that must be connected correctly. On Arduino boards with the
R3 layout, the SDA (data line) and SCL (clock line) are on the pin headers close to the AREF
pin. They are also referred to as A5 (SCL) and A4 (SDA).
SCL SDA
Arduino Uno A5 A4
Arduino Nano A5 A4
Arduino Mega 21 20
Leonardo/Micro 3 2
Library Installation
Setting up the MPU6050 module to begin capturing the device’s raw data output is fairly
simple. Manipulating the data into something meaningful, on the other hand, is more
difficult, but there are some libraries at our disposal.
To install the library, navigate to Sketch > Include Library > Manage Libraries… Wait for the
Library Manager to download the library index and update the list of installed libraries.
Filter your search by entering ‘mpu6050’. Look for the Adafruit MPU6050 Library by
Adafruit. Click on that entry and then choose Install.
The Adafruit MPU6050 library makes use of the Adafruit Unified Sensor Driver and Adafruit
Bus IO Library internally. So, search the library manager for Adafruit Unified Sensor and BusIO
and install them as well.
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;
void setup(void) {
Serial.begin(115200);
// Try to initialize!
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
Make sure you set the baud rate to “115200” in the serial port monitor. Because the
MPU6050 returns an excessive amount of data, this higher speed is required to display it.
There will be a lot of information displayed, such as linear acceleration, angular rotation, and
temperature. Move your sensor around and observe how the data changes.
Code Explanation:
At the beginning of the sketch, all the necessary libraries are included. As previously stated,
the Adafruit_MPU6050 library implements the hardware functions of the MPU6050, while the
Adafruit_Sensor library implements the unified sensor abstraction layer. Wire.h, which allows
us to communicate with I2C devices, is also included.
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Next, an instance of the Adafruit_MPU6050 class is created in order to access its associated
methods.
Adafruit_MPU6050 mpu;
In the setup section of the code, we first initialize the serial communication with the PC and
call the begin() function. The begin() function initializes the I2C interface and verifies
that the chip ID is correct. It then soft-resets the chip and waits for the sensor to calibrate
after wake-up.
Serial.begin(115200);
// Try to initialize!
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
The following three functions are then used to configure the measurement range of the
MPU6050.
setAccelerometerRange(mpu6050_accel_range_t)
Keep in mind that the smaller the range, the more sensitive the accelerometer readings will
be.
setGyroRange(mpu6050_gyro_range_t)
The setGyroRange() function sets the gyroscope measurement range. This function accepts
the following values:
setFilterBandwidth(mpu6050_bandwidth_t)
The setFilterBandwidth() function sets the bandwidth of the Digital Low-Pass Filter. This
function accepts the following values:
The bandwidth selection allows you to alter the low-pass filter’s cutoff frequency, allowing
you to smooth out the signal by removing high-frequency noise.
In this example, we set the accelerometer range to ±8G, the gyro range to ±500°/s, and the
filter bandwidth to 21 Hz.
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
In the loop section of the code, we create three objects of type sensors_event_t to hold
our results. sensors_event_t is simply a user-defined datatype (structures in C) that stores
a variety of sensor data such as acceleration, gyro, temperature, light, pressure, and many
others. More information is available on github.
sensors_event_t a, g, temp;
The function getEvent() is then called. This function reads a new set of values from the
sensor (a sensor “event”), converts them to the correct SI units and scale, and then assigns
the results to our mpu object.
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");
The Arduino IDE includes a useful tool called the serial plotter. It can provide real-time
visualizations of variables. This is extremely useful for visualizing data, debugging code, and
visualizing variables as waveforms.
Let’s give it a shot with the updated code below. Compile and upload the program below,
then navigate to Tools > Serial Plotter (Ctrl+Shift+L). The code uses a baud rate of 115200;
ensure that the serial plotter is also set to 115200.
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;
void setup(void) {
Serial.begin(115200);
// Try to initialize!
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
When you move the module up and down the Z axis, you should see something like this.
Code Explanation:
You’ll notice that the majority of this sketch is identical to the previous one, with the
exception of:
All other readings are printed in such a way that they form a comma-separated list of
values.
SHARE