国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【嵌入式模塊】MPU6050

這篇具有很好參考價(jià)值的文章主要介紹了【嵌入式模塊】MPU6050。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

0 前言

??作為慣性傳感器中入門級(jí)別的器件,MPU6050憑借它出色的性價(jià)比成為一款非常常用的角度姿態(tài)傳感器,在很多科創(chuàng)項(xiàng)目中被使用。我之前也接觸過很多次這個(gè)器件,也收集了不少資料,趁此機(jī)會(huì)總結(jié)一下學(xué)習(xí)筆記。

1 MPU6050概述

1.1 基本概述

??MPU6050包含3軸陀螺儀和3軸加速度計(jì),其中陀螺儀的主要作用是測(cè)量物體繞芯片的三個(gè)坐標(biāo)軸的角速度,其原理是高速旋轉(zhuǎn)的轉(zhuǎn)子指向的方向會(huì)保持不變,即所謂陀螺效應(yīng),詳細(xì)介紹建議自行搜索“陀螺儀工作原理”;加速度計(jì)則是測(cè)量三個(gè)軸向的加速度,同樣也是指芯片的三個(gè)坐標(biāo)軸。其原理可以想象成一個(gè)立方體箱子里面有一個(gè)失重懸空的小球,當(dāng)受到外界壓力時(shí),小球會(huì)朝著某個(gè)方向運(yùn)動(dòng),箱子內(nèi)壁就會(huì)受到對(duì)應(yīng)大小的壓力,從而可以計(jì)算出各個(gè)方向的加速度大小。
mpu6050,# 嵌入式設(shè)備,單片機(jī),嵌入式硬件,MPU6050,IMU,慣性器件

mpu6050,# 嵌入式設(shè)備,單片機(jī),嵌入式硬件,MPU6050,IMU,慣性器件

??當(dāng)整體受到向左的加速度時(shí),小球會(huì)有一個(gè)相對(duì)箱子向右的加速度,從而右側(cè)“箱壁”會(huì)受到對(duì)應(yīng)加速度大小的力,這樣就能計(jì)算出加速度的大小。

??MPU6050是InvenSense公司推出的全球首款整合性6軸運(yùn)動(dòng)處理組件。目前InvenSense已被日本的TDK公司收購(gòu),在他官網(wǎng)(https://invensense.tdk.com/),可能是年代久遠(yuǎn),MPU6050已經(jīng)是該公司的邊緣產(chǎn)品了,6軸芯片當(dāng)中,6050和6500兩款芯片被排在最后,還都是NOT RECOMMENDED的狀態(tài),而且資料支持也不是很完善,找遍了網(wǎng)站,也只找到了一個(gè)放數(shù)據(jù)手冊(cè)的網(wǎng)頁(yè),開發(fā)相關(guān)的寄存器手冊(cè)并未找到。因此,建議還是在網(wǎng)上去搜索資料吧,如下圖所示,都是網(wǎng)上流傳的經(jīng)典資料。

mpu6050,# 嵌入式設(shè)備,單片機(jī),嵌入式硬件,MPU6050,IMU,慣性器件

??MPU6050的核心就是它內(nèi)部的寄存器。它內(nèi)部有118個(gè)寄存器(編號(hào)從0到117)。其中需要注意,雖然寄存器手冊(cè)上寄存器編號(hào)是從13開始,但實(shí)際上13之前的寄存器也是可以使用的(看后面的代碼就知道了)。
??這些寄存器有一些是用來(lái)設(shè)置參數(shù)的,可讀可寫;也有一些是存放一些數(shù)據(jù)供外部讀取的,只可讀。它是基于IIC進(jìn)行通信,因此,在使用時(shí),先找到傳輸器件地址,然后再傳輸寄存器地址,最后傳輸相應(yīng)的數(shù)據(jù)或者指令,這也是IIC協(xié)議和器件寄存器交互的常用設(shè)定。

??既然有這么多寄存器,那用起來(lái)豈不是很困難?并不是,雖然寄存器多,但實(shí)際使用時(shí)也不需要使用如此多的寄存器。而且即使要使用的話,也可以利用C語(yǔ)言中的宏定義,這樣也不麻煩。

1.2 引腳和常用原理圖

??為了將這個(gè)芯片集成到我們需要的系統(tǒng)當(dāng)中,就需要了解這款芯片的引腳和它常用的原理圖,如下圖所示,這個(gè)是市面上賣的MPU6050模塊的原理圖。

mpu6050,# 嵌入式設(shè)備,單片機(jī),嵌入式硬件,MPU6050,IMU,慣性器件

可以看到,這里引出了8個(gè)引腳,分別是電源引腳5V和GND,IIC通信引腳SCL和SDA,一般來(lái)說(shuō),大部分的應(yīng)用只需要接這四個(gè)引腳即可。其中,XCL和XDA是額外的IIC通信引腳,主要用于連接外部的磁力傳感器,并利用自帶的運(yùn)動(dòng)處理器DMP硬件加速引擎,通過主IIC接口,向應(yīng)用輸出完整的9軸融合演算數(shù)據(jù)。
??而AD0引腳是用來(lái)設(shè)置IIC通信中的從機(jī)地址,如果接地(不接),則從機(jī)地址為0x68, 如果接高電平,則從機(jī)地址為0x69。而INT引腳主要用于中斷,如果要使用中斷需要設(shè)置相關(guān)的寄存器。

2 代碼

??了解了MPU6050的基礎(chǔ)知識(shí),接下來(lái)就是寫代碼來(lái)使用了。如果還沒確定使用的微處理器,我推薦先使用Arduino,因?yàn)樗闪撕芏嗟牡谌綆?kù),這樣在使用一些器件時(shí)不用自己再重復(fù)造輪子,只需要會(huì)調(diào)用即可。
??在Arduino中也有MPU6050的庫(kù),如下圖所示。

