天天看點

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

一. 引言

現在智能手機的功能已經非常強大,除了基礎的通信功能外,測位測速,空間角度等資料的測量也非常友善,這線上路導航,地圖,體感遊戲等應用中十分重要。不知你是否想過,智能裝置是如何擷取到其所在的空間狀态與加速度等資料的呢?MPU6050就是提供這類資料測量的一種傳感器子產品。

首先,通過樹莓派來讀取MPU6050傳感器子產品的資料并不複雜,MPU60X0是一款擴充性極強的數字運動處理器,我們本次實驗使用的是封裝好的功能子產品,如下圖所示:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

MPU6050晶片本身有24個引腳,每邊有6個引腳,功能較多,引腳功能與定位如下圖所示:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

關于MPU6050的進階用法,可以通過檢視晶片手冊擷取,本篇部落格我們着重與在樹莓派上對其進行應用。我們隻需要關注所使用的子產品的8個引腳即可。

二. 連線與準備工作

本次實驗我們使用的子產品有8個引腳,隻需要使用其中4個引腳即可實作功能。對于樹莓派I2C協定總線的應用,本系列部落格之前已經有非常多的實驗有過應用。首先連接配接傳感器子產品與樹莓派如下表:

傳感器子產品 樹莓派
VCC +5V
GND
SCL
SDA

開始使用I2C總線前,莫忘了開啟樹莓派的I2C功能,對I2C總線用法如果不太了解,可以閱讀以下部落格:

https://my.oschina.net/u/2340880/blog/5142788

連線完成後,在樹莓派的終端輸入如下指令可以檢視已經連接配接的I2C裝置:

sudo i2cdetect -y 1









           

如果連接配接無誤,終端輸出結果将如下圖所示:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

可以看到,圖中顯示的68即為我們所連接配接的傳感器的位址。

下面,是時候了解下MPU6050傳感器該如何使用了,我們知道,通過I2C總線,我們可以友善的讀取裝置中某個寄存器的資料,也可以向裝置的某個寄存器寫入資料,是以,使用MPU6050傳感器的核心是了解其中寄存器的使用方法。我們将以使用到的幾個寄存器為例做介紹,完整的寄存器用法可以從晶片手冊上得到。

1. 電源管理寄存器

電源管理寄存器的位址為107,對應十六進制數0x6b,它是一個8位的寄存器,其中第4位為保留位不能使用,功能如下:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

DECIVE_RESET: 這一位的作用是重置傳感器,将傳感器内部所有寄存器複位為初始狀态,複位完成後,這一位會清零。

SLEEP: 睡眠控制位,當此位為1時,傳感器将處于睡眠模式。需要注意,傳感器啟動時預設是睡眠模式,我們需要手動将其喚醒。

CYCLE:當裝置設定為非睡眠模式時,即SLEEP位不為1,此為如果設定為1,傳感器将處于循環模式,會按照寄存器108設定的速度進行資料循環采樣。

TEMP_DIS:是否禁用溫度傳感器,設定為1時,禁用溫度傳感器。

CLKSEL:3位無符号數值,用來指令時鐘源。

對于CLKSEL選項,其設定方式如下:

CLKSEL值 意義
使用内部的8MHz的振蕩器
1 使用陀螺儀X軸的頻率
2 使用陀螺儀Y軸的頻率
3
4 使用外部的32.768kHz頻率
5 使用外部19.2MHz頻率
6 保留值
7 停止時鐘并使振蕩器保持複位狀态

2. 陀螺儀資料寄存器

陀螺儀資料寄存器的位址為67到72,共48個二進制位,如下:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

這些寄存器都是隻讀的,不能寫入。

67和68寄存器存儲16位資料,為陀螺儀X軸的測量資料。其中68寄存器存儲低8位,67寄存器存儲高8位。

69和70寄存器存儲16位資料,為陀螺儀Y軸的測量資料。其中70寄存器存儲低8位,69寄存器存儲高8位。

71和72寄存器存儲16位資料,為陀螺儀Z軸的測量資料。其中72寄存器存儲低8位,71寄存器存儲高8位。

需要注意,從這些寄存器取出的資料都是原始資料,要得到真正的陀螺儀測量的旋轉角度,需要進行轉換,其轉換的機關與總量程有關,量程在寄存器27進行配置。

3. 陀螺儀配置寄存器

陀螺儀配置寄存器的位址為27,是一個可讀可寫的寄存器,如下:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

