基于arduino的MPU6050的使用

摘要

MPU6050是InvenSense公司推出的全球首款整合性6轴运动处理组件,内部整合了3轴陀螺仪和3轴加速度传感器。在制作自平衡小车和四轴六轴时需要用来做姿态的监控。
基于arduino的MPU6050的使用_第1张图片
本文核心记录使用arduino uno开发板获取MPU6050三轴数据的基本操作

硬件接线

MPU6050模块使用的数据接口协议是I2C总线协议,在arduino中使用Wire类库来实现MPU6050的访问。
基于arduino的MPU6050的使用_第2张图片
接线方式:
//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中读数据

// A code block
	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();

示例.向MPU6050中写数据

	Wire.beginTransmission(0x68); //开启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/32768250
	acc_x=ACCEL_X/32768*2g;
	g为当地重力加速度,取9.8m/s^2;

其中:MPU6050寄存器详细说明可以查询产品的数据手册。
完整实例代码:

/*
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[3] = (float)(val_seven[3] / 340 + 36.53);//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]);
   Serial.print("TEMP:");
   Serial.print('\t');
   Serial.println(val_seven[3]);
   delay(500);
}


关注微信公众号,后台回复‘MPU6050’获取数据手册

你可能感兴趣的:(笔记)