mpu6050,# 嵌入式設(shè)備,單片機(jī),嵌入式硬件,MPU6050,IMU,慣性器件

安裝好庫(kù)之后,接下來(lái)就找到給出的例子來(lái)學(xué)習(xí)它內(nèi)部的代碼了。

mpu6050,# 嵌入式設(shè)備,單片機(jī),嵌入式硬件,MPU6050,IMU,慣性器件

這里提供了6個(gè)例子,基本包含了大部分的使用。

??當(dāng)然,使用Arduino IDE也存在一個(gè)問題,那就是代碼不能定位過去,查看庫(kù)的源碼不太方便,因此建議自己基于VS Code配一個(gè)Arduino的環(huán)境,或者直接下載插件Platform IO這個(gè)插件,具體的教程建議自行搜索。
??具體可以看一下這個(gè)庫(kù)的源碼,主要是以下幾個(gè)文件,各自的作用已標(biāo)注清楚。
mpu6050,# 嵌入式設(shè)備,單片機(jī),嵌入式硬件,MPU6050,IMU,慣性器件
因此,如果不需要使用DMP時(shí),只需要包含"MPU6050.h"即可。

??那如果是其他的微處理器呢?比如51或者STM32等。這個(gè)可以考慮在網(wǎng)上找一些現(xiàn)成的,也可以考慮自己根據(jù)這個(gè)庫(kù)文件的源碼自己寫一個(gè)適配某個(gè)處理器的庫(kù)。本質(zhì)就是IIC通信和寄存器的讀取。這里放一個(gè)基于51的網(wǎng)上流傳甚廣的代碼。

