基于arduino的MPU6050的使用

摘要


MPU6050是InvenSense公司推出的全球首款整合性6轴运动处理组件,内部整合了3轴陀螺仪和3轴加速度传感器。在制作自平衡小车和四轴六轴时需要用来做姿态的监控。


本文核心记录使用arduino uno开发板获取


MPU6050三轴数据的基本操作


硬件接线


MPU6050模块使用的数据接口协议是I2C总线协议,在arduino中使用Wire类库来实现MPU6050的访问。


接线方式:

    //VCC--5V

    //GND--GND

    //SCL--A5

    //SDA--A4

    //AD0-- (AD0引脚为地址选择引脚,悬空或者接GND,硬件地址为0x68,接VCC/高电平硬件地址为0x69)

    //INT-- (中断引脚,如果用到可以接中端口,此处不接)

需要使用到的Wire库方法

1.wire.begin();/wire.begin(address);不带参数为以主机模式进入总线模式,带参数为以从机模式进入总线。

2.Wire.beginTransmission(address);开启对应器件的传输。

3. Wire.write(address); //指定操作寄存器的地址。

4.Wire.write(0); //写入一个字节的数据0。

5.Wire.requestFrom(address, n, true);//向器件请求2个字节的数据,特别说明,此处地址为器件地址。请求返回的数据存储到缓冲区buffer中

6.Wire.endTransmission(true); //结束传输,释放总线

7.Wire.available();//返回总线缓冲区有效数据字节数;

8.Wire.read();//从缓冲区buffer中读取数据,一次读取一个字节


示例1.从MPU6050中读数据

Wire.beginTransmission(0x68); //开启MPU6050的传输

Wire.write(0x3F); //指定需要读取数据的寄存器地址

Wire.requestFrom(0x68, 2, true); //向器件发出2个字节数据的请求

Wire.endTransmission(true); //结束传输,释放总线

while ((Wire.available() < 2));//等待2字节数据存入缓冲区。

int val = Wire.read() << 8 | Wire.read();

示例2.向MPU6050中写数据

Wire.beginTransmission(0x68); //开启MPU6050的传输

Wire.write(0x6B); //指定寄存器地址

Wire.write(0); //写入一个字节的数据

Wire.endTransmission(true); //结束传输释放总线


MPU6050模块的访问


1.    启动器件:在对MPU6050进行各项操作前,需要先启动该器件,具体操作就是向它的0x6B写入一个字节的数据0。


//向0x6B写入一个字节的数据0,启动器件

void MPU_START(void)

{

Wire.beginTransmission(0x68); //开启MPU6050的传输

Wire.write(0x6B); //指定寄存器地址

Wire.write(0); //写入一个字节的数据0

Wire.endTransmission(true); //结束传输释放总线

}


2.      配置MPU6050的倍率:默认加速度倍率±2g,默认角速度±250度/s。寄存器0x1B和0x1C两个寄存器的bit4+bit3分别用来配置角速度倍率和加速度倍率,用f表示倍率。


//角速度倍率更新配置

void GYRO_COFIG(unsigned int f)

