MicroPython 硬體 I2C 驅動 MPU6050 - RaspberryPi Pico 示例

笨蛋队长要变强發表於2024-11-23

MPU6050 暫存器內容和地址

  • 陀螺儀資料輸出暫存器(共6個暫存器,地址為0x43-0x48)
  • 加速度感測器資料輸出暫存器(6個,地址為0x3B-0x40)
  • 溫度感測器資料輸出暫存器(0x41-0x42)

Who am I 裝置驗證

MPU6050 的預設裝置地址為 0x68,其儲存 Who am I 的暫存器地址為 0x75,而該暫存器的值則為 0x68

who = i2c.readfrom_mem(0x68, 0x75, 1) # 獲取whoami暫存器一位元組值
print('0x' + ''.join(['{:02x}'.format(byte) for byte in who]))

MPU6050 基礎類構建

from machine import Pin, I2C
from math import atan
import utime
 
_MPU6050_ADDRESS = 0x68 # MPU6050 裝置地址

_PWR_MGMT_1 = 0x6B # 電源管理 1
_SMPLRT_DIV = 0x19 # 分頻取樣暫存器

_CONFIG = 0x1A # 配置暫存器
_GYRO_CONFIG = 0x1B # 陀螺儀配置暫存器
_ACCEL_CONFIG = 0x1C # 加速度計配置暫存器

# 加速度暫存器
ACCEL_XOUT_H = 0x3B
ACCEL_XOUT_L = 0x3C
ACCEL_YOUT_H = 0x3D
ACCEL_YOUT_L = 0x3E
ACCEL_ZOUT_H = 0x3F
ACCEL_ZOUT_L = 0x40

# 溫度暫存器
TEMP_OUT_H = 0x41
TEMP_OUT_L = 0x42

# 角速度暫存器
GYRO_XOUT_H = 0x43
GYRO_XOUT_L = 0x44
GYRO_YOUT_H = 0x45
GYRO_YOUT_L = 0x46
GYRO_ZOUT_H = 0x47
GYRO_ZOUT_L = 0x48

class MPU6050(object):
    
    def __init__(self, I2C, addr=_MPU6050_ADDRESS):
        
        self.i2c = I2C # I2C線路
        self.addr = addr # MPU6050地址
        
        # 初始化資料
        self.temp = None
        self.accel = None
        self.gyro = None
        
        # 喚醒MPU6050裝置
        self.i2c.writeto_mem(self.addr, _PWR_MGMT_1, bytes([0x00]))
        utime.sleep_ms(100)
        # 初始化配置暫存器
        self.i2c.writeto_mem(self.addr, _SMPLRT_DIV,   bytes([0x07])) # 分頻設定
        self.i2c.writeto_mem(self.addr, _CONFIG,       bytes([0x00])) # 感測器配置
        self.i2c.writeto_mem(self.addr, _GYRO_CONFIG,  bytes([0x00])) # 陀螺儀配置
        self.i2c.writeto_mem(self.addr, _ACCEL_CONFIG, bytes([0x00])) # 加速度配置
    
    def _read_data(self, addressH, addressL):
        highData = self.i2c.readfrom_mem(self.addr, addressH, 1)[0]
        lowData  = self.i2c.readfrom_mem(self.addr, addressL, 1)[0]
        rawData = highData << 8 | lowData
        if rawData > 32768:
            rawData = rawData - 65536
        return rawData
    
    def get_temp(self):
        self.temp = self._read_data(TEMP_OUT_H, TEMP_OUT_L) / 340.0 + 36.53
        return self.temp
    
    def get_accel(self):
        accel_x = self._read_data(ACCEL_XOUT_H, ACCEL_XOUT_L) / 16384.0
        accel_y = self._read_data(ACCEL_YOUT_H, ACCEL_YOUT_L) / 16384.0
        accel_z = self._read_data(ACCEL_ZOUT_H, ACCEL_ZOUT_L) / 16384.0
        self.accel = (accel_x, accel_y, accel_z)
        return self.accel
        
    def get_gyro(self):
        gyro_x = self._read_data(GYRO_XOUT_H, GYRO_XOUT_L) / 131.0
        gyro_y = self._read_data(GYRO_YOUT_H, GYRO_YOUT_L) / 131.0
        gyro_z = self._read_data(GYRO_ZOUT_H, GYRO_ZOUT_L) / 131.0
        self.gyro = (gyro_x, gyro_y, gyro_z)
        return self.gyro

關於姿態解算和濾波這裡不做處理,該文只關注於原資料的獲取和解析

MPU6050 使用例程

from machine import Pin, PWM, I2C, Timer
from mpu6050 import MPU6050
import utime

def main():
    while True:
		accel = MPU6050.get_accel()
	    gyro  = MPU6050.get_gyro()
	    temp  = MPU6050.get_temp()
	    
	    utime.sleep_ms(100)

if __name__ == "__main__":

    # 初始化裝置
    MPU6050 = MPU6050(I2C(1, scl=Pin(15), sda=Pin(14), freq=400000)) # 初始化MPU6050物件
    
    main()

  • 相關資源:micropython-IMU
    • micropython-IMU/micropython-mpu9x50 - 感測器資料獲取
    • micropython-IMU/micropython-fusion - 感測器資料後處理
  • 相關資源:ThisisG - MPU6050-I2C-Python-Class
  • 相關資源:Lezgend - MPU6050-MicroPython
  • 參考文件:Micropython——九軸感測器(MPU6050)的使用及演算法(一) - Xa_L
  • 參考文件:Micropython——九軸感測器(MPU6050)的使用及演算法(二) - Xa_L
  • 參考文件:Interfacing MPU6050 with Raspberry Pi Pico & MicroPython
  • 參考文件:使用 MicroPython 與 Raspberry Pi Pico 進行介面MPU6050

相關文章