MPU6050是一种6轴运动处理组件,由InvenSense公司推出。它集成了3轴陀螺仪和3轴加速度传感器,以及一个数字运动处理器(DMP: Digital Motion Processor)。
MPU6050的特点包括:
- 自带数字运动处理(DMP),可以输出6轴或9轴(需外接磁传感器)姿态解算数据。
- 集成可程序控制,测量范围为±250、±500、±1000与±2000°/sec的3轴角速度感测器(陀螺仪)。
- 集成可程序控制,范围为±2g、±4g、±8g和16g的3轴加速度传感器。
- 自带数字温度传感器。
总的来说,MPU6050是一个强大的运动处理组件,常用于各种需要姿态解算的应用中,如无人机、机器人、VR/AR设备等。
最近我手上也是有一块MPU6050,用它来做惯性导航,但是数据的噪音有点多,使用起来不是很理想。我在树莓派4B上也使用过,在arduino中也使用过,这里介绍一下在RP2040中读取MPU6050的数据。一般MPU6050都采用I2C的通信方式,从机地址为0x68,
代码片段:
MPU6050.py,我这里不是完整的MPU6050的库,只包含读取六轴数据以及温度信息的部分:
import machine
class accel():
def __init__(self, i2c, addr=0x68):
self.iic = i2c
self.addr = addr
#self.iic.start()
self.iic.writeto(self.addr, bytearray([107, 0]))
#self.iic.stop()
def get_raw_values(self):
#self.iic.start()
a = self.iic.readfrom_mem(self.addr, 0x3B, 14)
#self.iic.stop()
return a
def get_ints(self):
b = self.get_raw_values()
c = []
for i in b:
c.append(i)
return c
def bytes_toint(self, firstbyte, secondbyte):
if not firstbyte & 0x80:
return firstbyte << 8 | secondbyte
return - (((firstbyte ^ 255) << 8) | (secondbyte ^ 255) + 1)
def get_values(self):
raw_ints = self.get_raw_values()
vals = {}
vals["AcX"] = self.bytes_toint(raw_ints[0], raw_ints[1])
vals["AcY"] = self.bytes_toint(raw_ints[2], raw_ints[3])
vals["AcZ"] = self.bytes_toint(raw_ints[4], raw_ints[5])
vals["Tmp"] = self.bytes_toint(raw_ints[6], raw_ints[7]) / 340.00 + 36.53
vals["GyX"] = self.bytes_toint(raw_ints[8], raw_ints[9])
vals["GyY"] = self.bytes_toint(raw_ints[10], raw_ints[11])
vals["GyZ"] = self.bytes_toint(raw_ints[12], raw_ints[13])
return vals # returned in range of Int16
# -32768 to 32767
def sleep(self):
self.iic.start()
self.iic.writeto_mem(self.addr, 0x6B, b'\x40')
self.iic.stop()
def wakeup(self):
from time import sleep
self.iic.start()
self.iic.writeto_mem(self.addr, 0x6B, b'\x80')
self.iic.stop()
sleep(0.05)
self.iic.start()
self.iic.writeto_mem(self.addr, 0x68, b'\x07')
self.iic.stop()
sleep(0.05)
self.iic.start()
self.iic.writeto_mem(self.addr, 0x68, b'\x00')
self.iic.stop()
sleep(0.05)
self.iic.start()
self.iic.writeto_mem(self.addr, 0x6B, b'\x00')
self.iic.stop()
def val_test(self): # ONLY FOR TESTING! Also, fast reading sometimes crashes IIC
from time import sleep
while 1:
print(self.get_values())
sleep(0.05)
下面是主程序main.py:
我这里得到的都是最原始的数据,具体转换角度都是可以通过公式计算的(可以参考其他的博客,这里不多叙述),如果觉得噪声太多,后续是可以通过卡尔曼滤波等方法进行处理,效果会更好。
from machine import I2C,Pin
import MPU6050
import math
import time
i2c = I2C(0,sda=Pin(0),scl=Pin(1),freq=400000)#PICO中的GPIO0和GPIO1
addr = i2c.scan()
accel = MPU6050.accel(i2c)
#对加速度计的数值进行处理,可以得到加速度
def a_output(data):
data = data/16384
return data
#对陀螺仪的数值进行处理,可以得到角度
def g_output(data):
data = data/131
return data
while True:
accel_dict = accel.get_values()
time.sleep(0.1)
print(accel_dict)
运行结果如下: