日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

毕业设计2- MPU6050传感器调试记录(STM32CubeMX+STM32F103C8T6)

發(fā)布時間:2023/12/31 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 毕业设计2- MPU6050传感器调试记录(STM32CubeMX+STM32F103C8T6) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一、前情提要
  • 二、STM32CubeMX配置
  • 三、寄存器介紹
  • 四、Keil代碼介紹
  • 總結(jié)

本次調(diào)試的傳感器是正點原子的MPU6050(三軸陀螺儀+三軸加速度)。因為我的畢設(shè)中并不要求解算出歐拉角,只是用來反映風(fēng)電機(jī)組(demo)的振動情況即可。為了簡化, 所以我只使用了三軸加速度計,但是在這篇介紹中,采用了硬件I2C來讀取了硬件傳感器原始數(shù)據(jù),并對這些數(shù)據(jù)進(jìn)行了 卡爾曼濾波。

一、前情提要

這部分的問題是我在剛接觸這個傳感器的幾個問題,通過自己查閱資料有了個大致的了解。因此在這里想分享一下。感謝各位大佬們的分享,讓我不斷地可以學(xué)習(xí)。

我看了1個博客和1個小破站上的視頻,感覺博主和UP主講的很好
小破站視頻: https://www.bilibili.com/video/BV1sL411F7fu?spm_id_from=333.337.search-card.all.click
知乎博客: https://zhuanlan.zhihu.com/p/195683958
代碼參考視頻: https://www.bilibili.com/video/BV1qf4y1r73k?spm_id_from=333.337.search-card.all.click

這些問題也是我自己的理解,僅供參考,有不正確之處,歡迎大家指出,我的郵箱:2802433362@qq.com

1.你能解釋一下這種N軸IMU常見的一些概念嗎?
(1)笛卡爾坐標(biāo)系:

在下面實際中的這張圖好像跟上面的不太一樣啊,其實我們旋轉(zhuǎn)一下就好了,我說這個的目的是在姿態(tài)解算的時候,我們經(jīng)常會旋轉(zhuǎn)坐標(biāo)系,注意XYZ軸的位置關(guān)系千萬不要搞混了,有時候我自己也是多旋轉(zhuǎn)就亂了,所以可以借助右手坐標(biāo)系來幫助我們理解。

(2)歐拉角:我們常說的歐拉角指的是ROLL(橫滾角)、偏航角(Yaw)、俯仰角(Pitch)。具體的大家可以根據(jù)下面的模型來進(jìn)行理解。知乎博主“碼農(nóng)愛學(xué)習(xí)”寫的真的不錯,簡單易懂,很適合我們這種小白。“https://zhuanlan.zhihu.com/p/195683958”,我敢我再寫下去也是照搬人家的東西,博主概括的真的很全。

(3)四元素:他是表示旋轉(zhuǎn)的另一種方式,可以與歐拉角進(jìn)行轉(zhuǎn)化,具體的話可以參考CSDN的另外一個博主的文章:https://blog.csdn.net/xiaoma_bk/article/details/79082629
(4)陀螺儀傳感器:這個是涉及到很多物理方面的東西,我們可以簡單的認(rèn)為它可以X、Y、Z軸的角速度。
(5)加速度計傳感器:測量的是X、Y、Z的加速度。
(6)磁力計傳感器:測量的3軸磁場強(qiáng)度(這個目前我也不是很熟,后面要慢慢用起來的)

