Skip to content

Commit

Permalink
mpu9250 (accel, gyro, magneto) classes added
Browse files Browse the repository at this point in the history
  • Loading branch information
tomas-fryza committed Feb 24, 2025
1 parent 9e02951 commit b213be6
Show file tree
Hide file tree
Showing 38 changed files with 5,869 additions and 0 deletions.
21 changes: 21 additions & 0 deletions examples/03-mpu9250/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2018-2023 Mika Tuupola

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
21 changes: 21 additions & 0 deletions examples/03-mpu9250/MPU9250_WE/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 Wolfgang (Wolle) Ewald

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions examples/03-mpu9250/MPU9250_WE/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# MPU9250_WE
An Arduino library for the 9-axis accelerometer, gyroscope and magnetometer MPU9250 and the MPU6500. In essence the MPU6500 is a MPU9250 without the magnetometer. The library also provides basic support for the MPU6050.

The library contains many example sketches with lots of comments to make it easy to use. I have written them for the MPU9250 / I2C. You can "translate" them easily for the MPU6500. MPU6500_all_data.ino shows how to do this. The use of SPI is shown in MPU9250_SPI_all_data.ino and MPU6500_SPI_all_data.ino.

For further information visit my blog:

https://wolles-elektronikkiste.de/mpu9250-9-achsen-sensormodul-teil-1 (German)

https://wolles-elektronikkiste.de/en/mpu9250-9-axis-sensor-module-part-1 (English)

If you find bugs please inform me. If you like the library it would be great if you could give it a star.

If you are not familiar with the MPU9250 I recommend to work through the example sketches in the following order:

1. MPU9250_acceleration_data.ino
2. MPU9250_gyroscope_data.ino
3. MPU9250_calibration.ino
4. MPU9250_reusing_autocalib_data.ino
5. MPU9250_magnetometer_data.ino
6. MPU9250_all_data.ino
7. MPU9250_angles_and_orientation.ino
8. MPU9250_pitch_and_roll.ino
9. MPU9250_data_ready_interrupt_and_cycle.ino
10. MPU9250_wake_on_motion_interrupt.ino
11. MPU9250_FIFO_stop_when_full.ino
12. MPU9250_FIFO_continuous.ino
13. MPU6500_all_data.ino
14. MPU6050_all_data.ino

The sketch MPU9250_blank_all_settings.ino can be used as a basis for your own sketches. It contains all setting options.

<h3>If the MPU9250 / MPU6500 does not respond</h3>

There are various modules with different MPUxxxx ICs out there. Sometimes it's not clearly defined in online-shops what you will really get if you buy an MPU9250/MPU6500 module. It might be an MPU9250, it might be an MPU6500 or it might be something else, although the modules look the same. An indication is the label on the MPUxxxx IC:

