實驗介紹
手機上的“重力感應”想必大家都不陌生,基于重力感應可以實作飛車、輔助瞄準等各種體感非常強的互動功能。所謂的“重力感應”,其實就可以使用“加速度計及陀螺儀傳感器”來實作。
本節實驗中,我們将會基于 MPU-6050 實作一個根據開發闆姿态滾動的小球。當我們傾斜 HaaS EDU K1 時,會看見小球根據我們的傾斜方向發生相對應的偏移。

涉及知識點
- MPU-6050 的驅動和使用
- OLED繪圖
開發環境準備
硬體
開發用電腦一台
HAAS EDU K1 開發闆一塊
USB2TypeC 資料線一根
- 1
- 2
- 3
軟體
AliOS Things開發環境搭建
開發環境的搭建請參考 @ref HaaS_EDU_K1_Quick_Start (搭建開發環境章節),其中詳細的介紹了AliOS Things 3.3的IDE內建開發環境的搭建流程。
HaaS EDU K1 DEMO 代碼下載下傳
HaaS EDU K1 DEMO 的代碼下載下傳請參考 @ref HaaS_EDU_K1_Quick_Start (建立工程章節),其中,
選擇解決方案: 基于教育開發闆的示例
選擇開發闆: haaseduk1 board configure
代碼編譯、燒錄
參考 @ref HaaS_EDU_K1_Quick_Start (3.1 編譯工程章節),點選 ✅ 即可完成編譯固件。
參考 @ref HaaS_EDU_K1_Quick_Start (3.2 燒錄鏡像章節),點選 "⚡️" 即可完成燒錄固件。
硬體介紹 - MPU-6050
DataSheet
了解一款IC最快捷和精準的方法是查閱它的DataSheet。這款IC的DataSheet可以在以下連結擷取。
MPU-6000-Datasheet1.pdf MPU-6000-Register-Map1.pdf硬體規格
MPU-60X0是世界上第一款內建 6 軸MotionTracking裝置。它內建了3軸MEMS陀螺儀,3軸MEMS加速度計,以及一個可擴充的數字運動處理器 DMP( DigitalMotion Processor),可用I2C接口連接配接一個第三方的數字傳感器,比如磁力計。
MPU-6050具有三個用于将陀螺儀輸出數字化的16位模數轉換器(ADC)和三個用于将加速度計輸出數字化的16位ADC。 為了精确跟蹤快速和慢速運動,這些部件具有使用者可程式設計的陀螺儀滿量程範圍,範圍為±250,±500,±1000和±2000°/ sec(dps),以及使用者可程式設計的加速度計滿量程範圍 範圍為±2g,±4g,±8g和±16g。使用400kHz的I2C與裝置的所有寄存器進行通信。其他功能包括嵌入式溫度傳感器和片上振蕩器,在整個工作溫度範圍内誤差±1%。
更多硬體規格請參考 DataSheet。
傳感原理
陀螺儀由1850年法國實體學家萊昂·傅科在研究地球自傳中獲得靈感而發明出來的,類似像是把一個高速旋轉的陀螺放到一個萬向支架上,靠陀螺的方向來計算角速度,和現在小巧的晶片造型大相徑庭。
| |
早期的機械陀螺儀[1] |
那麼如何将這麼龐大的機械裝置,塞進小小的晶片當中呢?以目前廣泛使用的MPU-6050為例,它屬于傳感MEMS分支。傳感MEMS技術是指用微電子微機械加工出來的、用敏感元件如電容、壓電、壓阻、熱電耦、諧振、隧道電流等來感受轉換電信号的器件和系統。感興趣的同學可以來這裡學習亞德諾半導體的公開課 ——
MEMS傳感器2:加速,旋轉——陀螺儀工作原理。
我們使用的MPU-6050是一款經典的MEMS陀螺儀,即矽微機電陀螺儀。MEMS(Micro-Electro-Mechanical System)是指集機械元素、微型傳感器、微型執行器以及信号處理和控制電路、接口電路、通信和電源于一體的完整微型機電系統。絕大多數的MEMS陀螺儀依賴于互相正交的振動和轉動引起的交變科裡奧利力。在MPU-6050内部,存在一品質塊,當器件上電後,會觸發品質塊以固定頻率橫向運動。當器件遭受外力具備加速度時,就會觸發品質塊的縱向運動,進而改變四周梳齒之間的距離,改變輸出的電容,進而通過ADC将模拟信号轉換為數字信号,輸出給外部[2]。
原理圖
在原理圖中我們可以看出,器件使用I2C通訊接口。并且,器件支援使用過INT引腳,當資料到來時可以在該引腳上觸發中斷。需要注意的是,AD0引腳決定了器件位址的第 0 bit。當AD0連接配接高電平,即AD0 = 1,此時器件位址為0x69。
驅動方式
通訊接口
由DataSheet可知,MPU-6050采用的通訊方式為I2C。預設7bit裝置位址:0x69 (DataSheet P33 9.2)
在 AliOS Things 3.3中,I2C操作方式采用VFS的方式,開發者隻需要關心器件的裝置位址即可,因為隻要知道了裝置位址,讀寫位址也可以計算出,AliOS Things 會自動處理這些計算。如果我們需要為了 MPU-6050 初始化I2C接口,那麼對應的代碼為:
// solutions/eduk1_demo/drivers/sensor/drv_acc_gyro_inv_mpu6050.c
// 初始化I2C
int32_t ret = sensor_i2c_open (MPU_I2C_PORT, MPU_ADDR, I2C_BUS_BIT_RATES_100K, 0);
if (ret) {
LOGE("SENSOR", "sensor i2c open failed, ret:%d\n", ret);
return -EIO;
}
- 4
- 5
- 6
- 7
- 8
寄存器
一般,使用I2C通訊的器件,都是通過讀寫寄存器的方式來完成對裝置的讀取和配置,是以了解寄存器的分布就非常重要。由于 MPU-6050 的寄存器數量較多,建議讀者們查閱 Regsiter Map 文檔來擷取這些資訊。我們進列出部分較為關鍵的寄存器。
0x3B-0x40 三軸加速度寄存器 每軸資料2Byte
0x41-0x42 溫度寄存器 2Byte
0x43-0x48 三軸陀螺儀寄存器 每軸資料2Byte
驅動實作
uint8_t MPU_Init(void)
器件初始化。
{
uint8_t device_id = 0;
MPU_Write_Byte(MPU_PWR_MGMT1_REG, 0X80); // 複位MPU6050
aos_msleep(100);
MPU_Write_Byte(MPU_PWR_MGMT1_REG, 0X00); // 喚醒MPU6050
MPU_Set_Gyro_Fsr(3); // 陀螺儀傳感器,±2000dps
MPU_Set_Accel_Fsr(0); // 加速度傳感器,±2g
MPU_Set_Rate(50); // 設定采樣率50Hz
MPU_Write_Byte(MPU_INT_EN_REG, 0X00); // 關閉所有中斷
MPU_Write_Byte(MPU_USER_CTRL_REG, 0X00); // I2C主模式關閉
MPU_Write_Byte(MPU_FIFO_EN_REG, 0X00); // 關閉FIFO
MPU_Write_Byte(MPU_INTBP_CFG_REG, 0X80); // INT引腳低電平有效
device_id = MPU_Read_Byte(MPU_DEVICE_ID_REG);
if (device_id == MPU_DEV_ID) {
// 器件ID正确
LOGI("SENSOR", "MPU init OK\n");
MPU_Write_Byte(MPU_PWR_MGMT1_REG, 0X01); // 設定CLKSEL,PLL X軸為參考
MPU_Write_Byte(MPU_PWR_MGMT2_REG, 0X00); // 加速度與陀螺儀都工作
MPU_Set_Rate(50); // 設定采樣率為50Hz
} else {
LOGE("SENSOR", "MPU init Error -- %x\n", device_id);
return 1;
}
return 0;
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
void MPU_Get_Gyroscope(short *gx, short *gy, short *gz)
讀取三軸陀螺儀資料。由Register Map得知,隻需要從GYRO_XOUTH向後依次讀出6個寄存器内容即可。
uint8_t buf[6];
MPU_Read_Len(MPU_GYRO_XOUTH_REG, 6, buf);
*gx = ((u16)buf[0] << 8) | buf[1];
*gy = ((u16)buf[2] << 8) | buf[3];
*gz = ((u16)buf[4] << 8) | buf[5];
void MPU_Get_Accelerometer(short *ax, short *ay, short *az)
讀取三軸加速度資料。由Register Map得知,隻需要從ACCEL_XOUTH向後依次讀出6個寄存器内容即可。
MPU_Read_Len(MPU_ACCEL_XOUTH_REG, 6, buf);
*ax = ((u16)buf[0] << 8) | buf[1];
*ay = ((u16)buf[2] << 8) | buf[3];
*az = ((u16)buf[4] << 8) | buf[5];
應用開發
本實驗的應用較為簡單,隻需要讀出加速度資料,并顯示在螢幕上即可。OLED的相關接口中已經給出了豐富的繪圖函數。具體實作如下。
void gyroscope_task(void)
while (1)
{
// 清除螢幕memory
OLED_Clear();
// 擷取三軸加速度資訊
MPU_Get_Accelerometer(&r_ax, &r_ay, &r_az);
// 畫出固定的圓形邊框
OLED_DrawCircle(66, 32, 10, 1, 1);
// 畫出填充的圓
OLED_FillCircle(66 - r_ax / 250, 32 + r_ay / 500, 8, 1);
// 将螢幕memory顯示出來
OLED_Refresh_GRAM();
// 暫停20ms
aos_msleep(20);
更多應用
本實驗展示的僅是六軸傳感器的一個非常簡單的應用。随着類似傳感器的體積越來越小,精度越來越高,它們也被應用在各種消費類電子産品,如穿戴裝置、手機上。
使用它們可以進行一些非常有趣的應用,例如,手環中經常會使用到的計步算法,運動狀态檢測算法,都是基于其中的六軸傳感器資料。近年來,還有很多學術界的工作,使用手環中的六軸傳感器來實作空中寫字的識别。
除此之外,它也廣泛應用于輔助定位、飛行裝置的姿态檢測,錄影機雲台的水準保持等等。期待讀者們能夠發掘出更多有價值的使用場景。
引用
[1] Gyroscope invented by Léon Foucault in 1852. Replica built by Dumoulin-Froment for the Exposition universelle in 1867.
National Conservatory of Arts and Crafts museum, Paris.
By Stéphane Magnenat - Own work by uploader, subject public domain, Public Domain,
https://commons.wikimedia.org/w/index.php?curid=4302903[2] 圖檔來自
https://www.analog.com/cn/education/education-library/videos/5996766351001.html開發者支援
HaaS官方:
https://haas.iot.aliyun.com/HaaS技術社群:
https://blog.csdn.net/HaaSTech開發者釘釘群和公衆号見下圖,開發者釘釘群每天都有技術支援同學值班。
<link href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/markdown_views-d7a94ec6ab.css" rel="stylesheet">
<link href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/style-49037e4d27.css" rel="stylesheet">
</div>