2. 我在網(wǎng)上查閱的資料看到有3軸、6軸、9軸、10軸傳感器你能解釋一下有什么區(qū)別嗎?
(1) 3軸傳感器是指3軸陀螺儀。 它測量的是3個軸(XYZ)的角速度,其實通過這三個數(shù)據(jù)也能進(jìn)行姿態(tài)解算得到三個歐拉角(俯仰角、橫滾角、偏航角),因此他也是可以獨立工作的,出現(xiàn)了市面上常見的3軸傳感器。但是這個傳感器存在的問題是:
(a)因為它的計算方式的角度=角速度*dt,大家學(xué)過高數(shù)和大學(xué)物理,當(dāng)dt很小時,我們可以把物體看成勻速運動,但是這樣造成的問題是不太符合實際情況,我們只是假設(shè)這樣子,會有較大的累積誤差;
(b)之前看那個博主說,只使用3軸陀螺儀會出現(xiàn)相位差的問題(這部分我不是很懂,后面需要去補(bǔ)充一些知識)。
偉大的前輩們也知道這個問題,所以一個神奇的想法就產(chǎn)生了,能不能用兩個傳感器,相互校正一下,然后取個平均啥的(傳感器融合當(dāng)然沒這么簡單,此處只是舉個栗子),應(yīng)該能精確很多吧。但是從兩個角度來做效果應(yīng)該更好,因為再加一個3軸陀螺儀,就沒多大必要(此處我也不知道解釋比較好,就是那種本來這個誤差就大,換個角度去測量會更好,而不是疊羅漢。),于是6軸加速度就產(chǎn)生了。
(2)6軸傳感器是指3軸陀螺儀+3軸加速度計。 3軸加速度計測量的就是XYZ軸上的加速度g的一個分量。當(dāng)這個坐標(biāo)系很正的時候,三軸的數(shù)值應(yīng)該為aacx=0g、aacy=0g、aacz=1*g,其中9為重力加速度,9.8m/s2。當(dāng)這個傳感器有一個傾斜的話,g在x軸和y軸上就會有個分量,有可能就變成了aacx=0.3g、aacy=0.2g、aacz=0.7g,我們其實可以根據(jù)這些數(shù)據(jù)得到三個歐拉角,所有單獨用加速度計也可以進(jìn)行姿態(tài)結(jié)算,但是如果單獨用的話我們是無法解算出偏航的角的??梢詤⒖枷旅娴耐茖?dǎo)公式,我們通過傳感器得到的是ax、ay、az但是我們通過推導(dǎo)發(fā)現(xiàn)y沒了(p代表pitch俯仰角、r表示raw橫滾角、y表示yaw偏航角),數(shù)學(xué)就是這么神奇,哈哈,想不到吧,所以3軸加速度計只能解算出pitch角和raw角,所以6軸傳感器的yaw(偏航角會一直漂移),而pitch(俯仰角)和raw(橫滾角)通過數(shù)據(jù)融合算法可以得到較為穩(wěn)定的值。,目前常用的數(shù)據(jù)融合算法是DMP和卡爾曼濾波??柭鼮V波不得不說是一個很神奇的東西,此處強(qiáng)烈感謝卡爾曼前輩能研究出這么優(yōu)秀又通用的算法。

(3)9軸傳感器是指3軸陀螺儀+3軸加速度計+3軸磁力計。加3軸磁力計的目的大家可能可以猜到的啦,可以把偏航角也給校準(zhǔn)了,這樣可以得到較為穩(wěn)定的3個歐拉角(或者穩(wěn)定的四元組),具體的解算過程大家可以參考上面推薦的知乎博客,大佬寫的真的不錯,當(dāng)然小破站上的小哥哥的那個視頻講的也很清楚,再次感謝大佬們。我這次沒有選用類似MPU9250的9軸傳感器,一是因為我并不需要進(jìn)行姿態(tài)計算,二是因為我的整個系統(tǒng)存在電機(jī)和鋼軸,會對磁力計的校準(zhǔn)影響很大,不能起到相應(yīng)的效果。因此大家在使用的時候應(yīng)該主要有磁場校準(zhǔn)影響的情況。
9軸傳感器不是已經(jīng)很完美了嗎?可以完全把姿態(tài)計算出來,10軸傳感器又是啥哩
(4)10軸傳感器是指3軸陀螺儀+3軸加速度計+3軸磁力計+1個氣壓計,這個可以把氣壓高度計算出來,我認(rèn)為這個是錦上添花的作用。 ,當(dāng)然存在即是合理,自然有它的應(yīng)用場景。

