Gyroscope and accelerometer sensor based on Korneliusz Jarzebski's lib
Dependents: weather_station_proj weather_station_project weather_station_proj_v1_2
Revision 0:aef0335c060b, committed 2018-07-01
- Comitter:
- daniel_davvid
- Date:
- Sun Jul 01 11:58:49 2018 +0000
- Commit message:
- Updated so it can work in a weather station project using only the accelerometer
Changed in this revision
MPU6050.cpp | Show annotated file Show diff for this revision Revisions of this file |
MPU6050.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r aef0335c060b MPU6050.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MPU6050.cpp Sun Jul 01 11:58:49 2018 +0000 @@ -0,0 +1,661 @@ +/* +MPU6050.cpp - Class file for the MPU6050 Triple Axis Gyroscope & Accelerometer Arduino Library. +Version: 1.0.3 +(c) 2014-2015 Korneliusz Jarzebski +www.jarzebski.pl +This program is free software: you can redistribute it and/or modify +it under the terms of the version 3 GNU General Public License as +published by the Free Software Foundation. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + + +#include <mbed.h> +#include <math.h> +#include <new> +#include "MPU6050.h" + +MPU6050::MPU6050(PinName sda, PinName scl) : i2c_(*reinterpret_cast<I2C*>(i2cRaw)) +{ + // Placement new to avoid additional heap memory allocation. + new(i2cRaw) I2C(sda, scl); +} + +MPU6050::MPU6050(I2C &i2c) : i2c_(i2c) +{ +} + + +bool MPU6050::begin(mpu6050_dps_t scale, mpu6050_range_t range, int mpua) +{ + // Set Address + mpuAddress = mpua; + // Reset calibrate values + dg.XAxis = 0; + dg.YAxis = 0; + dg.ZAxis = 0; + useCalibrate = false; + + // Reset threshold values + tg.XAxis = 0; + tg.YAxis = 0; + tg.ZAxis = 0; + actualThreshold = 0; + + // Check MPU6050 Who Am I Register + if (fastRegister8(MPU6050_REG_WHO_AM_I) != 0x68) + { + return false; + } + + // Set Clock Source + setClockSource(MPU6050_CLOCK_PLL_XGYRO); + + // Set Scale & Range + setScale(scale); + setRange(range); + //LOW PASS FILTER SETUP + setDLPFMode(MPU6050_DLPF_6); + // Disable Sleep Mode + setSleepEnabled(false); + + + return true; +} + +void MPU6050::setScale(mpu6050_dps_t scale) +{ + uint8_t value; + + switch (scale) + { + case MPU6050_SCALE_250DPS: + dpsPerDigit = .007633f; + break; + case MPU6050_SCALE_500DPS: + dpsPerDigit = .015267f; + break; + case MPU6050_SCALE_1000DPS: + dpsPerDigit = .030487f; + break; + case MPU6050_SCALE_2000DPS: + dpsPerDigit = .060975f; + break; + default: + break; + } + + value = readRegister8(MPU6050_REG_GYRO_CONFIG); + value &= 0b11100111; + value |= (scale << 3); + writeRegister8(MPU6050_REG_GYRO_CONFIG, value); +} + +mpu6050_dps_t MPU6050::getScale(void) +{ + uint8_t value; + value = readRegister8(MPU6050_REG_GYRO_CONFIG); + value &= 0b00011000; + value >>= 3; + return (mpu6050_dps_t)value; +} + +void MPU6050::setRange(mpu6050_range_t range) +{ + uint8_t value; + + switch (range) + { + case MPU6050_RANGE_2G: + rangePerDigit = .000061f; + break; + case MPU6050_RANGE_4G: + rangePerDigit = .000122f; + break; + case MPU6050_RANGE_8G: + rangePerDigit = .000244f; + break; + case MPU6050_RANGE_16G: + rangePerDigit = .0004882f; + break; + default: + break; + } + + value = readRegister8(MPU6050_REG_ACCEL_CONFIG); + value &= 0b11100111; + value |= (range << 3); + writeRegister8(MPU6050_REG_ACCEL_CONFIG, value); +} + +mpu6050_range_t MPU6050::getRange(void) +{ + uint8_t value; + value = readRegister8(MPU6050_REG_ACCEL_CONFIG); + value &= 0b00011000; + value >>= 3; + return (mpu6050_range_t)value; +} + +void MPU6050::setDHPFMode(mpu6050_dhpf_t dhpf) +{ + uint8_t value; + value = readRegister8(MPU6050_REG_ACCEL_CONFIG); + value &= 0b11111000; + value |= dhpf; + writeRegister8(MPU6050_REG_ACCEL_CONFIG, value); +} + +void MPU6050::setDLPFMode(mpu6050_dlpf_t dlpf) +{ + uint8_t value; + value = readRegister8(MPU6050_REG_CONFIG); + value &= 0b11111000; + value |= dlpf; + writeRegister8(MPU6050_REG_CONFIG, value); +} + +void MPU6050::setClockSource(mpu6050_clockSource_t source) +{ + uint8_t value; + value = readRegister8(MPU6050_REG_PWR_MGMT_1); + value &= 0b11111000; + value |= source; + writeRegister8(MPU6050_REG_PWR_MGMT_1, value); +} + +mpu6050_clockSource_t MPU6050::getClockSource(void) +{ + uint8_t value; + value = readRegister8(MPU6050_REG_PWR_MGMT_1); + value &= 0b00000111; + return (mpu6050_clockSource_t)value; +} + +bool MPU6050::getSleepEnabled(void) +{ + return readRegisterBit(MPU6050_REG_PWR_MGMT_1, 6); +} + +void MPU6050::setSleepEnabled(bool state) +{ + writeRegisterBit(MPU6050_REG_PWR_MGMT_1, 6, state); +} + +bool MPU6050::getIntZeroMotionEnabled(void) +{ + return readRegisterBit(MPU6050_REG_INT_ENABLE, 5); +} + +void MPU6050::setIntZeroMotionEnabled(bool state) +{ + writeRegisterBit(MPU6050_REG_INT_ENABLE, 5, state); +} + +bool MPU6050::getIntMotionEnabled(void) +{ + return readRegisterBit(MPU6050_REG_INT_ENABLE, 6); +} + +void MPU6050::setIntMotionEnabled(bool state) +{ + writeRegisterBit(MPU6050_REG_INT_ENABLE, 6, state); +} + +bool MPU6050::getIntFreeFallEnabled(void) +{ + return readRegisterBit(MPU6050_REG_INT_ENABLE, 7); +} + +void MPU6050::setIntFreeFallEnabled(bool state) +{ + writeRegisterBit(MPU6050_REG_INT_ENABLE, 7, state); +} + +uint8_t MPU6050::getMotionDetectionThreshold(void) +{ + return readRegister8(MPU6050_REG_MOT_THRESHOLD); +} + +void MPU6050::setMotionDetectionThreshold(uint8_t threshold) +{ + writeRegister8(MPU6050_REG_MOT_THRESHOLD, threshold); +} + +uint8_t MPU6050::getMotionDetectionDuration(void) +{ + return readRegister8(MPU6050_REG_MOT_DURATION); +} + +void MPU6050::setMotionDetectionDuration(uint8_t duration) +{ + writeRegister8(MPU6050_REG_MOT_DURATION, duration); +} + +uint8_t MPU6050::getZeroMotionDetectionThreshold(void) +{ + return readRegister8(MPU6050_REG_ZMOT_THRESHOLD); +} + +void MPU6050::setZeroMotionDetectionThreshold(uint8_t threshold) +{ + writeRegister8(MPU6050_REG_ZMOT_THRESHOLD, threshold); +} + +uint8_t MPU6050::getZeroMotionDetectionDuration(void) +{ + return readRegister8(MPU6050_REG_ZMOT_DURATION); +} + +void MPU6050::setZeroMotionDetectionDuration(uint8_t duration) +{ + writeRegister8(MPU6050_REG_ZMOT_DURATION, duration); +} + +uint8_t MPU6050::getFreeFallDetectionThreshold(void) +{ + return readRegister8(MPU6050_REG_FF_THRESHOLD); +} + +void MPU6050::setFreeFallDetectionThreshold(uint8_t threshold) +{ + writeRegister8(MPU6050_REG_FF_THRESHOLD, threshold); +} + +uint8_t MPU6050::getFreeFallDetectionDuration(void) +{ + return readRegister8(MPU6050_REG_FF_DURATION); +} + +void MPU6050::setFreeFallDetectionDuration(uint8_t duration) +{ + writeRegister8(MPU6050_REG_FF_DURATION, duration); +} + +bool MPU6050::getI2CMasterModeEnabled(void) +{ + return readRegisterBit(MPU6050_REG_USER_CTRL, 5); +} + +void MPU6050::setI2CMasterModeEnabled(bool state) +{ + writeRegisterBit(MPU6050_REG_USER_CTRL, 5, state); +} + +void MPU6050::setI2CBypassEnabled(bool state) +{ + return writeRegisterBit(MPU6050_REG_INT_PIN_CFG, 1, state); +} + +bool MPU6050::getI2CBypassEnabled(void) +{ + return readRegisterBit(MPU6050_REG_INT_PIN_CFG, 1); +} + +void MPU6050::setAccelPowerOnDelay(mpu6050_onDelay_t delay) +{ + uint8_t value; + value = readRegister8(MPU6050_REG_MOT_DETECT_CTRL); + value &= 0b11001111; + value |= (delay << 4); + writeRegister8(MPU6050_REG_MOT_DETECT_CTRL, value); +} + +mpu6050_onDelay_t MPU6050::getAccelPowerOnDelay(void) +{ + uint8_t value; + value = readRegister8(MPU6050_REG_MOT_DETECT_CTRL); + value &= 0b00110000; + return (mpu6050_onDelay_t)(value >> 4); +} + +uint8_t MPU6050::getIntStatus(void) +{ + return readRegister8(MPU6050_REG_INT_STATUS); +} + +Activites MPU6050::readActivites(void) +{ + uint8_t data = readRegister8(MPU6050_REG_INT_STATUS); + + a.isOverflow = ((data >> 4) & 1); + a.isFreeFall = ((data >> 7) & 1); + a.isInactivity = ((data >> 5) & 1); + a.isActivity = ((data >> 6) & 1); + a.isDataReady = ((data >> 0) & 1); + + data = readRegister8(MPU6050_REG_MOT_DETECT_STATUS); + + a.isNegActivityOnX = ((data >> 7) & 1); + a.isPosActivityOnX = ((data >> 6) & 1); + + a.isNegActivityOnY = ((data >> 5) & 1); + a.isPosActivityOnY = ((data >> 4) & 1); + + a.isNegActivityOnZ = ((data >> 3) & 1); + a.isPosActivityOnZ = ((data >> 2) & 1); + + return a; +} + +Vector MPU6050::readRawAccel(void) +{ + char data = MPU6050_REG_ACCEL_XOUT_H; + i2c_.write(mpuAddress,&data, 1, true); + + + uint8_t value[6]; + i2c_.read(mpuAddress, (char *)&value, 6); + + uint8_t xha = value[0]; + uint8_t xla = value[1]; + uint8_t yha = value[2]; + uint8_t yla = value[3]; + uint8_t zha = value[4]; + uint8_t zla = value[5]; + + + ra.XAxis = xha << 8 | xla; + ra.YAxis = yha << 8 | yla; + ra.ZAxis = zha << 8 | zla; + + return ra; +} + +Vector MPU6050::readNormalizeAccel(void) +{ + readRawAccel(); + + na.XAxis = ra.XAxis * rangePerDigit * 9.80665f; + na.YAxis = ra.YAxis * rangePerDigit * 9.80665f; + na.ZAxis = ra.ZAxis * rangePerDigit * 9.80665f; + + return na; +} + +Vector MPU6050::readScaledAccel(void) +{ + readRawAccel(); + + na.XAxis = ra.XAxis * rangePerDigit; + na.YAxis = ra.YAxis * rangePerDigit; + na.ZAxis = ra.ZAxis * rangePerDigit; + + return na; +} + + +Vector MPU6050::readRawGyro(void) +{ + char data = MPU6050_REG_GYRO_XOUT_H; + i2c_.write(mpuAddress,&data, 1, true); + + uint8_t value[6]; + + i2c_.read(mpuAddress, (char *)&value, 6); + + uint8_t xha = value[0]; + uint8_t xla = value[1]; + uint8_t yha = value[2]; + uint8_t yla = value[3]; + uint8_t zha = value[4]; + uint8_t zla = value[5]; + + + rg.XAxis = xha << 8 | xla; + rg.YAxis = yha << 8 | yla; + rg.ZAxis = zha << 8 | zla; + + return rg; +} + +Vector MPU6050::readNormalizeGyro(void) +{ + readRawGyro(); + + if (useCalibrate) + { + ng.XAxis = (rg.XAxis - dg.XAxis) * dpsPerDigit; + ng.YAxis = (rg.YAxis - dg.YAxis) * dpsPerDigit; + ng.ZAxis = (rg.ZAxis - dg.ZAxis) * dpsPerDigit; + } else + { + ng.XAxis = rg.XAxis * dpsPerDigit; + ng.YAxis = rg.YAxis * dpsPerDigit; + ng.ZAxis = rg.ZAxis * dpsPerDigit; + } + + if (actualThreshold) + { + if (abs(ng.XAxis) < tg.XAxis) ng.XAxis = 0; + if (abs(ng.YAxis) < tg.YAxis) ng.YAxis = 0; + if (abs(ng.ZAxis) < tg.ZAxis) ng.ZAxis = 0; + } + + return ng; +} + +float MPU6050::readTemperature(void) +{ + int16_t T; + T = readRegister16(MPU6050_REG_TEMP_OUT_H); + return (float)T/340 + 36.53f; +} + +int16_t MPU6050::getGyroOffsetX(void) +{ + return readRegister16(MPU6050_REG_GYRO_XOFFS_H); +} + +int16_t MPU6050::getGyroOffsetY(void) +{ + return readRegister16(MPU6050_REG_GYRO_YOFFS_H); +} + +int16_t MPU6050::getGyroOffsetZ(void) +{ + return readRegister16(MPU6050_REG_GYRO_ZOFFS_H); +} + +void MPU6050::setGyroOffsetX(int16_t offset) +{ + writeRegister16(MPU6050_REG_GYRO_XOFFS_H, offset); +} + +void MPU6050::setGyroOffsetY(int16_t offset) +{ + writeRegister16(MPU6050_REG_GYRO_YOFFS_H, offset); +} + +void MPU6050::setGyroOffsetZ(int16_t offset) +{ + writeRegister16(MPU6050_REG_GYRO_ZOFFS_H, offset); +} + +int16_t MPU6050::getAccelOffsetX(void) +{ + return readRegister16(MPU6050_REG_ACCEL_XOFFS_H); +} + +int16_t MPU6050::getAccelOffsetY(void) +{ + return readRegister16(MPU6050_REG_ACCEL_YOFFS_H); +} + +int16_t MPU6050::getAccelOffsetZ(void) +{ + return readRegister16(MPU6050_REG_ACCEL_ZOFFS_H); +} + +void MPU6050::setAccelOffsetX(int16_t offset) +{ + writeRegister16(MPU6050_REG_ACCEL_XOFFS_H, offset); +} + +void MPU6050::setAccelOffsetY(int16_t offset) +{ + writeRegister16(MPU6050_REG_ACCEL_YOFFS_H, offset); +} + +void MPU6050::setAccelOffsetZ(int16_t offset) +{ + writeRegister16(MPU6050_REG_ACCEL_ZOFFS_H, offset); +} + +// Calibrate algorithm +void MPU6050::calibrateGyro(uint8_t samples) +{ + // Set calibrate + useCalibrate = true; + + // Reset values + float sumX = 0; + float sumY = 0; + float sumZ = 0; + float sigmaX = 0; + float sigmaY = 0; + float sigmaZ = 0; + + // Read n-samples + for (uint8_t i = 0; i < samples; ++i) + { + readRawGyro(); + sumX += rg.XAxis; + sumY += rg.YAxis; + sumZ += rg.ZAxis; + + sigmaX += rg.XAxis * rg.XAxis; + sigmaY += rg.YAxis * rg.YAxis; + sigmaZ += rg.ZAxis * rg.ZAxis; + + wait(0.005f); + } + + // Calculate delta vectors + dg.XAxis = sumX / samples; + dg.YAxis = sumY / samples; + dg.ZAxis = sumZ / samples; + + // Calculate threshold vectors + th.XAxis = sqrt((sigmaX / 50) - (dg.XAxis * dg.XAxis)); + th.YAxis = sqrt((sigmaY / 50) - (dg.YAxis * dg.YAxis)); + th.ZAxis = sqrt((sigmaZ / 50) - (dg.ZAxis * dg.ZAxis)); + + // If already set threshold, recalculate threshold vectors + if (actualThreshold > 0) + { + setThreshold(actualThreshold); + } +} + +// Get current threshold value +uint8_t MPU6050::getThreshold(void) +{ + return actualThreshold; +} + +// Set treshold value +void MPU6050::setThreshold(uint8_t multiple) +{ + if (multiple > 0) + { + // If not calibrated, need calibrate + if (!useCalibrate) + { + calibrateGyro(); + } + + // Calculate threshold vectors + tg.XAxis = th.XAxis * multiple; + tg.YAxis = th.YAxis * multiple; + tg.ZAxis = th.ZAxis * multiple; + } else + { + // No threshold + tg.XAxis = 0; + tg.YAxis = 0; + tg.ZAxis = 0; + } + + // Remember old threshold value + actualThreshold = multiple; +} + +// Fast read 8-bit from register +uint8_t MPU6050::fastRegister8(uint8_t reg, bool repeated) +{ + uint8_t value; + i2c_.write(mpuAddress,(char *)®, 1, true); + i2c_.read(mpuAddress,(char *)&value, 1, repeated); + + return value; +} + +// Read 8-bit from register +uint8_t MPU6050::readRegister8(uint8_t reg, bool repeated) +{ + uint8_t value; + i2c_.write(mpuAddress,(char *)®, 1, true); + i2c_.read(mpuAddress,(char *)&value, 1, repeated); + + return value; +} + +// Write 8-bit to register +void MPU6050::writeRegister8(uint8_t reg, uint8_t value, bool repeated) +{ + uint8_t cmd[2]; + cmd[0] = reg; + cmd[1] = value; + i2c_.write(mpuAddress,(char *)&cmd, 2, repeated); +} + +int16_t MPU6050::readRegister16(uint8_t reg, bool repeated) +{ + int16_t value; + i2c_.write(mpuAddress, (char *)®, 1, true); + uint8_t readings[2]; + i2c_.read(mpuAddress, (char *)&readings, 2, repeated); + uint8_t vha = readings[0]; + uint8_t vla = readings[1]; + + value = vha << 8 | vla; + + return value; +} + +void MPU6050::writeRegister16(uint8_t reg, int16_t value, bool repeated) +{ + i2c_.write(mpuAddress, (char *)®, 1, true); + i2c_.write(mpuAddress, (char *)&value, 2, repeated); +} + +// Read register bit +bool MPU6050::readRegisterBit(uint8_t reg, uint8_t pos) +{ + uint8_t value; + value = readRegister8(reg); + return ((value >> pos) & 1); +} + +// Write register bit +void MPU6050::writeRegisterBit(uint8_t reg, uint8_t pos, bool state) +{ + uint8_t value; + value = readRegister8(reg); + + if (state) + { + value |= (1 << pos); + } else + { + value &= ~(1 << pos); + } + + writeRegister8(reg, value); +} \ No newline at end of file
diff -r 000000000000 -r aef0335c060b MPU6050.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MPU6050.h Sun Jul 01 11:58:49 2018 +0000 @@ -0,0 +1,262 @@ +/* +MPU6050.h - Header file for the MPU6050 Triple Axis Gyroscope & Accelerometer Arduino Library. +Version: 1.0.3 +(c) 2014-2015 Korneliusz Jarzebski +www.jarzebski.pl +This program is free software: you can redistribute it and/or modify +it under the terms of the version 3 GNU General Public License as +published by the Free Software Foundation. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef MPU6050_h +#define MPU6050_h + +#include <mbed.h> + +// Using the GY-521 breakout board, I set ADO to 0 by grounding through a 4k7 resistor +// Seven-bit device address is 110100 for ADO = 0 and 110101 for ADO = 1 +#define ADO 0 +#if ADO +#define MPU6050_ADDRESS 0x69<<1 // Device address when ADO = 1 +#else +#define MPU6050_ADDRESS 0x68<<1 // Device address when ADO = 0 +#endif + +#define MPU6050_REG_ACCEL_XOFFS_H (0x06) +#define MPU6050_REG_ACCEL_XOFFS_L (0x07) +#define MPU6050_REG_ACCEL_YOFFS_H (0x08) +#define MPU6050_REG_ACCEL_YOFFS_L (0x09) +#define MPU6050_REG_ACCEL_ZOFFS_H (0x0A) +#define MPU6050_REG_ACCEL_ZOFFS_L (0x0B) +#define MPU6050_REG_GYRO_XOFFS_H (0x13) +#define MPU6050_REG_GYRO_XOFFS_L (0x14) +#define MPU6050_REG_GYRO_YOFFS_H (0x15) +#define MPU6050_REG_GYRO_YOFFS_L (0x16) +#define MPU6050_REG_GYRO_ZOFFS_H (0x17) +#define MPU6050_REG_GYRO_ZOFFS_L (0x18) +#define MPU6050_REG_CONFIG (0x1A) +#define MPU6050_REG_GYRO_CONFIG (0x1B) // Gyroscope Configuration +#define MPU6050_REG_ACCEL_CONFIG (0x1C) // Accelerometer Configuration +#define MPU6050_REG_FF_THRESHOLD (0x1D) +#define MPU6050_REG_FF_DURATION (0x1E) +#define MPU6050_REG_MOT_THRESHOLD (0x1F) +#define MPU6050_REG_MOT_DURATION (0x20) +#define MPU6050_REG_ZMOT_THRESHOLD (0x21) +#define MPU6050_REG_ZMOT_DURATION (0x22) +#define MPU6050_REG_INT_PIN_CFG (0x37) // INT Pin. Bypass Enable Configuration +#define MPU6050_REG_INT_ENABLE (0x38) // INT Enable +#define MPU6050_REG_INT_STATUS (0x3A) +#define MPU6050_REG_ACCEL_XOUT_H (0x3B) +#define MPU6050_REG_ACCEL_XOUT_L (0x3C) +#define MPU6050_REG_ACCEL_YOUT_H (0x3D) +#define MPU6050_REG_ACCEL_YOUT_L (0x3E) +#define MPU6050_REG_ACCEL_ZOUT_H (0x3F) +#define MPU6050_REG_ACCEL_ZOUT_L (0x40) +#define MPU6050_REG_TEMP_OUT_H (0x41) +#define MPU6050_REG_TEMP_OUT_L (0x42) +#define MPU6050_REG_GYRO_XOUT_H (0x43) +#define MPU6050_REG_GYRO_XOUT_L (0x44) +#define MPU6050_REG_GYRO_YOUT_H (0x45) +#define MPU6050_REG_GYRO_YOUT_L (0x46) +#define MPU6050_REG_GYRO_ZOUT_H (0x47) +#define MPU6050_REG_GYRO_ZOUT_L (0x48) +#define MPU6050_REG_MOT_DETECT_STATUS (0x61) +#define MPU6050_REG_MOT_DETECT_CTRL (0x69) +#define MPU6050_REG_USER_CTRL (0x6A) // User Control +#define MPU6050_REG_PWR_MGMT_1 (0x6B) // Power Management 1 +#define MPU6050_REG_WHO_AM_I (0x75) // Who Am I + +#ifndef VECTOR_STRUCT_H +#define VECTOR_STRUCT_H +struct Vector +{ + float XAxis; + float YAxis; + float ZAxis; +}; +#endif + +struct Activites +{ + bool isOverflow; + bool isFreeFall; + bool isInactivity; + bool isActivity; + bool isPosActivityOnX; + bool isPosActivityOnY; + bool isPosActivityOnZ; + bool isNegActivityOnX; + bool isNegActivityOnY; + bool isNegActivityOnZ; + bool isDataReady; +}; + +typedef enum +{ + MPU6050_CLOCK_KEEP_RESET = 0b111, + MPU6050_CLOCK_EXTERNAL_19MHZ = 0b101, + MPU6050_CLOCK_EXTERNAL_32KHZ = 0b100, + MPU6050_CLOCK_PLL_ZGYRO = 0b011, + MPU6050_CLOCK_PLL_YGYRO = 0b010, + MPU6050_CLOCK_PLL_XGYRO = 0b001, + MPU6050_CLOCK_INTERNAL_8MHZ = 0b000 +} mpu6050_clockSource_t; + +typedef enum +{ + MPU6050_SCALE_2000DPS = 0b11, + MPU6050_SCALE_1000DPS = 0b10, + MPU6050_SCALE_500DPS = 0b01, + MPU6050_SCALE_250DPS = 0b00 +} mpu6050_dps_t; + +typedef enum +{ + MPU6050_RANGE_16G = 0b11, + MPU6050_RANGE_8G = 0b10, + MPU6050_RANGE_4G = 0b01, + MPU6050_RANGE_2G = 0b00, +} mpu6050_range_t; + +typedef enum +{ + MPU6050_DELAY_3MS = 0b11, + MPU6050_DELAY_2MS = 0b10, + MPU6050_DELAY_1MS = 0b01, + MPU6050_NO_DELAY = 0b00, +} mpu6050_onDelay_t; + +typedef enum +{ + MPU6050_DHPF_HOLD = 0b111, + MPU6050_DHPF_0_63HZ = 0b100, + MPU6050_DHPF_1_25HZ = 0b011, + MPU6050_DHPF_2_5HZ = 0b010, + MPU6050_DHPF_5HZ = 0b001, + MPU6050_DHPF_RESET = 0b000, +} mpu6050_dhpf_t; + +typedef enum +{ + MPU6050_DLPF_6 = 0b110, + MPU6050_DLPF_5 = 0b101, + MPU6050_DLPF_4 = 0b100, + MPU6050_DLPF_3 = 0b011, + MPU6050_DLPF_2 = 0b010, + MPU6050_DLPF_1 = 0b001, + MPU6050_DLPF_0 = 0b000, +} mpu6050_dlpf_t; + +class MPU6050 +{ + public: + MPU6050(PinName sda, PinName scl); + MPU6050(I2C &i2c); + + bool begin(mpu6050_dps_t scale = MPU6050_SCALE_2000DPS, mpu6050_range_t range = MPU6050_RANGE_2G, int mpua = MPU6050_ADDRESS); + + void setClockSource(mpu6050_clockSource_t source); + void setScale(mpu6050_dps_t scale); + void setRange(mpu6050_range_t range); + mpu6050_clockSource_t getClockSource(void); + mpu6050_dps_t getScale(void); + mpu6050_range_t getRange(void); + void setDHPFMode(mpu6050_dhpf_t dhpf); + void setDLPFMode(mpu6050_dlpf_t dlpf); + mpu6050_onDelay_t getAccelPowerOnDelay(); + void setAccelPowerOnDelay(mpu6050_onDelay_t delay); + + uint8_t getIntStatus(void); + + bool getIntZeroMotionEnabled(void); + void setIntZeroMotionEnabled(bool state); + bool getIntMotionEnabled(void); + void setIntMotionEnabled(bool state); + bool getIntFreeFallEnabled(void); + void setIntFreeFallEnabled(bool state); + + uint8_t getMotionDetectionThreshold(void); + void setMotionDetectionThreshold(uint8_t threshold); + uint8_t getMotionDetectionDuration(void); + void setMotionDetectionDuration(uint8_t duration); + + uint8_t getZeroMotionDetectionThreshold(void); + void setZeroMotionDetectionThreshold(uint8_t threshold); + uint8_t getZeroMotionDetectionDuration(void); + void setZeroMotionDetectionDuration(uint8_t duration); + + uint8_t getFreeFallDetectionThreshold(void); + void setFreeFallDetectionThreshold(uint8_t threshold); + uint8_t getFreeFallDetectionDuration(void); + void setFreeFallDetectionDuration(uint8_t duration); + + bool getSleepEnabled(void); + void setSleepEnabled(bool state); + bool getI2CMasterModeEnabled(void); + void setI2CMasterModeEnabled(bool state); + bool getI2CBypassEnabled(void); + void setI2CBypassEnabled(bool state); + + float readTemperature(void); + Activites readActivites(void); + + int16_t getGyroOffsetX(void); + void setGyroOffsetX(int16_t offset); + int16_t getGyroOffsetY(void); + void setGyroOffsetY(int16_t offset); + int16_t getGyroOffsetZ(void); + void setGyroOffsetZ(int16_t offset); + + int16_t getAccelOffsetX(void); + void setAccelOffsetX(int16_t offset); + int16_t getAccelOffsetY(void); + void setAccelOffsetY(int16_t offset); + int16_t getAccelOffsetZ(void); + void setAccelOffsetZ(int16_t offset); + + void calibrateGyro(uint8_t samples = 50); + void setThreshold(uint8_t multiple = 1); + uint8_t getThreshold(void); + + Vector readRawGyro(void); + Vector readNormalizeGyro(void); + + Vector readRawAccel(void); + Vector readNormalizeAccel(void); + Vector readScaledAccel(void); + + private: + + I2C &i2c_; + char i2cRaw[sizeof(I2C)]; + + Vector ra, rg; // Raw vectors + Vector na, ng; // Normalized vectors + Vector tg, dg; // Threshold and Delta for Gyro + Vector th; // Threshold + Activites a; // Activities + + float dpsPerDigit, rangePerDigit; + float actualThreshold; + bool useCalibrate; + int mpuAddress; + + uint8_t fastRegister8(uint8_t reg, bool repeated=false); + uint8_t readRegister8(uint8_t reg, bool repeated=false); + void writeRegister8(uint8_t reg, uint8_t value, bool repeated=false); + + int16_t readRegister16(uint8_t reg, bool repeated=false); + void writeRegister16(uint8_t reg, int16_t value, bool repeated=false); + + bool readRegisterBit(uint8_t reg, uint8_t pos); + void writeRegisterBit(uint8_t reg, uint8_t pos, bool state); + +}; + +#endif \ No newline at end of file