//****************************************
// Update to MPU6050 by shinetop
// MCU: STC89C52
// 2012.3.1
// 功能: 顯示加速度計(jì)和陀螺儀的10位原始數(shù)據(jù)
//****************************************
// 使用單片機(jī)STC89C52
// 晶振:11.0592M
// 顯示:串口
// 編譯環(huán)境 Keil uVision2
//****************************************
#include <REG52.H>
#include <math.h>    //Keil library  
#include <stdio.h>   //Keil library	
#include <INTRINS.H> //Keil library	
typedef unsigned char  uchar;
typedef unsigned short ushort;
typedef unsigned int   uint;
//****************************************
// 定義51單片機(jī)端口
//****************************************
sbit    SCL = P1 ^ 5;			//IIC時(shí)鐘引腳定義
sbit    SDA = P1 ^ 4;			//IIC數(shù)據(jù)引腳定義
//****************************************
// 定義MPU6050內(nèi)部地址
//****************************************
#define	SMPLRT_DIV		0x19	//陀螺儀采樣率,典型值:0x07(125Hz)
#define	CONFIG			0x1A	//低通濾波頻率,典型值:0x06(5Hz)
#define	GYRO_CONFIG		0x1B	//陀螺儀自檢及測(cè)量范圍,典型值:0x18(不自檢,2000deg/s)
#define	ACCEL_CONFIG	0x1C	//加速計(jì)自檢、測(cè)量范圍及高通濾波頻率,典型值:0x01(不自檢,2G,5Hz)
#define	ACCEL_XOUT_H	0x3B
#define	ACCEL_XOUT_L	0x3C
#define	ACCEL_YOUT_H	0x3D
#define	ACCEL_YOUT_L	0x3E
#define	ACCEL_ZOUT_H	0x3F
#define	ACCEL_ZOUT_L	0x40
#define	TEMP_OUT_H		0x41
#define	TEMP_OUT_L		0x42
#define	GYRO_XOUT_H		0x43
#define	GYRO_XOUT_L		0x44
#define	GYRO_YOUT_H		0x45
#define	GYRO_YOUT_L		0x46
#define	GYRO_ZOUT_H		0x47
#define	GYRO_ZOUT_L		0x48
#define	PWR_MGMT_1		0x6B	//電源管理,典型值:0x00(正常啟用)
#define	WHO_AM_I		0x75	//IIC地址寄存器(默認(rèn)數(shù)值0x68,只讀)
#define	SlaveAddress	0xD0	//IIC寫入時(shí)的地址字節(jié)數(shù)據(jù),+1為讀取
//**************************************************************************************************
//定義類型及變量
//**************************************************************************************************
uchar dis[6];					//顯示數(shù)字(-511至512)的字符數(shù)組
int	dis_data;					//變量
//**************************************************************************************************
//函數(shù)聲明
//**************************************************************************************************
void  Delay5us();
void  delay(unsigned int k);										//延時(shí)
void  lcd_printf(uchar* s, int temp_data);
//********************************MPU6050操作函數(shù)***************************************************
void  InitMPU6050();											//初始化MPU6050
void  I2C_Start();
void  I2C_Stop();
void  I2C_SendACK(bit ack);
bit   I2C_RecvACK();
void  I2C_SendByte(uchar dat);
uchar I2C_RecvByte();
void  I2C_ReadPage();
void  I2C_WritePage();