3. 網(wǎng)上說的DMP算法和卡爾曼濾波你能簡要說一下他們是什么嗎?
(1)對于DMP算法:可以參考知乎博主“碼農(nóng)愛學(xué)習(xí)”的這篇文章:https://zhuanlan.zhihu.com/p/165156300
復(fù)制他的一段話:DMP就是MPU6050內(nèi)部的運動引擎,全稱Digital Motion Processor,直接輸出四元數(shù),可以減輕外圍微處理器的工作負(fù)擔(dān)且避免了繁瑣的濾波和數(shù)據(jù)融合。 就我們使用的諸如MPU6050、MPU9250等來說,DMP是硬件融合,就是商家已經(jīng)做了硬件的嵌入,我們只需要調(diào)用相應(yīng)的驅(qū)動庫即可,這樣可以很方便的,具體的一些驅(qū)動程序可以參考正點原子的驅(qū)動程序。
(2)對于卡爾曼濾波算法: 利用加速度計采集的3軸加速度計進(jìn)行姿態(tài)融合成的pitch、roll作為觀測值, 利用陀螺儀采集的3軸角度值進(jìn)行的姿態(tài)融合成的pitch,yaw,raw作為測量值。所以利用卡爾曼濾波可以實現(xiàn)pitch(俯仰角)、roll(橫滾角)的穩(wěn)定輸出。
(3)下面還是引用知乎博主“碼農(nóng)愛學(xué)習(xí)”中的內(nèi)容:這部分其實反映的是卡爾曼濾波的思想,K其實指的是卡爾曼增益,這部分我們可以這樣理解:每個傳感器都可以進(jìn)行姿態(tài)解算,得到自己的三個歐拉角,而我們希望把這些融合(直接取平均的方式顯然太low)了。因為每個傳感器都有自己的優(yōu)缺點,我們應(yīng)該把每個傳感器的優(yōu)點利用起來會使結(jié)果更加地準(zhǔn)確,因此前輩們提取了每個傳感器權(quán)重不同的方法來進(jìn)行融合,至于這個權(quán)重到底是多少,卡爾曼老先生在自己的論文中有明確的推導(dǎo)(卡爾曼濾波最經(jīng)典的那5個方程:2個預(yù)測方程,3個更新方程)。此處不再多做介紹,大家如果對卡爾曼濾波原理什么的想要有更深的了解,可以自行搜索,后面我也會自己出一期我自己對卡爾曼濾波的理解。

二、STM32CubeMX配置

有了上面的一些基礎(chǔ)概念和了解,我們下面開始配置STM32CubeMX
(1) 在“SYS”設(shè)置為“SW”調(diào)試模式;

(2)我們在“RCC”中選擇外部晶振模式;

(3) 因為MPU6050采用的通信協(xié)議是I2C,而我們又想采用硬件I2C去開發(fā),所以必須進(jìn)行勾選。

(4)因為我們想把數(shù)據(jù)打印到電腦的“串口調(diào)試助手”,所以我們需要開一路串口,波特率為115200;

(5)我們下面配置時鐘樹;

(6)將這個工程存放在文件夾中,整個目錄最好不要有中文,因為后面自動生成代碼的時候并不能直接打開,不過問題也不大,需要自己去相關(guān)文件夾中的找到工程文件打開;

(7)我們勾選一下我們希望生成文件的配置。

到此為止,我們的配置就已經(jīng)完成了。

三、寄存器介紹

對于傳感器而言,寄存器是很重要的東西,所以我們想要使用一個傳感器,一定要清楚他的寄存器怎樣配置,數(shù)據(jù)存儲在哪個寄存器中
(其實我在學(xué)習(xí)的時候也不喜歡看手冊,但是咱們都是搞這個的,datasheet肯定要看的,后面我們能形成屬于自己的一套看datasheet的流程和經(jīng)驗,會很舒服的)。我這里只是介紹一下我再這次調(diào)試中用到的寄存器,具體的每一個比特位到底表示什么大家自己查手冊就好了。








四、Keil代碼介紹

這部分是參考小破站上的視頻講解:https://www.bilibili.com/video/BV1qf4y1r73k?spm_id_from=333.337.search-card.all.click(俺是妥妥自己搬運工具人,同時加上自己的一點理解)。關(guān)于我們應(yīng)該對I2C通信有個簡單的了解吧(不了解的話,小破綻也有很多資源,我比較推薦的是創(chuàng)客學(xué)院的武老師的講解)。對于I2C設(shè)備,都有一個自己的設(shè)備地址,我們首先要做的知道設(shè)備地址。

(1)首先我們進(jìn)行多串口重映像,在“usart.h”文件中添加以下代碼;

#include "stdarg.h" #include "string.h" #include "stdio.h"

(2)在“usart.c”文件中添加下面的代碼;