{

Wire.beginTransmission(0x68); //开启MPU-6050的传输

Wire.write(0x1B); //角速度倍率寄存器的地址

Wire.requestFrom(0x68, 1, true); //请求读出原配置

unsigned char acc_conf = Wire.read();//原配置读出

acc_conf = ((acc_conf & 0xE7) | (f << 3));//倍率配置更新

Wire.write(acc_conf);更新倍率写入

Wire.endTransmission(true); //结束传输,释放总线


//加速度倍率更新配置

void ACCEL_COFIG(unsigned int f)

{

Wire.beginTransmission(0x68); //开启MPU-6050的传输

Wire.write(0x1C); //加速度倍率寄存器的地址

Wire.requestFrom(0x68, 1, true); //请求读出原配置

unsigned char acc_conf = Wire.read();//原配置读出

acc_conf = ((acc_conf & 0xE7) | (f << 3));//倍率配置更新

Wire.write(acc_conf);更新倍率写入

Wire.endTransmission(true); //结束传输,释放总线

3.      数据获取和换算:加速度角速度和温度数据均为16位数据,寄存器地址如下:

0x3B,加速度计的X轴分量ACCEL_X

0x3D,加速度计的Y轴分量ACCEL_Y

0x3F,加速度计的Z轴分量ACCEL_Z

0x41,当前温度TEMP

0x43,绕X轴旋转的角速度GYRO_X

0x45,绕Y轴旋转的角速度GYRO_Y

0x47,绕Z轴旋转的角速度GYRO_Z

从寄存器读取到的数据为2个字节的对应的数据分量,需要将获取的数据分量换算成相应的加速度和角速度。


换算方法:实际数值=对应数据分量/32768*倍率


假设,角速度和加速度倍率配置均默认为0,则角速度倍率±250度/s,加速度倍率为±2g。

则X轴角速度和加速度分别为gyr_x=GYRO_X/32768*250

acc_x=ACCEL_X/32768*2g;

g为当地重力加速度,取9.8m/s^2;

其中:MPU6050寄存器详细说明可以查询产品的数据手册。

完整实例代码:


// Visual Micro is in vMicro>General>Tutorial Mode

//

/*


    Name:      MPU6050_TestDemo.ino

    Created:2020/3/18 星期三 20:17:09

    Author:    SilenceJerui

*/

/*

    接线方式:

    //MPU6050--UNO

    //VCC--5V

    //GND--GND

    //SCL--A5

    //SDA--A4

    //AD0-- (AD0引脚为地址选择引脚,悬空或者接GND,硬件地址为0x68,接VCC/高电平硬件地址为0x69)

    //INT-- (中断引脚,如果用到可以接中端口,此处不接)

*/


#include

// Define User Types below here or use a .h file

//

#define ACCEL_CONFIG 1

#define GYRO_CONFIG 1

#define G 9.8

float val_seven[7];

// Define Function Prototypes that use User Types below here or use a .h file

//

// Define Functions below here or use other .ino or cpp files

//向0x6B写入一个字节的数据0,启动器件

void MPU_START(void)

{

    Wire.beginTransmission(0x68); //开启MPU6050的传输

    Wire.write(0x6B); //指定寄存器地址

    Wire.write(0); //写入一个字节的数据

    Wire.endTransmission(true); //结束传输,true表示释放总线

}

//配置角速度倍率

void GYRO_CONFIG_SET(int f)

{

    Wire.beginTransmission(0x68); //开启MPU-6050的传输

    Wire.write(0x1B); //角速度倍率寄存器的地址

    Wire.requestFrom(0x68, 1, true); //先读出原配置

    unsigned char acc_conf = Wire.read();

    acc_conf = ((acc_conf & 0xE7) | (f << 3));

    Wire.write(acc_conf);

    Wire.endTransmission(true); //结束传输,true表示释放总线

}

//配置加速度倍率

void ACCEL_CONFIG_SET(int f)

{

    Wire.beginTransmission(0x68); //开启MPU-6050的传输

    Wire.write(0x1C); //加速度倍率寄存器的地址

    Wire.requestFrom(0x68, 1, true); //先读出原配置

    unsigned char acc_conf = Wire.read();

    acc_conf = ((acc_conf & 0xE7) | (f << 3));

    Wire.write(acc_conf);

    Wire.endTransmission(true); //结束传输,true表示释放总线

}


//获取MPU数据

void Get_Value(void)

{

    //获取各个轴分量数据

    Wire.beginTransmission(0x68); //开启MPU-6050的传输

    Wire.write(0x3B);

    Wire.requestFrom(0x68, 7 * 2, true);

    Wire.endTransmission(true);

    for (long i = 0; i < 7; ++i)

    {

        val_seven[i] = Wire.read() << 8 | Wire.read();

    }

    //数据换算

    val_seven[0] = (float)(val_seven[0] / 32768 * (2 ^ ACCEL_CONFIG) * G);//acc_x

    val_seven[1] = (float)(val_seven[1] / 32768 * (2 ^ ACCEL_CONFIG) * G);//acc_y

    val_seven[2] = (float)(val_seven[2] / 32768 * (2 ^ ACCEL_CONFIG) * G);//acc_z

    val_seven[4] = (float)(val_seven[4] / 32768 * (2 ^ GYRO_CONFIG) * 250);//gyr_x

    val_seven[5] = (float)(val_seven[5] / 32768 * (2 ^ GYRO_CONFIG) * 250);//gyr_y

    val_seven[6] = (float)(val_seven[6] / 32768 * (2 ^ GYRO_CONFIG) * 250);//gyr_z

}


// The setup() function runs once each time the micro-controller starts

void setup()

{

    Serial.begin(9600);

    Wire.begin();//以主机模式开启总线

    MPU_START();//启动MPU6050

    GYRO_CONFIG_SET(0);//配置器件角速度倍率

    ACCEL_CONFIG_SET(0);//配置器件加速度倍率

}

// Add the main program code into the continuous loop() function

void loop()

{

    Get_Value();

    Serial.print("acc_x:");

    Serial.print('\t');

    Serial.println(val_seven[0]);

    Serial.print("acc_y:");

    Serial.print('\t');

    Serial.println(val_seven[1]);

    Serial.print("acc_z:");

    Serial.print('\t');

    Serial.println(val_seven[2]);

    Serial.print("gyr_x:");

    Serial.print('\t');

    Serial.println(val_seven[4]);

    Serial.print("gyr_y:");

    Serial.print('\t');

    Serial.println(val_seven[5]);

    Serial.print("gyr_z:");

    Serial.print('\t');

    Serial.println(val_seven[6]);

    delay(500);

}

你可能感兴趣的:(基于arduino的MPU6050的使用)