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份数据进行处理,以达到处理其数据偏移的问题。

posted @ 2022-07-06 08:40  Xa_L  阅读(572)  评论(0编辑  收藏  举报