void  display_ACCEL_x();
void  display_ACCEL_y();
void  display_ACCEL_z();
uchar Single_ReadI2C(uchar REG_Address);						//讀取I2C數(shù)據(jù)
void  Single_WriteI2C(uchar REG_Address, uchar REG_data);	   //向I2C寫入數(shù)據(jù)
//********************************************************************************
//整數(shù)轉(zhuǎn)字符串
//********************************************************************************
void lcd_printf(uchar* s, int temp_data)
{
    if(temp_data < 0)
    {
        temp_data = -temp_data;
        *s = '-';
    }
    else *s = ' ';

    *++s = temp_data / 10000 + 0x30;
    temp_data = temp_data % 10000; //取余運(yùn)算

    *++s = temp_data / 1000 + 0x30;
    temp_data = temp_data % 1000; //取余運(yùn)算

    *++s = temp_data / 100 + 0x30;
    temp_data = temp_data % 100; //取余運(yùn)算
    *++s = temp_data / 10 + 0x30;
    temp_data = temp_data % 10;  //取余運(yùn)算
    *++s = temp_data + 0x30;
}
//******************************************************************************************************
//串口初始化
//*******************************************************************************************************
void init_uart()
{
    TMOD = 0x21;
    TH1 = 0xfd;		//實(shí)現(xiàn)波特率9600(系統(tǒng)時(shí)鐘11.0592MHZ)
    TL1 = 0xfd;

    SCON = 0x50;
    PS = 1;    //串口中斷設(shè)為高優(yōu)先級(jí)別
    TR0 = 1;	 //啟動(dòng)定時(shí)器
    TR1 = 1;
    ET0 = 1;   //打開定時(shí)器0中斷
    ES = 1;
    EA = 1;
}
//*************************************************************************************************
//串口發(fā)送函數(shù)
//*************************************************************************************************
void  SeriPushSend(uchar send_data)
{
    SBUF = send_data;
    while(!TI);
    TI = 0;
}
//*************************************************************************************************
//************************************延時(shí)*********************************************************
//*************************************************************************************************
void delay(unsigned int k)
{
    unsigned int i, j;
    for(i = 0; i < k; i++)
    {
        for(j = 0; j < 121; j++);
    }
}
//************************************************************************************************
//延時(shí)5微秒(STC90C52RC@12M)
//不同的工作環(huán)境,需要調(diào)整此函數(shù)
//注意當(dāng)改用1T的MCU時(shí),請(qǐng)調(diào)整此延時(shí)函數(shù)
//************************************************************************************************
void Delay5us()
{
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
}
//*************************************************************************************************
//I2C起始信號(hào)
//*************************************************************************************************
void I2C_Start()
{
    SDA = 1;                    //拉高數(shù)據(jù)線
    SCL = 1;                    //拉高時(shí)鐘線
    Delay5us();                 //延時(shí)
    SDA = 0;                    //產(chǎn)生下降沿
    Delay5us();                 //延時(shí)
    SCL = 0;                    //拉低時(shí)鐘線
}
//*************************************************************************************************
//I2C停止信號(hào)
//*************************************************************************************************
void I2C_Stop()
{
    SDA = 0;                    //拉低數(shù)據(jù)線
    SCL = 1;                    //拉高時(shí)鐘線
    Delay5us();                 //延時(shí)
    SDA = 1;                    //產(chǎn)生上升沿
    Delay5us();                 //延時(shí)
}
//**************************************************************************************************
//I2C發(fā)送應(yīng)答信號(hào)
//入口參數(shù):ack (0:ACK 1:NAK)
//**************************************************************************************************
void I2C_SendACK(bit ack)
{
    SDA = ack;                  //寫應(yīng)答信號(hào)
    SCL = 1;                    //拉高時(shí)鐘線
    Delay5us();                 //延時(shí)
    SCL = 0;                    //拉低時(shí)鐘線
    Delay5us();                 //延時(shí)
}
//****************************************************************************************************
//I2C接收應(yīng)答信號(hào)
//****************************************************************************************************
bit I2C_RecvACK()
{
    SCL = 1;                    //拉高時(shí)鐘線
    Delay5us();                 //延時(shí)
    CY = SDA;                   //讀應(yīng)答信號(hào)
    SCL = 0;                    //拉低時(shí)鐘線
    Delay5us();                 //延時(shí)
    return CY;
}
//*****************************************************************************************************
//向I2C總線發(fā)送一個(gè)字節(jié)數(shù)據(jù)
//*****************************************************************************************************
void I2C_SendByte(uchar dat)
{
    uchar i;
    for(i = 0; i < 8; i++)      //8位計(jì)數(shù)器
    {
        dat <<= 1;              //移出數(shù)據(jù)的最高位
        SDA = CY;               //送數(shù)據(jù)口
        SCL = 1;                //拉高時(shí)鐘線
        Delay5us();             //延時(shí)
        SCL = 0;                //拉低時(shí)鐘線
        Delay5us();             //延時(shí)
    }
    I2C_RecvACK();
}
//*****************************************************************************************************
//從I2C總線接收一個(gè)字節(jié)數(shù)據(jù)
//******************************************************************************************************
uchar I2C_RecvByte()
{
    uchar i;
    uchar dat = 0;
    SDA = 1;                    //使能內(nèi)部上拉,準(zhǔn)備讀取數(shù)據(jù),
    for(i = 0; i < 8; i++)      //8位計(jì)數(shù)器
    {
        dat <<= 1;
        SCL = 1;                //拉高時(shí)鐘線
        Delay5us();             //延時(shí)
        dat |= SDA;             //讀數(shù)據(jù)
        SCL = 0;                //拉低時(shí)鐘線
        Delay5us();             //延時(shí)
    }
    return dat;
}
//*****************************************************************************************************
//向I2C設(shè)備寫入一個(gè)字節(jié)數(shù)據(jù)
//*****************************************************************************************************
void Single_WriteI2C(uchar REG_Address, uchar REG_data)
{
    I2C_Start();                  //起始信號(hào)
    I2C_SendByte(SlaveAddress);   //發(fā)送設(shè)備地址+寫信號(hào)
    I2C_SendByte(REG_Address);    //內(nèi)部寄存器地址,
    I2C_SendByte(REG_data);       //內(nèi)部寄存器數(shù)據(jù),
    I2C_Stop();                   //發(fā)送停止信號(hào)
}
//*******************************************************************************************************
//從I2C設(shè)備讀取一個(gè)字節(jié)數(shù)據(jù)
//*******************************************************************************************************
uchar Single_ReadI2C(uchar REG_Address)
{
    uchar REG_data;
    I2C_Start();                   //起始信號(hào)
    I2C_SendByte(SlaveAddress);    //發(fā)送設(shè)備地址+寫信號(hào)
    I2C_SendByte(REG_Address);     //發(fā)送存儲(chǔ)單元地址,從0開始
    I2C_Start();                   //起始信號(hào)
    I2C_SendByte(SlaveAddress + 1);//發(fā)送設(shè)備地址+讀信號(hào)
    REG_data = I2C_RecvByte();     //讀出寄存器數(shù)據(jù)
    I2C_SendACK(1);                //接收應(yīng)答信號(hào)
    I2C_Stop();                    //停止信號(hào)
    return REG_data;
}
//******************************************************************************************************
//初始化MPU6050
//******************************************************************************************************
void InitMPU6050()
{
    Single_WriteI2C(PWR_MGMT_1, 0x00);	//解除休眠狀態(tài)
    Single_WriteI2C(SMPLRT_DIV, 0x07);
    Single_WriteI2C(CONFIG, 0x06);
    Single_WriteI2C(GYRO_CONFIG, 0x18);
    Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//******************************************************************************************************
//合成數(shù)據(jù)
//******************************************************************************************************
int GetData(uchar REG_Address)
{
    uchar H, L;
    H = Single_ReadI2C(REG_Address);
    L = Single_ReadI2C(REG_Address + 1);
    return ((H << 8) + L); //合成數(shù)據(jù)
}
//******************************************************************************************************
//超級(jí)終端(串口調(diào)試助手)上顯示10位數(shù)據(jù)
//******************************************************************************************************
void Display10BitData(int value)
{
    uchar i;
//	value/=64;							//轉(zhuǎn)換為10位數(shù)據(jù)
    lcd_printf(dis, value);			//轉(zhuǎn)換數(shù)據(jù)顯示
    for(i = 0; i < 6; i++)
    {
        SeriPushSend(dis[i]);
    }

    // 	DisplayListChar(x,y,dis,4);	//啟始列,行,顯示數(shù)組,顯示長(zhǎng)度
}
//*******************************************************************************************************
//主程序
//*******************************************************************************************************
void main()
{
    delay(500);		//上電延時(shí)
    init_uart();
    InitMPU6050();	//初始化MPU6050
    delay(150);
    while(1)
    {
        Display10BitData(GetData(ACCEL_XOUT_H));	//顯示X軸加速度
        Display10BitData(GetData(ACCEL_YOUT_H));	//顯示Y軸加速度
        Display10BitData(GetData(ACCEL_ZOUT_H));	//顯示Z軸加速度
        Display10BitData(GetData(GYRO_XOUT_H));		//顯示X軸角速度
        Display10BitData(GetData(GYRO_YOUT_H));		//顯示Y軸角速度
        Display10BitData(GetData(GYRO_ZOUT_H));		//顯示Z軸角速度

        SeriPushSend(0x0d);
        SeriPushSend(0x0a);//換行,回車
        delay(2000);
    }
}

3 姿態(tài)解算

??前面提到MPU6050有很多的寄存器,但其實(shí)最核心的就是陀螺儀和加速度讀取的數(shù)值,即姿態(tài)數(shù)據(jù)。但是,需要注意的是,前面也強(qiáng)調(diào)過,這個(gè)讀取到的姿態(tài)數(shù)據(jù)是基于元器件坐標(biāo)系的,而在實(shí)際應(yīng)用中需要的更多是相對(duì)于大地坐標(biāo)系的數(shù)據(jù)。這樣得到的才是真正意義上的姿態(tài)。

??首先要搞清楚芯片坐標(biāo)系的樣式,這直接關(guān)系到所測(cè)數(shù)據(jù)的正方向。如下圖所示。

mpu6050,# 嵌入式設(shè)備,單片機(jī),嵌入式硬件,MPU6050,IMU,慣性器件

芯片水平放置,絲印朝正上方,此時(shí),前方是+Y方向,右側(cè)是+X方向,正上方是+Z方向,三軸符合右手坐標(biāo)系。至于旋轉(zhuǎn)的角速度的正方向,也是按照右手定則,大拇指指向軸的正方向,四指所指的方向?yàn)樾D(zhuǎn)的正方向。