XG\_ST,YG\_ST與ZG\_ST這3位用來設定陀螺儀執行自檢。FS\_SEL用來設定陀螺儀的量程範圍,低3位為保留位,無需使用。FS_SEL可設定的量程範圍如下:

FS_SEL 量程範圍 靈敏度參數
±250 °/s 131
±500 °/s 65.5
±1000 °/s 32.8
±2000 °/s 16.4

對于不同的量程範圍,我們擷取到原始資料後,需要除以對應的靈敏度參數才能得到最終的陀螺儀資料。

4. 加速計資料寄存器

加速計資料寄存器的位址為59到64,共48個二進制位,如下:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

其使用方法與陀螺儀資料寄存器類似,同樣需要在寄存器28來對加速計進行配置與設定量程,通過量程對應的靈敏度來計算得到真實的加速度值。

5. 加速計配置寄存器

陀螺儀配置寄存器的位址為28,是一個可讀可寫的寄存器,如下:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

XA\_ST,YA\_ST,ZA\_ST都是自檢執行控制位,AFS\_SEL用來設定量程,其與靈敏度對應關系如下:

AFS_SEL
±2 16384
±4g 8192
±8g 4096
±16g 2048

6. 溫度資料寄存器

溫度資料寄存器的位址為65到66,共16個二進制位,如下:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

對于測量到的溫度資料為有符号數,需要采用如下的計算公式得到真實的攝氏度資料:

攝氏溫度 = TEMP_OUT / 340 + 36.53

除此之外,還有許多功能傳感器,如采樣率配置等,有需要可以從晶片手冊查到。

三. 編寫代碼

完成了前面的基礎準備工作,編寫代碼擷取傳感器子產品的資料則非常容易,示例代碼如下:

#coding:utf-8

import smbus
import math
import time

# 電源控制寄存器位址
power_regist = 0x6b

# I2C子產品初始化
bus = smbus.SMBus(1)
# 外接I2C裝置的位址
address = 0x68

# 封裝一些讀取資料的功能函數

# 讀取一個字長度的資料(16位)
def readWord(adr):
    high = bus.read_byte_data(address, adr)
    low = bus.read_byte_data(address, adr+1)
    val = (high << 8) + low
    return val

# 将讀取到的資料轉換為原碼 (有符号數本身是采用補碼方式存儲的)
def readWordReal(adr):
    val = readWord(adr)
    x = 0xffff
    # 首位為1 表示是負數
    if (val >= 0x8000):
        # 求原碼
        return -((x - val)+1)
    else:
        return val

# 已知加速度求角度值
def dist(a, b):
    return math.sqrt((a*a)+(b*b))

def getRotationX(x, y, z):
    radians = math.atan2(y, dist(x,z))
    return math.degrees(radians)

def getRotationY(x, y, z):
    radians = math.atan2(x, dist(y,z))
    return math.degrees(radians)

# 設定電源模式
bus.write_byte_data(address, power_regist, 0)


while True:
    time.sleep(0.5)
    print("螺旋儀資料-----------")
    gyroX = readWordReal(0x43)
    gyroY = readWordReal(0x45)
    gyroZ = readWordReal(0x47)

    print("X軸陀螺儀原始資料:", gyroX, "X軸每秒旋轉度數:", gyroX/131)
    print("Y軸陀螺儀原始資料:", gyroY, "Y軸每秒旋轉度數:", gyroY/131)
    print("Z軸陀螺儀原始資料:", gyroZ, "Z軸每秒旋轉度數:", gyroZ/131)

    print("加速度資料----------")
    accelX = readWordReal(0x3b)
    accelY = readWordReal(0x3d)
    accelZ = readWordReal(0x3f)

    print("X軸加速度原始資料:", accelX, "X軸加速度:", accelX/16384)
    print("Y軸加速度原始資料:", accelY, "Y軸加速度:", accelY/16384)
    print("Z軸加速度原始資料:", accelZ, "Z軸加速度:", accelZ/16384)

    print("攝氏溫度資料--------")
    temp = readWordReal(0x41)
    print("溫度原始資料:", temp, "攝氏度:", temp/340 + 36.53)

    print("旋轉家角度資料-------")
    print("X軸旋轉度數:", getRotationX(accelX/16384, accelY/16384, accelZ/16384))
    print("Y軸旋轉度數:", getRotationX(accelX/16384, accelY/16384, accelZ/16384))



           

在樹莓派上運作上面代碼,效果如下圖所示:

一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用一起玩轉樹莓派(18)——MPU6050陀螺儀加速度傳感器子產品應用

專注技術,懂的熱愛,願意分享,做個朋友

QQ:316045346

繼續閱讀