Skip to content

Arduino library for MPU6500 Six-Axis (Gyro + Accelerometer) aka fake MPU9250

License

Notifications You must be signed in to change notification settings

paulosincos/MPU6500_aka-fake9250

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Work in Progress Fork

This fork is a working in progress convertion of hideakitai/MPU9250 repository to support fake MPU9250 that not work as expected.

In fact, these fake sensors are MPU6500 and has no magnetometers, or if it has magnetomers, it is a mistery on how it can be activated.

The goal of this fork is to bring compatibility to work as MPU6500 with accelerometer and gyro.

The quarternions filters was removed due to:

  • better code abstraction, this repo only cover the raw sensor funcionality;
  • a quaternion calculation needs a magnetomer to work as expected, so, you will need a additional magnetometer sensor, since these fake sensors doesn't has one (or its doesn't work); Trying to adapt a quaternion to work with no magnetometer will trap you in a issue called yaw drift, that make fake yaw moves even if the sensor is still on a flat table. This fake moves ins't constant and can't be normalized without a magnetomer, I tried it a lot and ended up buying a external magnetometer (QMC5883L) to work together the fake mpu;
  • a specific repository with a abstract quaternion will be created;

To use this lib, instead importing the MPU9250.h (from hideakitai), import the MPU6500_Raw.h, but remember the code is not the same.

==========================================

Original read-me from source repository

==========================================

MPU9250

Arduino library for MPU9250 Nine-Axis (Gyro + Accelerometer + Compass) MEMS MotionTracking™ Device

This library is based on the great work by kriswiner, and re-writen for the simple usage.

WARNING

MPU-9250 has been DISCONTINUED. I won't provide active support. This library supports only genuine MPU-9250, and I can't help other copy products of it

If you have a problem, first read the FAQ. After that, please search for similar issues. Please open the issue and fill out the issue template if you can't find the solution.

FAQ

There are interference between some axes

There are some possibilities.

  • Your device may not be a genuine MPU-9250
  • Calibration is not enough
  • Gimbal lock

Please refer #62, #69, etc.

Magnetometer is always zero

Your device may not be a genuine MPU-9250. Please refer #52 #72

Usage

Simple Measurement

#include "MPU9250.h"

MPU9250 mpu; // You can also use MPU9255 as is

void setup() {
    Serial.begin(115200);
    Wire.begin();
    delay(2000);

    mpu.setup(0x68);  // change to your own address
}

void loop() {
    if (mpu.update()) {
        Serial.print(mpu.getYaw()); Serial.print(", ");
        Serial.print(mpu.getPitch()); Serial.print(", ");
        Serial.println(mpu.getRoll());
    }
}

Calibration

  • accel/gyro/mag offsets are NOT stored to register if the MPU has powered off (app note)
  • need to set all offsets at every bootup by yourself (or calibrate at every bootup)
  • device should be stay still during accel/gyro calibration
  • round device around during mag calibration
#include "MPU9250.h"

MPU9250 mpu; // You can also use MPU9255 as is

void setup() {
    Serial.begin(115200);
    Wire.begin();
    delay(2000);

    mpu.setup(0x68);  // change to your own address

    delay(5000);

    // calibrate anytime you want to
    mpu.calibrateAccelGyro();
    mpu.calibrateMag();
}

void loop() { }

Coordinate

The coordinate of quaternion and roll/pitch/yaw angles are basedd on airplane coordinate (Right-Handed, X-forward, Z-down). On the other hand, the coordinate of euler angle is based on the axes of acceleration and gyro sensors (Right-Handed, X-forward, Z-up).Please use getEulerX/Y/Z() for euler angles and getRoll/Pitch/Yaw() for airplane coordinate angles.

Other Settings

I2C Address

You must set your own address based on A0, A1, A2 setting as:

mpu.setup(0x70);

Customize MPU9250 Configuration

You can set your own setting using MPU9250Setting struct as:

MPU9250Setting setting;
setting.accel_fs_sel = ACCEL_FS_SEL::A16G;
setting.gyro_fs_sel = GYRO_FS_SEL::G2000DPS;
setting.mag_output_bits = MAG_OUTPUT_BITS::M16BITS;
setting.fifo_sample_rate = FIFO_SAMPLE_RATE::SMPL_200HZ;
setting.gyro_fchoice = 0x03;
setting.gyro_dlpf_cfg = GYRO_DLPF_CFG::DLPF_41HZ;
setting.accel_fchoice = 0x01;
setting.accel_dlpf_cfg = ACCEL_DLPF_CFG::DLPF_45HZ;

mpu.setup(0x68, setting);

See custom_setting.ino example for detail.

List of Settings

enum class ACCEL_FS_SEL { A2G, A4G, A8G, A16G };
enum class GYRO_FS_SEL { G250DPS, G500DPS, G1000DPS, G2000DPS };
enum class MAG_OUTPUT_BITS { M14BITS, M16BITS };

enum class FIFO_SAMPLE_RATE : uint8_t {
    SMPL_1000HZ,
    SMPL_500HZ,
    SMPL_333HZ,
    SMPL_250HZ,
    SMPL_200HZ,
    SMPL_167HZ,
    SMPL_143HZ,
    SMPL_125HZ,
};

