MPU6050 Example with Arduino
TL;DR
This guide provides an example of how to use the MPU6050 accelerometer and gyroscope with Arduino, using PlatformIO for development. It includes instructions for connecting the MPU6050 to Arduino, setting up PlatformIO, handling common permission issues, and reading data from the sensor.
PIN Connections
Arduino MPU6050
------- -------
3.3V ----------> VCC
GND ----------> GND
SCL ----------> SCL
SDA ----------> SDA
Checking Arduino Connection Port
- Check USB devices using
lsusb
, where CH340 should appear, indicating the Arduino. - Verify the port using
ls /dev/tty*
, which should show something likettyUSB0
orttyUSB1
. -
If you receive a permission error for
/dev/ttyUSB0
, follow these steps:-
Add user to dialout group:
sudo usermod -aG dialout $USER
-
Check connected port:
sudo dmesg | grep tty
-
Check and fix permissions (if necessary):
ls -l /dev/ttyUSB0 sudo chmod a+rw /dev/ttyUSB0
-
Setting Up PlatformIO for Arduino
- Install PlatformIO from the VSCode extensions tab.
-
Create a new project:
- Click New Project in PIO Home under Quick Access.
- Name the project (e.g.,
mpu6050
). - Select
Arduino Uno
as the board andArduino
as the framework. - Set a location for the project, e.g.,
/home/$USER/PlatformIO/mpu6050/
.
-
Code Setup:
PlatformIO projects use
.cpp
files instead of Arduino’s.ino
files.Example
src/main.cpp
file:#include <Arduino.h> int counter = 0; void setup() { Serial.begin(9600); } void loop() { counter++; Serial.println(counter); delay(1000); }
- Build and Upload:
- Click Build (
✓
icon). - Click Upload (
→
icon).
- Click Build (
Resolving udev
Permission Issues for PlatformIO
-
Install PlatformIO’s udev rules:
sudo curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/refs/heads/develop/platformio/assets/system/99-platformio-udev.rules -o /etc/udev/rules.d/99-platformio-udev.rules
-
Restart
udev
:sudo service udev restart
MPU6050 Data Reading Example
-
Install the
Adafruit MPU6050
library from PlatformIO:- Go to Libraries in PIO Home and search for “MPU6050”.
-
Project Configuration (
platformio.ini
):[env:uno] platform = atmelavr board = uno framework = arduino monitor_speed = 115200 lib_deps = adafruit/Adafruit MPU6050@^2.2.6
-
MPU6050 Code Example:
// Arduino MPU6050 // ------- ------- // 3.3V ----------> VCC // GND ----------> GND // SCL ----------> SCL // SDA ----------> SDA #include <Arduino.h> // Basic demo for accelerometer readings from Adafruit MPU6050 #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_21_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.print(" 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.print(" rad/s"); Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degC"); delay(100); }
Earthquake Detection Example
To detect rapid acceleration changes that might indicate an earthquake, you can modify the loop to detect large spikes in acceleration:
// Arduino MPU6050
// ------- -------
// 3.3V ----------> VCC
// GND ----------> GND
// SCL ----------> SCL
// SDA ----------> SDA
#include <Arduino.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;
// Settings for earthquake detection
const float gravitationalAccel = 9.80665; // Gravitational acceleration (m/s²)
float previousNetAccel = 0; // Previous net acceleration value
float accelThreshold = 0.85; // Threshold value (m/s²)
unsigned long durationThreshold = 500; // Threshold for earthquake duration (ms)
// Settings for running variables
float readingSensitivity = 0.05; // Reading sensitivity (m/s²)
unsigned long startTime = 0;
int loopDelay = 200; // Loop delay (ms)
void setup()
{
Serial.begin(115200);
Wire.begin();
// Initialize the MPU6050 sensor
if (!mpu.begin())
{
Serial.println("MPU6050 connection failed!");
while (1)
;
}
mpu.setAccelerometerRange(MPU6050_RANGE_8_G); // Set the accelerometer range
mpu.setGyroRange(MPU6050_RANGE_500_DEG); // Set the gyro range
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ); // Set the filter bandwidth
Serial.println("MPU6050 ready, starting to read data...");
}
void checkEarthquake()
{
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
// Calculate total acceleration
float totalAccel = sqrt(pow(a.acceleration.x, 2) + pow(a.acceleration.y, 2) + pow(a.acceleration.z, 2));
float netAccel = abs(totalAccel - gravitationalAccel); // Calculate net acceleration
// Check if the net acceleration value has changed by more than 5%
if (abs(netAccel - previousNetAccel) > previousNetAccel * readingSensitivity)
{
Serial.print("Net Acceleration: ");
Serial.print(netAccel);
Serial.println(" m/s²");
previousNetAccel = netAccel; // Update previous net acceleration value
}
// Earthquake detection
if (netAccel > accelThreshold)
{
if (startTime == 0)
{
startTime = millis(); // Set the start time of the earthquake
}
}
else
{
startTime = 0; // No movement
}
// Detect earthquake if high acceleration is detected for a certain duration
if (startTime > 0 && millis() - startTime > durationThreshold)
{
Serial.println("Earthquake Detected!");
// Alarm, logging, etc. can be done here
}
}
void loop()
{
checkEarthquake(); // Call the earthquake check function
// Other operations or conditions can be added here
delay(loopDelay); // Short delay
}