MPU9250 Arduino SSD1306 OLED
Assalamualaikum. In this article, I will provide a tutorial on how to retrieve data from the MPU9250 using Arduino and show the data on the OLED SSD1306 I2C using the u8g2 library.
About MPU-9250
MPU-9250 is an IC in which there are Gyroscope, Accelerometer, and Magnetometer sensors. Each sensor has the ability to read 3-axis, so this mpu9250 IC is also called the Nine-Axis MEMS Motion Tracking Device.
You can see the features of each sensor in the following table:
Range : ±250, ±500, ±1000, and ±2000°/sec
16-bit ADCs
Operating current: 3.2mA
Sleep mode current: 8µAAccelerometer Range : ±2g, ±4g, ±8g and ±16g
16-bit ADCs
Operating current: 450µA
Sleep mode current: 8µAGyroscope Range: ±4800µT
14-bit ADCs
Operating current: 280µAMagnetometer
MPU9250 Pinout
To make it easier for us to use this IC, several company make modules that look like the following:
VCC : +2.4V to +3.6V
GND : 0V
SCL : Serial Clock (I2C)
SDA : Serial Data (I2C)
EDA : Serial Data (Master I2C) for external sensor
ECL : Serial Clock (Master I2C) for external sensor
AD0 : I2C Address.
If AD0 = 0, the address is 1101000.(0x68)
If AD0 = 1, the address is 1101001(0x69)
INT : Interrupt Digital Output
NCS : Chip select (SPI mode only)
FSYNC : Frame synchronization digital input. Connect to GND when not in use
Credit : Tenstar Robot
Arduino MPU-9250 Wiring
To show the data sensor in an OLED display, I use OLED with I2C communication, so the pins used are SCL and SDA.
The MPU9250 sensor, also uses I2C communication, so that the SCL and SDA pins on the MPU9250 and OLED are connected together.
Here it is reminded that this module works normally at +3.3V. The board used is Arduino Uno utilizing the +3.3V pin as shown in the picture beside.
Henceforth, so that Arduino Uno can read data from the sensor module, we use a library from Sparkfun.
Arduino library
The library for this sensor module is available in the Library Manager. To compile this program code, I use Arduino IDE 2. How to add this library is shown in the following image:
a. MPU9250
At the time of writing this article, the version of this library is 1.0.2. It may differ from the version you use later.
b. U8g2
After the library installation is complete, let’s look at the basic program code below.
Code
The program code below is the Example program code from the library above. However, for personal use, I deleted several lines of the program so that it was easier to read.
Use the following program code, then upload it to your Arduino board.
/* MPU9250 Basic Example Code
by: Kris Winer
date: April 1, 2014
Modified by Brent Wilkins July 19, 2016
*/
#include "quaternionFilters.h"
#include "MPU9250.h"
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#define SerialDebug true // Set to true to get Serial output for debugging
#define I2Cclock 400000
#define I2Cport Wire
#define MPU9250_ADDRESS MPU9250_ADDRESS_AD0 // Use either this line or the next to select which I2C address your device is using
//#define MPU9250_ADDRESS MPU9250_ADDRESS_AD1
MPU9250 myIMU(MPU9250_ADDRESS, I2Cport, I2Cclock);
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
void setup() {
Wire.begin();
u8g2.begin();
byte c = myIMU.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);
if (c == 0x71) {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_6x13_tr);
u8g2.setCursor(0, 13);
u8g2.print("MPU9250 is Online");
} while (u8g2.nextPage());
delay(500);
// Start by performing self test and reporting values
myIMU.MPU9250SelfTest(myIMU.selfTest);
// Calibrate gyro and accelerometers, load biases in bias registers
myIMU.calibrateMPU9250(myIMU.gyroBias, myIMU.accelBias);
// Initialize device for active mode read of acclerometer, gyro, and temp
myIMU.initMPU9250();
// Read the WHO_AM_I register of the magnetometer
byte d = myIMU.readByte(AK8963_ADDRESS, WHO_AM_I_AK8963);
if (d != 0x48) {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_6x13_tr);
u8g2.setCursor(0, 13);
u8g2.print("Failed...");
} while (u8g2.nextPage());
delay(500);
}
// Get magnetometer calibration from AK8963 ROM
// Initialize device for active mode read of magnetometer
myIMU.initAK8963(myIMU.factoryMagCalibration);
// Get sensor resolutions, only need to do this once
myIMU.getAres();
myIMU.getGres();
myIMU.getMres();
} else {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_6x13_tr);
u8g2.setCursor(0, 13);
u8g2.print("MPU9250 is Offline");
} while (u8g2.nextPage());
delay(2000);
}
}
void loop() {
// If intPin goes high, all data registers have new data
// On interrupt, check if data ready interrupt
if (myIMU.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) {
myIMU.readAccelData(myIMU.accelCount); // Read the x/y/z adc values
// Now we'll calculate the accleration value into actual g's
// This depends on scale being set
myIMU.ax = (float)myIMU.accelCount[0] * myIMU.aRes; // - myIMU.accelBias[0];
myIMU.ay = (float)myIMU.accelCount[1] * myIMU.aRes; // - myIMU.accelBias[1];
myIMU.az = (float)myIMU.accelCount[2] * myIMU.aRes; // - myIMU.accelBias[2];
myIMU.readGyroData(myIMU.gyroCount); // Read the x/y/z adc values
// Calculate the gyro value into actual degrees per second
// This depends on scale being set
myIMU.gx = (float)myIMU.gyroCount[0] * myIMU.gRes;
myIMU.gy = (float)myIMU.gyroCount[1] * myIMU.gRes;
myIMU.gz = (float)myIMU.gyroCount[2] * myIMU.gRes;
myIMU.readMagData(myIMU.magCount); // Read the x/y/z adc values
// Calculate the magnetometer values in milliGauss
// Include factory calibration per data sheet and user environmental
// corrections
// Get actual magnetometer value, this depends on scale being set
myIMU.mx = (float)myIMU.magCount[0] * myIMU.mRes
* myIMU.factoryMagCalibration[0]
- myIMU.magBias[0];
myIMU.my = (float)myIMU.magCount[1] * myIMU.mRes
* myIMU.factoryMagCalibration[1]
- myIMU.magBias[1];
myIMU.mz = (float)myIMU.magCount[2] * myIMU.mRes
* myIMU.factoryMagCalibration[2]
- myIMU.magBias[2];
} // if (readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01)
// Must be called before updating quaternions!
myIMU.updateTime();
//Pass gyro rate as rad/s
MahonyQuaternionUpdate(myIMU.ax, myIMU.ay, myIMU.az, myIMU.gx * DEG_TO_RAD,
myIMU.gy * DEG_TO_RAD, myIMU.gz * DEG_TO_RAD, myIMU.my,
myIMU.mx, myIMU.mz, myIMU.deltat);
myIMU.delt_t = millis() - myIMU.count;
if (myIMU.delt_t > 500) {
u8g2.firstPage();
do {
//Set font for tittle
u8g2.setFont(u8g2_font_6x13_tr);
u8g2.drawStr(10, 14, "Akcel");
u8g2.drawStr(53, 14, "Gyro");
u8g2.drawStr(90, 14, "Magnet");
u8g2.setCursor(0, 25);
u8g2.print("X");
u8g2.setCursor(0, 38);
u8g2.print("Y");
u8g2.setCursor(0, 50);
u8g2.print("Z");
//Set font for data
u8g2.setFont(u8g2_font_5x7_tr);
//Show Accelerometer Data
u8g2.setCursor(10, 25);
u8g2.print(1000 * myIMU.ax);
u8g2.setCursor(10, 37);
u8g2.print(1000 * myIMU.ay);
u8g2.setCursor(10, 49);
u8g2.print(1000 * myIMU.az);
//Show Gyroscope Data
u8g2.setCursor(53, 25);
u8g2.print(myIMU.gx, 1);
u8g2.setCursor(53, 37);
u8g2.print(myIMU.gy, 1);
u8g2.setCursor(53, 49);
u8g2.print(myIMU.gz, 1);
//Show Magnetometer Data
u8g2.setCursor(90, 25);
u8g2.print(myIMU.mx);
u8g2.setCursor(90, 37);
u8g2.print(myIMU.my);
u8g2.setCursor(90, 49);
u8g2.print(myIMU.mz);
// Read the adc values
myIMU.tempCount = myIMU.readTempData();
// Temperature in degrees Centigrade
myIMU.temperature = ((float)myIMU.tempCount) / 333.87 + 21.0;
// Print temperature in degrees Centigrade
// Show Temperature Data
u8g2.setCursor(0, 62);
u8g2.print("Temperature:");
u8g2.setCursor(65, 62);
u8g2.print(myIMU.temperature, 2);
u8g2.setCursor(95, 62);
u8g2.print("C");
} while (u8g2.nextPage());
myIMU.count = millis();
}
}
Result
MPU9250 Datasheet
If needed, I attach the datasheet below to see a complete description of this MPU-9250 IC.
If you get a mistake either in words or program code, comment below immediately. Hopefully, this article on how to read data from the MPU9250 using Arduino is useful.
Read more:
- remote rejected main -> main (pre-receive hook declined)
- 32 bit Linux Distro Available In 2022
- CH340 dev ttyUSB not showing Linux, but detected in terminal
- Baud Rate Arduino On Serial Port. What Does It Mean?
- Install Arduino IDE Ubuntu 22.04 Terminal