73 lines
2.3 KiB
Python
73 lines
2.3 KiB
Python
"""
|
|
SC7A20
|
|
|
|
Micropython library for the SC7A20 Accelerometer
|
|
=================================================
|
|
#Preliminary composition 20240312
|
|
|
|
@dahanzimin From the Mixly Team
|
|
"""
|
|
import time
|
|
from math import atan,sqrt,degrees
|
|
from micropython import const
|
|
|
|
SC7A20_ADDRESS = const(0x19)
|
|
SC7A20_REG_ID = const(0x0F)
|
|
SC7A20_REG_CTRL1 = const(0x20)
|
|
SC7A20_REG_CTRL2 = const(0x21)
|
|
SC7A20_REG_CTRL3 = const(0x22)
|
|
SC7A20_REG_CTRL4 = const(0x23)
|
|
SC7A20_REG_DATA = const(0x28)
|
|
|
|
#2g 4g 8g 16g
|
|
_Range_X = (1024,512,256,128)
|
|
|
|
class SC7A20:
|
|
|
|
def __init__(self, i2c_bus, set_range=2, front=False):
|
|
self._device = i2c_bus
|
|
self._address = SC7A20_ADDRESS
|
|
self._range = set_range #default 8g range
|
|
self._front = front
|
|
|
|
if self._rreg(SC7A20_REG_ID) != 0x11:
|
|
raise AttributeError("Cannot find a SC7A20")
|
|
self._wreg(SC7A20_REG_CTRL1, 0X77) #400HZ,xyz使能
|
|
self._wreg(SC7A20_REG_CTRL2, 0X00) #禁止高通滤波模式
|
|
self._wreg(SC7A20_REG_CTRL3, 0X00) #禁止中断
|
|
self._wreg(SC7A20_REG_CTRL4, 0X00 | set_range << 4) #连续更新,设置量程
|
|
|
|
def _wreg(self, reg, val):
|
|
'''Write memory address'''
|
|
self._device.writeto_mem(self._address,reg,val.to_bytes(1, 'little'))
|
|
|
|
def _rreg(self, reg):
|
|
'''Read memory address'''
|
|
return self._device.readfrom_mem(self._address, reg, 1)[0]
|
|
|
|
def u2s(self, n):
|
|
return n if n < (1 << 7) else n - (1 << 8)
|
|
|
|
@property
|
|
def getdata(self):
|
|
x_acc = ((self.u2s(self._rreg(SC7A20_REG_DATA + 1)) << 8 | self._rreg(SC7A20_REG_DATA + 0)) >> 4) / _Range_X[self._range]
|
|
y_acc = ((self.u2s(self._rreg(SC7A20_REG_DATA + 3)) << 8 | self._rreg(SC7A20_REG_DATA + 2)) >> 4) / _Range_X[self._range]
|
|
z_acc = ((self.u2s(self._rreg(SC7A20_REG_DATA + 5)) << 8 | self._rreg(SC7A20_REG_DATA + 4)) >> 4) / _Range_X[self._range]
|
|
return (-x_acc, y_acc, z_acc, None) if self._front else (x_acc, y_acc, z_acc, None)
|
|
|
|
def acceleration(self):
|
|
return self.getdata[0:3]
|
|
|
|
def strength(self):
|
|
from math import sqrt
|
|
return sqrt(self.getdata[0]**2+self.getdata[1]**2+self.getdata[2]**2)
|
|
|
|
def temperature(self):
|
|
return self.getdata[3]
|
|
|
|
def eulerangles(self,upright=False):
|
|
x, y, z = self.acceleration()
|
|
pitch = degrees(atan(z / sqrt(x ** 2 + y ** 2))) if upright else degrees(atan(y / sqrt(x ** 2 + z ** 2)))
|
|
roll = degrees(atan(x / sqrt(y ** 2 + z ** 2)))
|
|
return round(pitch,2),round(roll,2)
|