enum class GYRO_DLPF_CFG : uint8_t {
    DLPF_250HZ,
    DLPF_184HZ,
    DLPF_92HZ,
    DLPF_41HZ,
    DLPF_20HZ,
    DLPF_10HZ,
    DLPF_5HZ,
    DLPF_3600HZ,
};

enum class ACCEL_DLPF_CFG : uint8_t {
    DLPF_218HZ_0,
    DLPF_218HZ_1,
    DLPF_99HZ,
    DLPF_45HZ,
    DLPF_21HZ,
    DLPF_10HZ,
    DLPF_5HZ,
    DLPF_420HZ,
};

struct MPU9250Setting {
    ACCEL_FS_SEL     accel_fs_sel {ACCEL_FS_SEL::A16G};
    GYRO_FS_SEL      gyro_fs_sel {GYRO_FS_SEL::G2000DPS};
    MAG_OUTPUT_BITS  mag_output_bits {MAG_OUTPUT_BITS::M16BITS};
    FIFO_SAMPLE_RATE fifo_sample_rate {FIFO_SAMPLE_RATE::SMPL_200HZ};
    uint8_t          gyro_fchoice {0x03};
    GYRO_DLPF_CFG    gyro_dlpf_cfg {GYRO_DLPF_CFG::DLPF_41HZ};
    uint8_t          accel_fchoice {0x01};
    ACCEL_DLPF_CFG   accel_dlpf_cfg {ACCEL_DLPF_CFG::DLPF_45HZ};
};

Magnetic Declination

Magnetic declination should be set depending on where you are to get accurate data. To set it, use this method.

mpu.setMagneticDeclination(value);

You can find magnetic declination in your city here.

For more details, see wiki.

Quaternion Filter

You can choose quaternion filter using void selectFilter(QuatFilterSel sel). Available quaternion filters are listed below.

enum class QuatFilterSel {
    NONE,
    MADGWICK, // default
    MAHONY,
};

You can also change the calculate iterations for the filter as follows. The default value is 1. Generally 10-20 is good for stable yaw estimation. Please see this discussion for the detail.

mpu.setFilterIterations(10);

Other I2C library

You can use other I2C library e.g. SoftWire.

MPU9250_<SoftWire> mpu;
SoftWire sw(SDA, SCL);

// you need setting struct
MPU9250Setting setting;

// in setup()
mpu.setup(0x70, setting, sw);

About I2C Errors

Sometimes this library shows the I2C error number if your connection is not correct. It's based on the I2C error number which is reported by the Wire.endTransmission(). It returns following number based on the result of I2C data transmission.

0:success 1:data too long to fit in transmit buffer 2:received NACK on transmit of address 3:received NACK on transmit of data 4:other error

If you have such errors, please check your hardware connection and I2C address setting first. Please refer Wire.endTransmission() reference for these errors, and section 2.3 of this explanation for ACK and NACK.

APIs

bool setup(const uint8_t addr, const MPU9250Setting& setting, WireType& w = Wire);
void verbose(const bool b);
void ahrs(const bool b);
void sleep(bool b);
void calibrateAccelGyro();
void calibrateMag();
bool isConnected();
bool isConnectedMPU9250();
bool isConnectedAK8963();
bool isSleeping();
bool available();
bool update();
void update_accel_gyro();
void update_mag();
void update_rpy(float qw, float qx, float qy, float qz);

float getRoll() const;
float getPitch() const;
float getYaw() const;

float getEulerX() const;
float getEulerY() const;
float getEulerZ() const;

float getQuaternionX() const;
float getQuaternionY() const;
float getQuaternionZ() const;
float getQuaternionW() const;

float getAcc(const uint8_t i) const;
float getGyro(const uint8_t i) const;
float getMag(const uint8_t i) const;
float getLinearAcc(const uint8_t i) const;

float getAccX() const;
float getAccY() const;
float getAccZ() const;
float getGyroX() const;
float getGyroY() const;
float getGyroZ() const;
float getMagX() const;
float getMagY() const;
float getMagZ() const;
float getLinearAccX() const;
float getLinearAccY() const;
float getLinearAccZ() const;

float getAccBias(const uint8_t i) const;
float getGyroBias(const uint8_t i) const;
float getMagBias(const uint8_t i) const;
float getMagScale(const uint8_t i) const;

float getAccBiasX() const;
float getAccBiasY() const;
float getAccBiasZ() const;
float getGyroBiasX() const;
float getGyroBiasY() const;
float getGyroBiasZ() const;
float getMagBiasX() const;
float getMagBiasY() const;
float getMagBiasZ() const;
float getMagScaleX() const;
float getMagScaleY() const;
float getMagScaleZ() const;

float getTemperature() const;

void setAccBias(const float x, const float y, const float z);
void setGyroBias(const float x, const float y, const float z);
void setMagBias(const float x, const float y, const float z);
void setMagScale(const float x, const float y, const float z);
void setMagneticDeclination(const float d);

void selectFilter(QuatFilterSel sel);
void setFilterIterations(const size_t n);

bool selftest();

License

MIT

Acknowledgments / Contributor

About

Arduino library for MPU6500 Six-Axis (Gyro + Accelerometer) aka fake MPU9250

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 90.9%
  • C 9.1%