??關(guān)于MPU6050的姿態(tài)解算,主要有兩種方式,分別是基于歐拉角和旋轉(zhuǎn)矩陣推導(dǎo)直接調(diào)用芯片中的DMP模塊,這里簡(jiǎn)要介紹一下。

3.1 歐拉角&旋轉(zhuǎn)矩陣

??關(guān)于歐拉角和旋轉(zhuǎn)矩陣,如果不理解基礎(chǔ)知識(shí)的建議翻閱我之前的一篇博客:

【學(xué)習(xí)筆記】空間坐標(biāo)系旋轉(zhuǎn)與四元數(shù)

了解基本的旋轉(zhuǎn)矩陣的知識(shí)后,接下來(lái)就是利用旋轉(zhuǎn)矩陣來(lái)計(jì)算芯片的姿態(tài)角了。這里建議參考這篇文章,寫得比較詳細(xì)。

有一點(diǎn)存在一點(diǎn)疑問,那就是文章中提到的是Z-Y-X歐拉角,但我認(rèn)為應(yīng)該叫Z-Y-X固定角更合理,這也符合教材上的矩陣相乘的順序。

此外,這篇文章當(dāng)中陀螺儀和加速度計(jì)解算是分開的,加速度主要負(fù)責(zé)靜態(tài)的姿態(tài)角,陀螺儀反應(yīng)動(dòng)態(tài)的姿態(tài)角變化,然后設(shè)定不同的權(quán)值,加權(quán)求和得到。其實(shí)數(shù)據(jù)融合更加合理的應(yīng)該是使用卡爾曼濾波。這個(gè)后續(xù)也會(huì)跟進(jìn)補(bǔ)充。

