// I2Cdev library collection - MPU6050 I2C device class
// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00)
// 8/24/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// ... - ongoing debug release
// NOTE: THIS IS ONLY A PARIAL RELEASE. THIS DEVICE CLASS IS CURRENTLY UNDERGOING ACTIVE
// DEVELOPMENT AND IS STILL MISSING SOME IMPORTANT FEATURES. PLEASE KEEP THIS IN MIND IF
// YOU DECIDE TO USE THIS PARTICULAR CODE FOR ANYTHING.
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2012 Jeff Rowberg
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.
===============================================
*/
#include "MPU6050.h"
/** Default constructor, uses default I2C address.
* @see MPU6050_DEFAULT_ADDRESS
*/
MPU6050::MPU6050() {
devAddr = MPU6050_DEFAULT_ADDRESS;
}
/** Specific address constructor.
* @param address I2C address
* @see MPU6050_DEFAULT_ADDRESS
* @see MPU6050_ADDRESS_AD0_LOW
* @see MPU6050_ADDRESS_AD0_HIGH
*/
MPU6050::MPU6050(uint8_t address) {
devAddr = address;
}
/** Power on and prepare for general usage.
* This will activate the device and take it out of sleep mode (which must be done
* after start-up). This function also sets both the accelerometer and the gyroscope
* to their most sensitive settings, namely +/- 2g and +/- 250 degrees/sec, and sets
* the clock source to use the X Gyro for reference, which is slightly better than
* the default internal clock source.
*/
void MPU6050::initialize() {
setClockSource(MPU6050_CLOCK_PLL_XGYRO);
setFullScaleGyroRange(MPU6050_GYRO_FS_250);
setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
setSleepEnabled(false); // thanks to Jack Elston for pointing this one out!
}
/** Verify the I2C connection.
* Make sure the device is connected and responds as expected.
* @return True if connection is valid, false otherwise
*/
bool MPU6050::testConnection() {
return getDeviceID() == 0x34;
}
// AUX_VDDIO register (InvenSense demo code calls this RA_*G_OFFS_TC)
/** Get the auxiliary I2C supply voltage level.
* When set to 1, the auxiliary I2C bus high logic level is VDD. When cleared to
* 0, the auxiliary I2C bus high logic level is VLOGIC. This does not apply to
* the MPU-6000, which does not have a VLOGIC pin.
* @return I2C supply voltage level (0=VLOGIC, 1=VDD)
*/
uint8_t MPU6050::getAuxVDDIOLevel() {
I2Cdev::readBit(devAddr, MPU6050_RA_YG_OFFS_TC, MPU6050_TC_PWR_MODE_BIT, buffer);
return buffer[0];
}
/** Set the auxiliary I2C supply voltage level.
* When set to 1, the auxiliary I2C bus high logic level is VDD. When cleared to
* 0, the auxiliary I2C bus high logic level is VLOGIC. This does not apply to
* the MPU-6000, which does not have a VLOGIC pin.
* @param level I2C supply voltage level (0=VLOGIC, 1=VDD)
*/
void MPU6050::setAuxVDDIOLevel(uint8_t level) {
I2Cdev::writeBit(devAddr, MPU6050_RA_YG_OFFS_TC, MPU6050_TC_PWR_MODE_BIT, level);
}
// SMPLRT_DIV register
/** Get gyroscope output rate divider.
* The sensor register output, FIFO output, DMP sampling, Motion detection, Zero
* Motion detection, and Free Fall detection are all based on the Sample Rate.
* The Sample Rate is generated by dividing the gyroscope output rate by
* SMPLRT_DIV:
*
* Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV)
*
* where Gyroscope Output Rate = 8kHz when the DLPF is disabled (DLPF_CFG = 0 or
* 7), and 1kHz when the DLPF is enabled (see Register 26).
*
* Note: The accelerometer output rate is 1kHz. This means that for a Sample
* Rate greater than 1kHz, the same accelerometer sample may be output to the
* FIFO, DMP, and sensor registers more than once.
*
* For a diagram of the gyroscope and accelerometer signal paths, see Section 8
* of the MPU-6000/MPU-6050 Product Specification document.
*
* @return Current sample rate
* @see MPU6050_RA_SMPLRT_DIV
*/
uint8_t MPU6050::getRate() {
I2Cdev::readByte(devAddr, MPU6050_RA_SMPLRT_DIV, buffer);
return buffer[0];
}
/** Set gyroscope sample rate divider.
* @param rate New sample rate divider
* @see getRate()
* @see MPU6050_RA_SMPLRT_DIV
*/
void MPU6050::setRate(uint8_t rate) {
I2Cdev::writeByte(devAddr, MPU6050_RA_SMPLRT_DIV, rate);
}
// CONFIG register
/** Get external FSYNC configuration.
* Configures the external Frame Synchronization (FSYNC) pin sampling. An
* external signal connected to the FSYNC pin can be sampled by configuring
* EXT_SYNC_SET. Signal changes to the FSYNC pin are latched so that short
* strobes may be captured. The latched FSYNC signal will be sampled at the
* Sampling Rate, as defined in register 25. After sampling, the latch will
* reset to the current FSYNC signal state.
*
* The sampled value will be reported in place of the least significant bit in
* a sensor data register determined by the value of EXT_SYNC_SET according to
* the following table.
*
* <pre>
* EXT_SYNC_SET | FSYNC Bit Location
* -------------+-------------------
* 0 | Input disabled
* 1 | TEMP_OUT_L[0]
* 2 | GYRO_XOUT_L[0]
* 3 | GYRO_YOUT_L[0]
* 4 | GYRO_ZOUT_L[0]
* 5 | ACCEL_XOUT_L[0]
* 6 | ACCEL_YOUT_L[0]
* 7 | ACCEL_ZOUT_L[0]
* </pre>
*
* @return FSYNC configuration value
*/
uint8_t MPU6050::getExternalFrameSync() {
I2Cdev::readBits(devAddr, MPU6050_RA_CONFIG, MPU6050_CFG_EXT_SYNC_SET_BIT, MPU6050_CFG_EXT_SYNC_SET_LENGTH, buffer);
return buffer[0];
}
/** Set external FSYNC configuration.
* @see getExternalFrameSync()
* @see MPU6050_RA_CONFIG
* @param sync New FSYNC configuration value
*/
void MPU6050::setExternalFrameSync(uint8_t sync) {
I2Cdev::writeBits(devAddr, MPU6050_RA_CONFIG, MPU6050_CFG_EXT_SYNC_SET_BIT, MPU6050_CFG_EXT_SYNC_SET_LENGTH, sync);
}
/** Get digital low-pass filter configuration.
* The DLPF_CFG parameter sets the digital low pass filter configuration. It
* also determines the internal sampling rate used by the device as shown in
* the table below.
*
* Note: The accelerometer output rate is 1kHz. This means that for a Sample
* Rate greater than 1kHz, the same accelerometer sample may be output to the
* FIFO, DMP, and sensor registers more than once.
*
* <pre>
* | ACCELEROMETER | GYROSCOPE
* DLPF_CFG | Bandwidth | Delay | Bandwidth | Delay | Sample Rate
* ---------+-----------+--------+-----------+--------+-------------
* 0 | 260Hz | 0ms | 256Hz | 0.98ms | 8kHz
* 1 | 184Hz | 2.0ms | 188Hz | 1.9ms | 1kHz
* 2 | 94Hz | 3.0ms | 98Hz | 2.8ms | 1kHz
* 3 | 44Hz | 4.9ms | 42Hz | 4.8ms | 1kHz
* 4 | 21Hz | 8.5ms | 20Hz | 8.3ms | 1kHz
* 5 | 10Hz | 13.8ms | 10Hz | 13.4ms | 1kHz
* 6 | 5Hz | 19.0ms | 5Hz | 18.6ms | 1kHz