MPU6050 (i2cdevlib): raw motion data and calibration
Jeff Rowberg鈥檚 i2cdevlib MPU6050 library is the oldest and most complete way into the InvenSense MPU6050, the six-axis accelerometer and gyroscope on the GY-521 board. It talks to the chip register by register through I2Cdev, so almost every setting the datasheet names has a call: ranges, filters, the sample rate, interrupts, the FIFO and the offset registers.
Built in on Mokxi: #include <MPU6050.h> and it builds, with nothing to install. Free, and no account needed.
What MPU6050 does
Readings come out as raw signed 16-bit counts. At the default ranges, 16384 counts are one g of acceleration and 131 counts are one degree per second of rotation; change the range with setFullScaleAccelRange() and the numbers per unit change with it. Converting to real units is the sketch鈥檚 job.
The library is also known for its DMP examples, which load InvenSense鈥檚 motion processor firmware onto the chip to get a fused quaternion. That part is not simulated in Mokxi: dmpInitialize() returns 1 and the DMP examples say so. The raw reads, the ranges and the offset calibration all work.
| Library Manager name | MPU6050 |
|---|---|
| Author | Electronic Cats, Jeff Rowberg (i2cdevlib) |
| Include | #include <MPU6050.h>#include <I2Cdev.h>#include <MPU6050_6Axis_MotionApps20.h>#include <MPU6050_6Axis_MotionApps612.h> |
| Boards | every board Mokxi compiles for but ATtiny85 |
| In the simulator | Runs, with a gap the note below names. |
| Parts it drives | Accelerometer and gyroscope, MPU6050 |
Install it
It builds on every board Mokxi compiles for but ATtiny85.
In Mokxi it is built in: #include <MPU6050.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "MPU6050" by Electronic Cats, Jeff Rowberg (i2cdevlib) from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add MPU6050 to lib_deps in PlatformIO. Mokxi follows the calls of release 1.3.1, so a sketch written here builds there too.
What to know in the simulator: The DMP is not simulated: dmpInitialize() returns 1 and the DMP examples say so.
ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
MPU6050 mpu
Creates the sensor at the default address 0x68 (0x69 when AD0 is pulled high).
mpu.initialize()
Wakes the chip from sleep and sets the clock and the default ranges. Call Wire.begin() first.
mpu.testConnection()
True when the chip answers with the right ID. Print it in setup() so a wiring fault is obvious.
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz)
Reads all six axes in one I2C transfer into int16_t variables.
int16_t ax, ay, az, gx, gy, gz;
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
float gForceZ = az / 16384.0;mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_4)
Sets the accelerometer to plus or minus 4 g (8192 counts a g). FS_2, FS_8 and FS_16 are the others.
mpu.CalibrateAccel(6)
Averages readings with the board lying flat and writes offsets so the axes read zero (and one g on Z). CalibrateGyro(6) does the gyro.
mpu.setXAccelOffset(-1343)
Writes a known offset straight into the chip, with the Y, Z and gyro versions beside it, so a calibrated board does not need calibrating at every start.
mpu.PrintActiveOffsets()
Prints the offsets now in the chip, ready to paste into setup().
Example: Raw MPU6050 counts with i2cdevlib
On the Arduino Uno R3. It runs in the browser exactly as printed.
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"
MPU6050 accelgyro;
int16_t ax, ay, az;
int16_t gx, gy, gz;
void setup() {
Wire.begin();
Serial.begin(38400);
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
}
void loop() {
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
Serial.print("a/g:\t");
Serial.print(ax); Serial.print("\t");
Serial.print(ay); Serial.print("\t");
Serial.print(az); Serial.print("\t");
Serial.print(gx); Serial.print("\t");
Serial.print(gy); Serial.print("\t");
Serial.println(gz);
delay(250);
}Wiring
- Arduino Uno R3 A4 to Accelerometer and gyroscope, MPU6050 SDA
- Arduino Uno R3 A5 to Accelerometer and gyroscope, MPU6050 SCL
- Arduino Uno R3 5V to Accelerometer and gyroscope, MPU6050 VCC
- Arduino Uno R3 GND to Accelerometer and gyroscope, MPU6050 GND
Common errors and how to fix them
MPU6050 connection failed
testConnection() read the wrong ID or nothing at all. Check SDA and SCL, that AD0 matches the address you expect, and that Wire.begin() runs before initialize(). Some cheap boards carry an MPU6500, which reports a different ID.
DMP Initialization failed (code 1)
On a real board that code means the DMP firmware failed to load, often from a bad I2C line. In Mokxi the DMP is not simulated and this is the expected result; use getMotion6() or a filter such as Madgwick for orientation.
The gyro reads a few hundred counts when the board is still
Every MPU6050 has a zero offset. Run CalibrateGyro() with the board still, then copy the printed offsets into setXGyroOffset() and its neighbors.
Keep going
Try MPU6050 without installing anything
Open the example, change the sketch, and keep your version in a free account.