#define TXBUF_SIZE_MAX 100 void usart2_printf(const char *format, ...) {va_list args;uint32_t length;uint8_t txbuf[TXBUF_SIZE_MAX] = {0};va_start(args, format);length = vsnprintf((char *)txbuf, sizeof(txbuf), (char *)format, args);va_end(args);HAL_UART_Transmit(&huart2, (uint8_t *)txbuf, length, HAL_MAX_DELAY);memset(txbuf, 0, TXBUF_SIZE_MAX); }

(3)對于類似樹莓派的Linux系統(tǒng)中我們可以通過I2C查詢的指令即可實現(xiàn),當(dāng)然,STM32也有相應(yīng)的程序可以查看:

for (uint8_t i=0; i<255;i++) {if(HAL_I2C_IsDeviceReady(&hi2c1, i ,1, 1000) == HAL_OK) //尋找設(shè)備地址,I2C原裝函數(shù) { usart2_printf("%d\r\n",i);break;}. }

我們在串口中可以看到返回值,我返回的是208,轉(zhuǎn)換成16進(jìn)制數(shù)據(jù)為0xD0,所以我們的I2C設(shè)備地址為0xD0。
(4)下面我們在“main.c”文件中 添加宏定義:

//***************************************MPU6050是地址***********************************// #define MPU6050_ADDR 0xD0 //*******************************通過查看芯片手冊相關(guān)傳感器地址**************************// #define SMPLRT_DIV_REG 0x19 #define GYRO_CONFIG_REG 0x1B #define ACCEL_CONFIG_REG 0x1c #define ACCEL_XOUT_H_REG 0x3B #define TEMP_OUT_H_REG 0x41 #define GYRO_XOUT_H_REG 0x43 #define PWR_MGMT_1_REG 0x6B //電源管理1寄存器 #define WHO_AM_I_REG 0x75 //************************加速度計*********************// int16_t Accel_X_RAW = 0; int16_t Accel_Y_RAW = 0; int16_t Accel_Z_RAW = 0; //***********************陀螺儀***********************// int16_t Gyro_X_RAW = 0; int16_t Gyro_Y_RAW = 0; int16_t Gyro_Z_RAW = 0; int16_t Temp_RAW = 0; float Ax,Ay,Az,Gx,Gy,Gz,Temp; //將最后讀取的值放入這些變量中

(5)進(jìn)行MPU6050初始化,配置一些寄存器;

void MPU6050_Init(void ) {/*HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);第1個參數(shù)為I2C操作句柄第2個參數(shù)為從機(jī)設(shè)備地址第3個參數(shù)為從機(jī)寄存器地址第4個參數(shù)為從機(jī)寄存器地址長度第5個參數(shù)為發(fā)送的數(shù)據(jù)的起始地址第6個參數(shù)為傳輸數(shù)據(jù)的大小第7個參數(shù)為操作超時時間    */uint8_t check,Data;// check device ID WHO_AM_I//檢查設(shè)備ID HAL_I2C_Mem_Read (&hi2c1 ,MPU6050_ADDR,WHO_AM_I_REG,1,&check ,1,1000);if(check == 104) //if the device is present,寄存器地址默認(rèn)0x68{//power management register 0x6B we should write all 0's to wake the sensor up//電源管理寄存器,我們應(yīng)該在0x6B中寫入所有0來喚醒傳感器Data = 0;HAL_I2C_Mem_Write (&hi2c1 ,MPU6050_ADDR ,PWR_MGMT_1_REG ,1,&Data ,1,1000);//Set DATA RATE of 1KHz by writing SMPLRT_DIV register//通過寫入SMPLRT_DIV寄存器設(shè)置1KHz的數(shù)據(jù)速率Data = 0x07;HAL_I2C_Mem_Write (&hi2c1 ,MPU6050_ADDR ,SMPLRT_DIV_REG ,1 ,&Data,1,1000);// Set accelerometer configuration in ACCEL_CONFIG Register// XA_ST=0,YA_ST=0,ZA_ST=0, FS_SEL=0 ->±2g//在加速度寄存器中修改配置Data = 0x00;HAL_I2C_Mem_Write (&hi2c1 ,MPU6050_ADDR, ACCEL_CONFIG_REG, 1, &Data, 1, 1000);// Set Gyroscopic configuration in GYRO_CONFIG Register// XG_ST=0,YG_ST=0, FS_SEL=0 ->± 250 °/s//修改重力加速計配置Data = 0x00;HAL_I2C_Mem_Write (&hi2c1 ,MPU6050_ADDR, GYRO_CONFIG_REG, 1, &Data, 1, 1000);} }

(6)進(jìn)行數(shù)據(jù)讀取函數(shù):加速度數(shù)據(jù)讀取、陀螺儀數(shù)據(jù)讀取、溫度數(shù)據(jù)讀取;

//************************************加速度傳感器讀取*************************************// void MPU6050_Read_Accel(void) {uint8_t Rec_Data[6];//Read 6 BYTES of data starting from ACCEL_XOUT_H registerHAL_I2C_Mem_Read (&hi2c1 ,MPU6050_ADDR ,ACCEL_XOUT_H_REG ,1,Rec_Data ,6,1000);Accel_X_RAW = (int16_t )(Rec_Data [0] <<8 | Rec_Data [1]);Accel_Y_RAW = (int16_t )(Rec_Data [2] <<8 | Rec_Data [3]);Accel_Z_RAW = (int16_t )(Rec_Data [4] <<8 | Rec_Data [5]);Ax = Accel_X_RAW/16384.0;Ay = Accel_Y_RAW/16384.0;Az = Accel_Z_RAW/16384.0; } //*********************************陀螺儀數(shù)據(jù)讀取*****************************************// void MPU6050_Read_Gyro(void ) {uint8_t Rec_Data[6];// Read 6 BYTES of data staring from GYRO_XOUT_H registerHAL_I2C_Mem_Read (&hi2c1, MPU6050_ADDR ,GYRO_XOUT_H_REG ,1,Rec_Data ,6 ,1000);Gyro_X_RAW = (int16_t )(Rec_Data [0] << 8 | Rec_Data [1]);Gyro_Y_RAW = (int16_t )(Rec_Data [2] << 8 | Rec_Data [3]);Gyro_Z_RAW = (int16_t )(Rec_Data [4] << 8 | Rec_Data [5]);Gx = Gyro_X_RAW/131.0;Gy = Gyro_Y_RAW/131.0;Gz = Gyro_Z_RAW/131.0; } //***********************************芯片溫度讀取************************************// void MPU6050_Read_Temp(void ) {uint8_t Rec_Data[2];HAL_I2C_Mem_Read (&hi2c1 ,MPU6050_ADDR ,TEMP_OUT_H_REG ,1 ,Rec_Data ,2 ,1000);Temp_RAW = (int16_t )(Rec_Data [0]<<8)|Rec_Data [1];Temp = 36.53 + (Temp_RAW )/340; }

(7) 在主函數(shù)中調(diào)用這些函數(shù)即可;

MPU6050_Init (); MPU6050_Read_Accel(); MPU6050_Read_Gyro(); MPU6050_Read_Temp(); usart2_printf("Ax=%.2f,Ay=%.2f,Az=%.2f\r\n",Ax,Ay,Az); usart2_printf("Gx=%.2f,Gy=%.2f,Gz=%.2f\r\n",Gx,Gy,Gz); usart2_printf("Temperature=%.2f,\r\n",Temp ); HAL_Delay (500);

(8)我們將這些代碼編譯,燒錄到我們單片機(jī)中即可。


總結(jié)

通過本次實驗,我學(xué)會了:
(1)了解了陀螺儀進(jìn)行姿態(tài)計算的原理;
(2)大致了解卡爾曼濾波的基本過程,同時怎么樣將卡爾曼應(yīng)用到卡爾曼濾波;
(3)通過單片機(jī)實現(xiàn)了MPU6050原始數(shù)據(jù)的讀取。
后面還需要學(xué)習(xí)的:
(1)陀螺儀、加速度計、磁力計他們的工作原理是什么,誤差到底來自于那些方面;
(2)利用這些原始數(shù)據(jù)進(jìn)行姿態(tài)解算的具體怎么操作;
(3)在草稿本上認(rèn)真推導(dǎo)姿態(tài)解算的過程,并把它記錄下來。

總結(jié)

以上是生活随笔為你收集整理的毕业设计2- MPU6050传感器调试记录(STM32CubeMX+STM32F103C8T6)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。