3.2 DMP

??DMP(Digital Motion Processor),即數(shù)字運(yùn)動(dòng)處理器,是MPU6050芯片內(nèi)置的一個(gè)重要模塊。它的作用就是根據(jù)測(cè)得的陀螺儀和加速度數(shù)據(jù)計(jì)算得到芯片的歐拉角yaw,pitch,roll的值。使用者可以不用關(guān)心它內(nèi)部是怎么實(shí)現(xiàn)的。如果想了解的話可以去找找DMP相關(guān)的資料。

3 校正

??IMU有一個(gè)重要的特性,那就是它的誤差是會(huì)隨時(shí)間累積的,最好是隔一段時(shí)間校正一次。而所謂校正,就一定要有一個(gè)參考對(duì)象。對(duì)于MPU6050來(lái)說(shuō),一般參考對(duì)象就是地面。

??校正時(shí),首先將MPU6050放置水平,保持靜止。然后運(yùn)行代碼,讀取陀螺儀和加速度數(shù)據(jù)。理論上來(lái)說(shuō),水平靜止放置,陀螺儀數(shù)值應(yīng)該為零,不為零則是誤差,將誤差寫入到芯片內(nèi)部“偏差寄存器”中,再次讀取數(shù)值,計(jì)算誤差,如此反復(fù),直到誤差值在允許范圍之類,記下誤差值,寫入到偏差寄存器中。
??至于加速度數(shù)值,要考慮重力的影響,因?yàn)槭撬椒胖?,所以重力只在Z軸有分量。即Z軸分量為g,而默認(rèn)加速度的單位是2g,而加速度數(shù)值用16位寄存器表示,且第一位為符號(hào)位(有正負(fù)之分),因此實(shí)際數(shù)值為 ( 2 15 ? 1 ) 2 = 16383.5 ≈ 16384 \frac{\left( 2^{15}-1 \right)}{2}=16383.5\approx 16384 2(215?1)?=16383.516384,但由于這個(gè)重力加速度與Z軸正方向相反,故值為負(fù)的,即-16384.
??當(dāng)然,有時(shí)候因?yàn)榘惭b等原因,IMU校正時(shí)不能Z軸保持豎直,比如X軸保持豎直,則將實(shí)際數(shù)值代入到校正函數(shù)中,沒啥差別。這里有一篇博客給出了一個(gè)測(cè)試代碼,建議仔細(xì)閱讀。
??關(guān)于校正,實(shí)際上也可以看作是一個(gè)自動(dòng)控制系統(tǒng),因此也可以采用如PID或者是機(jī)器學(xué)習(xí)等控制方法來(lái)進(jìn)行校正。
??關(guān)于PID的例子,其實(shí)上面提到的Arduino的庫(kù)中就有使用,即它內(nèi)部的calibration()函數(shù),具體原理可以去找源碼查看。
??關(guān)于機(jī)器學(xué)習(xí)的例子,是我找到的一篇博客,用的是梯度下降的方式來(lái)取值,思路很清奇,但個(gè)人感覺本質(zhì)上還是迭代,是否使用梯度下降差別不是很大。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-824579.html

