|
# C.LEBOCQ 02/2020
|
|
# MicroPython library for the MPU6886 imu ( M5StickC / ATOM Matrix )
|
|
# Based on https://github.com/m5stack/M5StickC/blob/master/src/utility/MPU6886.cpp
|
|
|
|
from machine import I2C
|
|
from time import sleep
|
|
|
|
MPU6886_ADDRESS = const(0x68)
|
|
MPU6886_WHOAMI = const(0x75)
|
|
MPU6886_ACCEL_INTEL_CTRL = const(0x69)
|
|
MPU6886_SMPLRT_DIV = const(0x19)
|
|
MPU6886_INT_PIN_CFG = const(0x37)
|
|
MPU6886_INT_ENABLE = const(0x38)
|
|
MPU6886_ACCEL_XOUT_H = const(0x3B)
|
|
MPU6886_ACCEL_XOUT_L = const(0x3C)
|
|
MPU6886_ACCEL_YOUT_H = const(0x3D)
|
|
MPU6886_ACCEL_YOUT_L = const(0x3E)
|
|
MPU6886_ACCEL_ZOUT_H = const(0x3F)
|
|
MPU6886_ACCEL_ZOUT_L = const(0x40)
|
|
|
|
MPU6886_TEMP_OUT_H = const(0x41)
|
|
MPU6886_TEMP_OUT_L = const(0x42)
|
|
|
|
MPU6886_GYRO_XOUT_H = const(0x43)
|
|
MPU6886_GYRO_XOUT_L = const(0x44)
|
|
MPU6886_GYRO_YOUT_H = const(0x45)
|
|
MPU6886_GYRO_YOUT_L = const(0x46)
|
|
MPU6886_GYRO_ZOUT_H = const(0x47)
|
|
MPU6886_GYRO_ZOUT_L = const(0x48)
|
|
|
|
MPU6886_USER_CTRL = const(0x6A)
|
|
MPU6886_PWR_MGMT_1 = const(0x6B)
|
|
MPU6886_PWR_MGMT_2 = const(0x6C)
|
|
MPU6886_CONFIG = const(0x1A)
|
|
MPU6886_GYRO_CONFIG = const(0x1B)
|
|
MPU6886_ACCEL_CONFIG = const(0x1C)
|
|
MPU6886_ACCEL_CONFIG2 = const(0x1D)
|
|
MPU6886_FIFO_EN = const(0x23)
|
|
|
|
#consts for Acceleration & Resolution scale
|
|
AFS_2G = const(0x00)
|
|
AFS_4G = const(0x01)
|
|
AFS_8G = const(0x02)
|
|
AFS_16G = const(0x03)
|
|
|
|
GFS_250DPS = const(0x00)
|
|
GFS_500DPS = const(0x01)
|
|
GFS_1000DPS = const(0x02)
|
|
GFS_2000DPS = const(0x03)
|
|
|
|
class MPU6886():
|
|
|
|
def __init__(self, i2c, Gscale = GFS_2000DPS, Ascale = AFS_8G):
|
|
self.i2c = i2c
|
|
self.Gscale = Gscale
|
|
self.Ascale = Ascale
|
|
if self.init():
|
|
self.setAccelFsr(Ascale)
|
|
self.setGyroFsr(Gscale)
|
|
|
|
# sleep in ms
|
|
def sleepms(self,n):
|
|
sleep(n / 1000)
|
|
|
|
# set I2C reg (1 byte)
|
|
def setReg(self, reg, dat):
|
|
self.i2c.writeto(MPU6886_ADDRESS, bytearray([reg, dat]))
|
|
|
|
# get I2C reg (1 byte)
|
|
def getReg(self, reg):
|
|
self.i2c.writeto(MPU6886_ADDRESS, bytearray([reg]))
|
|
t = self.i2c.readfrom(MPU6886_ADDRESS, 1)
|
|
return t[0]
|
|
|
|
# get n reg
|
|
def getnReg(self, reg, n):
|
|
self.i2c.writeto(MPU6886_ADDRESS, bytearray([reg]))
|
|
t = self.i2c.readfrom(MPU6886_ADDRESS, n)
|
|
return t
|
|
|
|
def init(self):
|
|
tempdata = self.getReg(MPU6886_WHOAMI)
|
|
if tempdata != 0x19:
|
|
return False
|
|
self.sleepms(1)
|
|
regdata = 0x00
|
|
self.setReg(MPU6886_PWR_MGMT_1, regdata)
|
|
self.sleepms(10)
|
|
regdata = (0x01<<7)
|
|
self.setReg(MPU6886_PWR_MGMT_1, regdata)
|
|
self.sleepms(10)
|
|
regdata = (0x01<<0)
|
|
self.setReg(MPU6886_PWR_MGMT_1, regdata)
|
|
self.sleepms(10)
|
|
regdata = 0x10
|
|
self.setReg(MPU6886_ACCEL_CONFIG, regdata)
|
|
self.sleepms(1)
|
|
regdata = 0x18
|
|
self.setReg(MPU6886_GYRO_CONFIG, regdata)
|
|
self.sleepms(1)
|
|
regdata = 0x01
|
|
self.setReg(MPU6886_CONFIG, regdata)
|
|
self.sleepms(1)
|
|
regdata = 0x05
|
|
self.setReg(MPU6886_SMPLRT_DIV, regdata)
|
|
self.sleepms(1)
|
|
regdata = 0x00
|
|
self.setReg(MPU6886_INT_ENABLE, regdata)
|
|
self.sleepms(1)
|
|
regdata = 0x00
|
|
self.setReg(MPU6886_ACCEL_CONFIG2, regdata)
|
|
self.sleepms(1)
|
|
regdata = 0x00
|
|
self.setReg(MPU6886_USER_CTRL, regdata)
|
|
self.sleepms(1)
|
|
regdata = 0x00
|
|
self.setReg(MPU6886_FIFO_EN, regdata)
|
|
self.sleepms(1)
|
|
regdata = 0x22
|
|
self.setReg(MPU6886_INT_PIN_CFG, regdata)
|
|
self.sleepms(1)
|
|
regdata = 0x01
|
|
self.setReg(MPU6886_INT_ENABLE, regdata)
|
|
self.sleepms(100)
|
|
self.getGres()
|
|
self.getAres()
|
|
return True
|
|
|
|
def getGres(self):
|
|
if self.Gscale == GFS_250DPS:
|
|
self.gRes = 250.0 / 32768.0
|
|
elif self.Gscale == GFS_500DPS:
|
|
self.gRes = 500.0/32768.0
|
|
elif self.Gscale == GFS_1000DPS:
|
|
self.gRes = 1000.0/32768.0
|
|
elif self.Gscale == GFS_2000DPS:
|
|
self.gRes = 2000.0/32768.0
|
|
else:
|
|
self.gRes = 250.0/32768.0
|
|
|
|
def getAres(self):
|
|
if self.Ascale == AFS_2G:
|
|
self.aRes = 2.0/32768.0
|
|
elif self.Ascale == AFS_4G:
|
|
self.aRes = 4.0/32768.0
|
|
elif self.Ascale == AFS_8G:
|
|
self.aRes = 8.0/32768.0
|
|
elif self.Ascale == AFS_16G:
|
|
self.aRes = 16.0/32768.0
|
|
else:
|
|
self.aRes = 2.0/32768.0
|
|
|
|
def getAccelAdc(self):
|
|
buf = self.getnReg(MPU6886_ACCEL_XOUT_H,6)
|
|
|
|
ax = (buf[0]<<8) | buf[1]
|
|
ay = (buf[2]<<8) | buf[3]
|
|
az = (buf[4]<<8) | buf[5]
|
|
return ax,ay,az
|
|
|
|
def getAccelData(self):
|
|
ax,ay,az = self.getAccelAdc()
|
|
if ax > 32768:
|
|
ax -= 65536
|
|
if ay > 32768:
|
|
ay -= 65536
|
|
if az > 32768:
|
|
az -= 65536
|
|
ax *= self.aRes
|
|
ay *= self.aRes
|
|
az *= self.aRes
|
|
return ax,ay,az
|
|
|
|
def getGyroAdc(self):
|
|
buf = self.getnReg(MPU6886_GYRO_XOUT_H,6)
|
|
gx = (buf[0]<<8) | buf[1]
|
|
gy = (buf[2]<<8) | buf[3]
|
|
gz = (buf[4]<<8) | buf[5]
|
|
return gx,gy,gz
|
|
|
|
def getGyroData(self):
|
|
gx,gy,gz = self.getGyroAdc()
|
|
if gx > 32768:
|
|
gx -= 65536
|
|
if gy > 32768:
|
|
gy -= 65536
|
|
if gz > 32768:
|
|
gz -= 65536
|
|
gx *= self.gRes
|
|
gy *= self.gRes
|
|
gz *= self.gRes
|
|
return gx, gy, gz
|
|
|
|
def getTempAdc(self):
|
|
buf = self.getnReg(MPU6886_TEMP_OUT_H,2)
|
|
return (buf[0]<<8) | buf[1]
|
|
|
|
def getTempData(self):
|
|
return self.getTempAdc() / 326.8 + 25.0
|
|
|
|
def setGyroFsr(self,scale):
|
|
regdata = (scale<<3)
|
|
self.setReg(MPU6886_GYRO_CONFIG, regdata)
|
|
self.sleepms(10)
|
|
self.Gscale = scale
|
|
self.getGres()
|
|
|
|
def setAccelFsr(self,scale):
|
|
regdata = (scale<<3)
|
|
self.setReg(MPU6886_ACCEL_CONFIG, regdata)
|
|
self.sleepms(10)
|
|
self.Ascale = scale
|
|
self.getAres() |