基于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 <Wire.h>

// 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);

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,875评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,569评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,475评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,459评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,537评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,563评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,580评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,326评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,773评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,086评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,252评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,921评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,566评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,190评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,435评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,129评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,125评论 2 352

推荐阅读更多精彩内容