到了這里,關(guān)于【嵌入式模塊】MPU6050的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32單片機(jī)入門學(xué)習(xí)筆記——MPU6050

    STM32單片機(jī)入門學(xué)習(xí)筆記——MPU6050

    筆記整理自B站UP主江科大自化協(xié)教程《[10-2] MPU6050簡(jiǎn)介_嗶哩嗶哩_bilibili》,所用單片機(jī)也為教程推薦單片機(jī)。 如果芯片里再集成一個(gè)3軸的磁場(chǎng)傳感器,測(cè)量XYZ軸的磁場(chǎng)強(qiáng)度,那就叫做9軸姿態(tài)傳感器,如果再集成一個(gè)氣壓傳感器,測(cè)量氣壓大小,那就叫做10軸姿態(tài)傳感器,一

    2024年02月08日
    瀏覽(47)
  • 單片機(jī)開發(fā)教程3——串口發(fā)送MPU6050姿態(tài)角

    單片機(jī)開發(fā)教程3——串口發(fā)送MPU6050姿態(tài)角

    MPU6050 是 InvenSense 公司推出的整合性 6 軸運(yùn)動(dòng)處理組件,其內(nèi)部整合了 3 軸陀螺儀和 3 軸加速度傳感器,并且含有一個(gè)IIC 接口, 可用于連接外部磁力傳感器,并利用自帶的數(shù)字運(yùn)動(dòng)處理器(DMP: Digital Motion Processor) 硬件加速引擎,通過主 IIC 接口,向應(yīng)用端輸出完整的 9 軸融

    2024年02月14日
    瀏覽(22)
  • (Rockpi 4b使用心得),Python的smbus模塊,mpu6050等模塊的使用

    (Rockpi 4b使用心得),Python的smbus模塊,mpu6050等模塊的使用

    大家好,關(guān)于有些新手們買了rockpi4b,或者使用過樹莓派的在轉(zhuǎn)rockpi4b的過程中,使用Python中的smbus模塊會(huì)遇到很多錯(cuò)誤,而Python又因?yàn)槠渲械恼Z(yǔ)法特別簡(jiǎn)單的關(guān)系,所以受到了眾多程序員的擁戴,而這篇文章主要講的是使用rockpi4b的時(shí)候,和樹莓派之間又有什么不同。本人也

    2023年04月12日
    瀏覽(23)
  • 【STM32F4系列】【HAL庫(kù)】【模塊介紹】MPU6050設(shè)置與DMP庫(kù)使用

    【STM32F4系列】【HAL庫(kù)】【模塊介紹】MPU6050設(shè)置與DMP庫(kù)使用

    MPU6050是一個(gè)3軸陀螺儀(測(cè)角加速度)和3軸加速度計(jì)(測(cè)量線加速度)的測(cè)量芯片 內(nèi)部自帶運(yùn)算單元(DMP),可以輸出經(jīng)姿態(tài)融合計(jì)算后的 四元數(shù) (一種表示旋轉(zhuǎn)的方法) 而且MPU6050的價(jià)格較低(10r以下),常被用于精度不高的場(chǎng)合作為姿態(tài)感知的芯片 如經(jīng)典項(xiàng)目平衡車,某年電賽題目風(fēng)力擺

    2024年02月05日
    瀏覽(62)
  • 【畢業(yè)設(shè)計(jì)教程】單片機(jī)發(fā)送短信消息(GMS模塊) - 物聯(lián)網(wǎng) 嵌入式 stm32

    【畢業(yè)設(shè)計(jì)教程】單片機(jī)發(fā)送短信消息(GMS模塊) - 物聯(lián)網(wǎng) 嵌入式 stm32

    Hi,大家好,這里是丹成學(xué)長(zhǎng),今天向大家介紹如何使用GMS模塊,達(dá)到單片機(jī)發(fā)送短信的效果,應(yīng)用場(chǎng)景非常廣泛 ** 單片機(jī)發(fā)送短信消息(GMS模塊)** 大家可用于 課程設(shè)計(jì) 或 畢業(yè)設(shè)計(jì) 單片機(jī)-嵌入式畢設(shè)選題大全及項(xiàng)目分享: https://blog.csdn.net/m0_71572576/article/details/125409052 GS

    2024年02月02日
    瀏覽(27)
  • IoT物聯(lián)網(wǎng)嵌入式設(shè)備中30種常見傳感器模塊簡(jiǎn)介及原理講解

    IoT物聯(lián)網(wǎng)嵌入式設(shè)備中30種常見傳感器模塊簡(jiǎn)介及原理講解

    人們?yōu)榱藦耐饨绔@取信息,必須借助于感覺器官。而單靠人們自身的感覺器官,在研究自然現(xiàn)象和規(guī)律以及生產(chǎn)活動(dòng)中它們的功能就遠(yuǎn)遠(yuǎn)不夠了。為適應(yīng)這種情況,就需要傳感器。因此可以說(shuō),傳感器是人類五官的延長(zhǎng),又稱之為電五官。 在現(xiàn)代工業(yè)生產(chǎn)尤其是自動(dòng)化生產(chǎn)過

    2023年04月09日
    瀏覽(24)
  • STM32MPU6050角度的讀?。⊿TM32驅(qū)動(dòng)MPU6050)

    STM32MPU6050角度的讀?。⊿TM32驅(qū)動(dòng)MPU6050)

    注:文末附STM32驅(qū)動(dòng)MPU6050代碼工程鏈接,需要的讀者請(qǐng)自取。 MPU6050是一款集成了三軸陀螺儀和三軸加速度計(jì)的傳感器芯片,由英國(guó)飛利浦半導(dǎo)體(現(xiàn)為恩智浦半導(dǎo)體)公司生產(chǎn)。它通過電子接口(如I2C或SPI)與微控制器進(jìn)行通信,可用于測(cè)量物體的加速度和角速度,廣泛應(yīng)

    2024年02月20日
    瀏覽(23)
  • STM32----MPU6050

    STM32----MPU6050

    前言:最近幾個(gè)月沒有寫文章了,因?yàn)檫@學(xué)期的事情真的有點(diǎn)多,但是想了想,文章還是要更新,總結(jié)自己學(xué)習(xí)的知識(shí),真的很重要!?。?MPU6050 是 InvenSense 公司推出的全球首款整合性 6 軸運(yùn)動(dòng)處理組件 ,相較于多組件方案,免除了組合陀螺儀與加速器時(shí)之軸間差的問題,減

    2024年02月15日
    瀏覽(18)
  • MPU6050簡(jiǎn)介

    MPU6050簡(jiǎn)介

    MPU6050是一個(gè)6軸姿態(tài)傳感器,可以測(cè)量芯片自身X,Y,Z軸的加速度,角速度,從而得到姿態(tài)角,用于平衡車,飛行器等。 內(nèi)部結(jié)構(gòu): 3軸加速度計(jì)(Accelerometer):測(cè)X,Y,Z軸的加速度 3軸陀螺儀傳感器(Gyroscope):測(cè)X,Y,Z軸的角速度 16位ADC采集傳感器的模擬信號(hào),量化范圍:-32768~3276

    2024年02月16日
    瀏覽(15)
  • MPU6050調(diào)試

    MPU6050調(diào)試

    1 原理簡(jiǎn)介 1.1 MPU6050芯片資料 1.內(nèi)部主要結(jié)構(gòu):陀螺儀、加速度計(jì)、數(shù)字運(yùn)動(dòng)處理器DMP(Digital Motion Processor)。另外MPU6050還含有第二個(gè)IIC接口,用于連接一個(gè)第三方數(shù)字傳感器AUXAUX_DA(如磁力計(jì))用于輸出完整九軸信號(hào)(角速度、角加速度以及磁場(chǎng)信號(hào)等) 2.連接接口: (1

    2024年02月06日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包