![MPU9250](https://user-images.githubusercontent.com/41305162/181456778-d3f69414-2627-445b-82b9-560dbfcbf982.jpg)

The labels I am aware of are:

- MP92: MPU9250
- MP65: MPU6500
- MP651: MPU6515

You can also run the example sketch MPU9250_who_am_I.ino to find out which device you have.

I am using the "Who I am" registers of the MPU9250, MPU6500 and the magnetometer AK8963 to check if the modules are connected. If you create an MPU9250 object, but, for example, you are actually using an MPU6500, the init functions will return "false". However, the gyroscope and the accelerometer will work, because all related registers are the same. For other variants it might be similar. If the library works although you are using a different MPUxxxx, then just be happy, but you will have to live with the init function returning "false" - or find an alternative library.

<h3>Support of the MPU6050</h3>

The library does support the MPU6050 only to a limited extent. You can query the accelaration, gyroscope and temperature values, and you can choose the range. But more advance functions like WOM interrupt, FIFO and others will no work properly. And I do not intend to work further on MPU6050 functions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/***************************************************************************
* Example sketch for the MPU9250_WE library (MPU6050)
*
* This sketch shows how to get acceleration, gyroscocope and temperature
* data from the MPU6050. In essence, the MPU6050 is an older version of the
* MPU6500. Due to the poor register documentation, not all functions do work
* on the MPU6050 like they do on the MPU6500 or MPU9250.
*
* For further information visit my blog:
*
* https://wolles-elektronikkiste.de/mpu9250-9-achsen-sensormodul-teil-1 (German)
* https://wolles-elektronikkiste.de/en/mpu9250-9-axis-sensor-module-part-1 (English)
*
***************************************************************************/
#include <MPU6050_WE.h>
#include <Wire.h>
#define MPU6050_ADDR 0x68

/* There are several ways to create your MPU6050 object:
* MPU6050_WE myMPU6050 = MPU6050_WE() -> uses Wire / I2C Address = 0x68
* MPU6050_WE myMPU6050 = MPU6050_WE(MPU6050_ADDR) -> uses Wire / MPU6050_ADDR
* MPU6050_WE myMPU6050 = MPU6050_WE(&wire2) -> uses the TwoWire object wire2 / MPU6050_ADDR
* MPU6050_WE myMPU6050 = MPU6050_WE(&wire2, MPU6050_ADDR) -> all together
* Successfully tested with two I2C busses on an ESP32
*/
MPU6050_WE myMPU6050 = MPU6050_WE(MPU6050_ADDR);

void setup() {
Serial.begin(115200);
Wire.begin();
if(!myMPU6050.init()){
Serial.println("MPU6050 does not respond");
}
else{
Serial.println("MPU6050 is connected");
}

/* The slope of the curve of acceleration vs measured values fits quite well to the theoretical
* values, e.g. 16384 units/g in the +/- 2g range. But the starting point, if you position the
* MPU6050 flat, is not necessarily 0g/0g/1g for x/y/z. The autoOffset function measures offset
* values. It assumes your MPU6050 is positioned flat with its x,y-plane. The more you deviate
* from this, the less accurate will be your results.
* The function also measures the offset of the gyroscope data. The gyroscope offset does not
* depend on the positioning.
* This function needs to be called at the beginning since it can overwrite your settings!
*/
Serial.println("Position you MPU6050 flat and don't move it - calibrating...");
delay(1000);
myMPU6050.autoOffsets();
Serial.println("Done!");

/* This is a more accurate method for calibration. You have to determine the minimum and maximum
* raw acceleration values of the axes determined in the range +/- 2 g.
* You call the function as follows: setAccOffsets(xMin,xMax,yMin,yMax,zMin,zMax);
* Use either autoOffset or setAccOffsets, not both.
*/
//myMPU6050.setAccOffsets(-14240.0, 18220.0, -17280.0, 15590.0, -20930.0, 12080.0);

/* The gyroscope data is not zero, even if you don't move the MPU6050.
* To start at zero, you can apply offset values. These are the gyroscope raw values you obtain
* using the +/- 250 degrees/s range.
* Use either autoOffset or setGyrOffsets, not both.
*/
//myMPU6050.setGyrOffsets(45.0, 145.0, -105.0);

/* MPU6050_GYRO_RANGE_250 250 degrees per second (default)
* MPU6050_GYRO_RANGE_500 500 degrees per second
* MPU6050_GYRO_RANGE_1000 1000 degrees per second
* MPU6050_GYRO_RANGE_2000 2000 degrees per second
*/
myMPU6050.setGyrRange(MPU6050_GYRO_RANGE_250);

/* MPU6050_ACC_RANGE_2G 2 g (default)
* MPU6050_ACC_RANGE_4G 4 g
* MPU6050_ACC_RANGE_8G 8 g
* MPU6050_ACC_RANGE_16G 16 g
*/
myMPU6050.setAccRange(MPU6050_ACC_RANGE_2G);

delay(200);
}

void loop() {
xyzFloat gValue = myMPU6050.getGValues();
xyzFloat gyr = myMPU6050.getGyrValues();
float temp = myMPU6050.getTemperature();
float resultantG = myMPU6050.getResultantG(gValue);

Serial.println("Acceleration in g (x,y,z):");
Serial.print(gValue.x);
Serial.print(" ");
Serial.print(gValue.y);
Serial.print(" ");
Serial.println(gValue.z);
Serial.print("Resultant g: ");
Serial.println(resultantG);

Serial.println("Gyroscope data in degrees/s: ");
Serial.print(gyr.x);
Serial.print(" ");
Serial.print(gyr.y);
Serial.print(" ");
Serial.println(gyr.z);

Serial.print("Temperature in °C: ");
Serial.println(temp);

Serial.println("********************************************");

delay(1000);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/***************************************************************************
* Example sketch for the MPU6500_WE library
*
* This sketch shows how to get acceleration, gyroscocope and temperature
* data from the MPU6500 using SPI.
*
* For further information visit my blog:
*
* https://wolles-elektronikkiste.de/mpu9250-9-achsen-sensormodul-teil-1 (German)
* https://wolles-elektronikkiste.de/en/mpu9250-9-axis-sensor-module-part-1 (English)
*
***************************************************************************/

#include <MPU6500_WE.h>
const int csPin = 10; // Chip Select Pin
// const int mosiPin = 22; // "MOSI" Pin
// const int misoPin = 21; // "MISO" Pin
// const int sckPin = 16; // SCK Pin
bool useSPI = true; // SPI use flag


/* There are two constructors for SPI: */
MPU6500_WE myMPU6500 = MPU6500_WE(&SPI, csPin, useSPI);

/* Use this one if you want to change the default SPI pins (only for ESP32 so far): */
// MPU6500_WE myMPU6500 = MPU6500_WE(&SPI, csPin, mosiPin, misoPin, sckPin, useSPI);

void setup() {
Serial.begin(115200);
Wire.begin();
if(!myMPU6500.init()){
Serial.println("MPU6500 does not respond");
}
else{
Serial.println("MPU6500 is connected");
}

/* Choose the SPI clock speed, default is 8 MHz
This function must be used only after init(), not before */
//myMPU9250.setSPIClockSpeed(4000000);

Serial.println("Position you MPU6500 flat and don't move it - calibrating...");
delay(1000);
myMPU6500.autoOffsets();
Serial.println("Done!");

//myMPU6500.setAccOffsets(-14240.0, 18220.0, -17280.0, 15590.0, -20930.0, 12080.0);
//myMPU6500.setGyrOffsets(45.0, 145.0, -105.0);
myMPU6500.enableGyrDLPF();
//myMPU6500.disableGyrDLPF(MPU6500_BW_WO_DLPF_8800); // bandwdith without DLPF
myMPU6500.setGyrDLPF(MPU6500_DLPF_6);
myMPU6500.setSampleRateDivider(5);
myMPU6500.setGyrRange(MPU6500_GYRO_RANGE_250);
myMPU6500.setAccRange(MPU6500_ACC_RANGE_2G);
myMPU6500.enableAccDLPF(true);
myMPU6500.setAccDLPF(MPU6500_DLPF_6);
//myMPU6500.enableAccAxes(MPU6500_ENABLE_XYZ);
//myMPU6500.enableGyrAxes(MPU6500_ENABLE_XYZ);
}

void loop() {
xyzFloat gValue = myMPU6500.getGValues();
xyzFloat gyr = myMPU6500.getGyrValues();
float temp = myMPU6500.getTemperature();
float resultantG = myMPU6500.getResultantG(gValue);

Serial.println("Acceleration in g (x,y,z):");
Serial.print(gValue.x);
Serial.print(" ");
Serial.print(gValue.y);
Serial.print(" ");
Serial.println(gValue.z);
Serial.print("Resultant g: ");
Serial.println(resultantG);

Serial.println("Gyroscope data in degrees/s: ");
Serial.print(gyr.x);
Serial.print(" ");
Serial.print(gyr.y);
Serial.print(" ");
Serial.println(gyr.z);

Serial.print("Temperature in °C: ");
Serial.println(temp);

Serial.println("********************************************");

delay(1000);
}
Loading

0 comments on commit b213be6

Please sign in to comment.