了解 MPU6050 芯片:
MPU-6000(6050)为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时之轴间差的问题,减少了大量的包装空间。MPU-6000(6050)整合了3轴陀螺仪、3轴加速器,并含可藉由第二个I2C端口连接其他厂牌之加速器、磁力传感器、或其他传感器的数位运动处理(DMP: Digital Motion Processor)硬件加速引擎,由主要I2C端口以单一数据流的形式,向应用端输出完整的9轴融合演算技术。 InvenSense 的运动处理资料库,可处理运动感测的复杂数据,降低了运动处理运算对操作系统的负荷,并为应用开发提供架构化的API。 MPU-6000(6050)的角速度全格感测范围为±250、±500、±1000与±2000°/sec (dps),可准确追踪快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g±8g与±16g。产品传输可透过最高至400kHz的 I2C 或最高达20MHz的SPI(MPU-6050没有SPI)。 MPU-6000可在不同电压下工作,VDD供电电压介为2.5V±5%、3.0V±5%或3.3V±5%,逻辑接口VVDIO供电为1.8V± 5%(MPU6000仅用VDD)。MPU-6000的包装尺寸4x4x0.9mm(QFN),在业界是革命性的尺寸。其他的特征包含内建的温度感测器、包含在运作环境中仅有±1%变动的振荡器。
了解 I2C 总线通讯协议:
连接 Arduino:
请注意: Arduino Uno 下 SDA 是 A4,SCL 是 A5 Arduino Mega 2560 下 SDA 是 pin 20,SCL 是 21
准备并安装依赖库文件:
例程:
/* *@Author: TONYLABS *@Date: 2012.12.23 */
//@引入 Wire.h 头文件,下面的 I2Cdev.h 依赖于它
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
mpu MPU6050 mpu(0x68);
bool dmpReady = false;
uint8_t mpuIntStatus;
uint8_t devStatus;
uint16_t packetSize;
uint16_t fifoCount;
uint8_t fifoBuffer[64];
Quaternion q;
VectorFloat gravity;
float ypr[3];
volatile bool mpuInterrupt = false;
dmpDataReady() {
mpuInterrupt = true;
}
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("Initializing I2C devices...");
mpu.initialize();
Serial.println("Testing device connections...");
Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
delay(2);
Serial.println("Initializing DMP...");
devStatus = mpu.dmpInitialize(); //@返回 DMP 状态结果,0为成功,不为0则发生错误
//@如果成功返回 0
if (devStatus == 0) {
Serial.println("Enabling DMP...");
mpu.setDMPEnabled(true);
Serial.println("Enabling interrupt detection (Arduino external interrupt 0)...");
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
Serial.println("DMP ready! Waiting for first interrupt...");
dmpReady = true;
packetSize = mpu.dmpGetFIFOPacketSize();
} else {
Serial.print("DMP Initialization failed (code ");
Serial.print(devStatus);
Serial.println(")");
}
}
void loop() {
float alpha, omiga;
if (!dmpReady) return;
if (!mpuInterrupt && fifoCount < packetSize) return;
mpuIntStatus = mpu.getIntStatus();
fifoCount = mpu.getFIFOCount();
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
mpu.resetFIFO();
Serial.println("FIFO overflow!");
} else if (mpuIntStatus & 0x02) {
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
mpu.getFIFOBytes(fifoBuffer, packetSize);
fifoCount -= packetSize;
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
alpha=-ypr[2] * 180/M_PI;
omiga=mpu.getRotationX()/16.4;
Serial.print("Alpha ");
Serial.print(alpha);
Serial.print("\tOmiga ");
Serial.println(omiga);
}
}