A library for Invensense MPU chips. It is written in C++ and designed for working with ESP32 microcontroller esp-idf framework. Supports both SPI and I2C protocols interchangeably, selectable bus port, and even multiple connected MPUs.
part | sensors | protocol |
---|---|---|
MPU6000 | Gyro/Accel | I2C, SPI |
MPU6050 | Gyro/Accel | I2C |
MPU6500 | Gyro/Accel | I2C, SPI |
MPU6555 | Gyro/Accel | I2C, SPI |
MPU9150 | Gyro/Accel/Compass | I2C |
MPU9250 | Gyro/Accel/Compass | I2C, SPI |
MPU9255 | Gyro/Accel/Compass | I2C, SPI |
ICM20948 | Gyro/Accel/Compass | I2C, SPI |
- Support to SPI and I2C protocol (with selectable port)
- Basic configurations (sample rate (4Hz~32KHz), clock source, full-scale, standby mode, offsets, interrupts, DLPF, etc..)
- Burst reading for all sensors
- Low Power Accelerometer mode (various rates, e.g. 8.4μA at 0.98Hz)
- Low Power Wake-on-motion mode (with motion detection interrupt)
- FIFO buffer access for all internal and external sensors
- Complete Auxiliary I2C support for external sensors (up to 4)
- External Frame Synchronization (FSYNC) pass-through interrupt
- Motion, Zero-motion and Free-Fall detection (as motion detection interrupt)
- Total access to the Magnetometer (even when MPU connected by SPI protocol)
- Calibration for Gyro and Accel
- Self-Test (true implementation from MotionApps)
- Quaternion (3-axis Gyroscope)
- Quaternion (6-axis Gyroscope and Accelerometer)
- Screen Orientation (Android's screen rotation algorithm)
- Tap Detection
- Pedometer
- Gyroscope calibrated data
MPU driver depends on the following protocol libraries to communicate with the chip with ease: [ I2Cbus | SPIbus ].
You must download the one according to the protocol you'll use and place within your components directory as well.
I2Cbus: git clone https://github.com/natanaeljr/esp32-I2Cbus.git I2Cbus
SPIbus: git clone https://github.com/natanaeljr/esp32-SPIbus.git SPIbus
Note: At least one of these libraries must be installed as components for the MPU library to work. It won't work otherwise.
Download the repository, or clone it right into your project components directory with the following command.
git clone https://github.com/poadoc/esp32-MPU-driver
This way you can easily update the library with git pull
whenever a update is available.
First of all, make sure MPU Driver is a component in you project, then run make menuconfig
, select your chip model and communication protocol you'll use browsing through to Component config
-> MPU Driver
.
Now, in your source code, include the mpu main header MPU.hpp
, the communication library I2Cbus.hpp
or SPIbus.hpp
and any other mpu headers that you'll use. Then get the bus ready as shown below.
#include "MPU.hpp" // main file, provides the class itself
#include "mpu/math.hpp" // math helper for dealing with MPU data
#include "mpu/types.hpp" // MPU data types and definitions
#include "I2Cbus.hpp"
// ...
i2c0.begin(SDA, SCL, CLOCK); // initialize the I2C bus
And for SPI:
#include "MPU.hpp" // main file, provides the class itself
#include "mpu/math.hpp" // math helper for dealing with MPU data
#include "mpu/types.hpp" // MPU data types and definitions
#include "SPIbus.hpp"
// ...
hspi.begin(MOSI, MISO, SCLK); // initialize the SPI bus
spi_device_handle_t mpu_spi_handle;
hspi.addDevice(SPIMODE, CLOCK, CS_PIN, &mpu_spi_handle);
Note: You can initialize/configure the bus through the esp-idf API normally, it should work just fine too.
Create a MPU object, setup and initialize it.
MPU_t MPU; // create an object
MPU.setBus(i2c0); // set communication bus, for SPI -> pass 'hspi'
MPU.setAddr(mpud::MPU_I2CADDRESS_AD0_LOW); // set address or handle, for SPI -> pass 'mpu_spi_handle'
MPU.testConnection() // test connection with the chip, return is a error code
MPU.initialize(); // this will initialize the chip and set default configurations
Call set
functions to configure the chip as needed.
MPU.setSampleRate(250); // in (Hz)
MPU.setAccelFullScale(mpud::ACCEL_FS_4G);
MPU.setGyroFullScale(mpud::GYRO_FS_500DPS);
MPU.setDigitalLowPassFilter(mpud::DLPF_42HZ); // smoother data
MPU.setInterruptEnabled(mpud::INT_EN_RAWDATA_READY); // enable INT pin
Read sensor data:
mpud::raw_axes_t accelRaw; // holds x, y, z axes as int16
mpud::raw_axes_t gyroRaw; // holds x, y, z axes as int16
MPU.acceleration(&accelRaw); // fetch raw data from the registers
MPU.rotation(&gyroRaw); // fetch raw data from the registers
printf("accel: %+d %+d %+d\n", accelRaw.x, accelRaw.y, accelRaw.z);
printf("gyro: %+d %+d %+d\n", gyroRaw[0], gyroRaw[1], gyroRaw[2]);
Convert to more readable formats.
mpud::float_axes_t accelG = mpud::accelGravity(accelRaw, mpud::ACCEL_FS_4G); // raw data to gravity
mpud::float_axes_t gyroDPS = mpud::gyroDecPerSec(gyroRaw, mpud::GYRO_FS_500DPS); // raw data to º/s
printf("accel: %+.2f %+.2f %+.2f\n", accelG[0], accelG[1], accelG[2]);
printf("gyro: %+.2f %+.2f %+.2f\n", gyroDPS.x, gyroDPS.y, gyroDPS.z);
The API provides many other functions to manage and operate the sensor in its full potencial. See API Reference .
See MPU Unit Test for more information.