Micropython——九轴传感器(MPU6050)的使用及算法(二)
前言:
在上篇文章中,简单地实现了九轴传感器(MPU6050)的获取加速度、角速度以及温度的数值。但是,我们知道,对于MPU6050来说,其提供的数据会夹杂有严重的噪音,在芯片处理静止状态时数据摆动都可能超过2%。除了噪音以外,其数据还含有偏移现象。这对于我们来说是无法忍受的。所以,我们要先对其生成的数据偏移进行校准,然后我们在处理其噪音现象。
1、对数据偏移进行校准
如何校准是我们所要关注的重点。对于数据来说,比较准确的偏移量要对大量的数据进行统计才能获知,数据量越大越准,但统计的时间也就越慢。一般校准可以在每次启动系统时进行,那么你应当在准确度和启动时间之间做一个权衡。
更改后的驱动代码实现
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):
self.AcX_high_bite = self.get_raw_values[0]
self.AcX_low_bite = self.get_raw_values[1]
self.AcX = self.bytes_toint(self.AcX_high_bite,self.AcX_low_bite)
self.AcX_calibre = self.AcX - self.AcX_calibration
self.AcY_high_bite = self.get_raw_values[2]
self.AcY_low_bite = self.get_raw_values[3]
self.AcY = self.bytes_toint(self.AcY_high_bite,self.AcY_low_bite)
self.AcY_calibre = self.AcY - self.AcY_calibration
self.AcZ_high_bite = self.get_raw_values[4]
self.AcZ_low_bite = self.get_raw_values[5]
self.AcZ = self.bytes_toint(self.AcZ_high_bite,self.AcZ_low_bite)
self.AcZ_calibre = self.AcZ - self.AcZ_calibration
self.temp_high_byte = self.get_raw_values[6]
self.temp_low_byte = self.get_raw_values[7]
self.temp = self.bytes_toint( self.temp_high_byte,self.temp_low_byte)
self.temperature = self.temp / 340.00 + 36.53
self.GyX_high_byte = self.captures[8]
self.GyX_low_byte = self.captures[9]
self.GyX = self.bytes_to_int(self.GyX_high_byte, self.GyX_low_byte)#100ms陀螺仪输出一次值
self.GyX_calibre = self.GyX - self.GyX_calibration
self.GyY_high_byte = self.captures[10]
self.GyY_low_byte = self.captures[11]
self.GyY = self.bytes_to_int(self.GyY_high_byte, self.GyY_low_byte)#100ms陀螺仪输出一次值
self.GyY_calibre = self.GyY - self.GyY_calibration
self.GyZ_high_byte = self.captures[12]
self.GyZ_low_byte = self.captures[13]
self.GyZ = self.bytes_to_int(self.GyZ_high_byte, self.GyZ_low_byte)#100ms陀螺仪输出一次值
self.GyZ_calibre = self.GyZ - self.GyZ_calibration
# -32768 to 32767
#移位合并
def bytes_toint(self, firstbyte, secondbyte):
if not firstbyte & 0x80:
return firstbyte << 8 | secondbyte
return - (((firstbyte ^ 255) << 8) | (secondbyte ^ 255) + 1)
#读取100次求出平均值,第一次初始化时求出陀螺仪6轴初始值,不动的情况下,理论初始值等于0
def calibration(self):
i = 0
self.GyX_calibration = 0
self.GyY_calibration = 0
self.GyZ_calibration = 0
self.AcX_calibration = 0
self.AcY_calibration = 0
self.AcZ_calibration = 0
while i < 100:
self.i2c.readform_mem_into(self.address,0x3B,14)
self.get_values()
self.AcX_calibration += self.AcX
self.AcY_calibration += self.AcY
self.AcZ_calibration += self.AcZ
self.GyX_calibration += self.GyX
self.GyY_calibration += self.GyY
self.GyZ_calibration += self.GyZ
i+=1
time.sleep(0.1)
self.GyX_calibration /= 100
self.GyY_calibration /= 100
self.GyZ_calibration /= 100
self.AcX_calibration /= 100
self.AcY_calibration /= 100
self.AcZ_calibration /= 100
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)
这里我们对于每次对100份数据进行处理,以达到处理其数据偏移的问题。