Skip to content

Commit d8e5f5e

Browse files
committed
add LSM6DS33 drive
1 parent ebcaa5d commit d8e5f5e

File tree

2 files changed

+248
-0
lines changed

2 files changed

+248
-0
lines changed

‎sensor/LSM6DS33/READMD.md‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
**LSM6DS33**, ST's always-on 3D accelerometer and 3D gyroscope sensor.
2+
3+
4+
5+
## example
6+
7+
Normal mode
8+
9+
```python
10+
from lsm6ds33 import LSM6DS33
11+
from machine import Pin, I2C
12+
13+
i2c = I2C(1, freq=400000)
14+
gyr = LSM6DS33(i2c)
15+
gyr.a()
16+
gyr.g()
17+
```
18+
19+
20+
21+
IRQ mode
22+
23+
```python
24+
from lsm6ds33 import LSM6DS33
25+
from machine import Pin, I2C
26+
27+
i2c = I2C(1, freq=400000)
28+
gyr = LSM6DS33(i2c)
29+
30+
def GYR_IRQ(t):
31+
pyb.LED(1).toggle()
32+
print('A:', gyr.a_raw())
33+
34+
gyr.wakeup_mode(True, Pin('PA6'), GYR_IRQ)
35+
36+
```
37+

‎sensor/LSM6DS33/lsm6ds33.py‎

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# LSM6DS33: ST's always-on 3D accelerometer and 3D gyroscope micropython drive
2+
# ver: 1.0
3+
# License: MIT
4+
# Author: shaoziyang (shaoziyang@mail.micropython.org.cn)
5+
# v1.0 2019.5
6+
7+
LSM6DS33_ORIENT_CFG_G = const(0x0B)
8+
LSM6DS33_INT1_CTRL = const(0x0D)
9+
LSM6DS33_INT2_CTRL = const(0x0E)
10+
LSM6DS33_CTRL1_XL = const(0x10)
11+
LSM6DS33_CTRL2_G = const(0x11)
12+
LSM6DS33_CTRL3_C = const(0x12)
13+
LSM6DS33_CTRL4_C = const(0x13)
14+
LSM6DS33_CTRL5_C = const(0x14)
15+
LSM6DS33_CTRL6_C = const(0x15)
16+
LSM6DS33_CTRL7_G = const(0x16)
17+
LSM6DS33_CTRL8_XL = const(0x17)
18+
LSM6DS33_CTRL9_XL = const(0x18)
19+
LSM6DS33_CTRL10_C = const(0x19)
20+
LSM6DS33_WAKE_UP_SRC = const(0x1B)
21+
LSM6DS33_STATUS = const(0x1E)
22+
LSM6DS33_OUT_TEMP_L = const(0x20)
23+
LSM6DS33_OUTX_L_G = const(0x22)
24+
LSM6DS33_OUTY_L_G = const(0x24)
25+
LSM6DS33_OUTZ_L_G = const(0x26)
26+
LSM6DS33_OUTX_L_XL = const(0x28)
27+
LSM6DS33_OUTY_L_XL = const(0x2A)
28+
LSM6DS33_OUTZ_L_XL = const(0x2C)
29+
LSM6DS33_TAP_CFG = const(0x58)
30+
LSM6DS33_WAKE_UP_THS = const(0x5B)
31+
LSM6DS33_WAKE_UP_DUR = const(0x5C)
32+
LSM6DS33_MD1_CFG = const(0x5E)
33+
LSM6DS33_MD2_CFG = const(0x5F)
34+
35+
LSM6DS33_SCALEA = ('2g', '16g', '4g', '8g')
36+
LSM6DS33_COEA = (1, 8, 2, 4)
37+
LSM6DS33_SCALEG = ('250', '125', '500', '', '1000', '', '2000')
38+
LSM6DS33_COEG = (2, 1, 4, 0, 8, 0, 16)
39+
40+
class LSM6DS33():
41+
def __init__(self, i2c, addr = 0x6B):
42+
self.i2c = i2c
43+
self.addr = addr
44+
self.tb = bytearray(1)
45+
self.rb = bytearray(1)
46+
self.irq_v = [[0, 0, 0], [0, 0, 0]]
47+
self._power = True
48+
self._power_a = 0x10
49+
self._power_g = 0x10
50+
self._wakeup_mode = 0
51+
if self.getreg(15) != 0x69:
52+
raise Exception('sensor ID error')
53+
# RESET
54+
self.setreg(LSM6DS33_CTRL3_C, 1)
55+
# ODR_XL=6 FS_XL=0
56+
self.setreg(LSM6DS33_CTRL1_XL, 0x60)
57+
# ODR_G=4 FS=250
58+
self.setreg(LSM6DS33_CTRL2_G, 0x40)
59+
# BDU=1 IF_INC=1
60+
self.setreg(LSM6DS33_CTRL3_C, 0x44)
61+
self.setreg(LSM6DS33_CTRL8_XL, 0)
62+
# scale=2G 125dps
63+
self._scale_a = 0
64+
self._scale_g = 0
65+
66+
def int16(self, d):
67+
return d if d < 0x8000 else d - 0x10000
68+
69+
def setreg(self, reg, dat):
70+
self.tb[0] = dat
71+
self.i2c.writeto_mem(self.addr, reg, self.tb)
72+
73+
def getreg(self, reg):
74+
self.i2c.readfrom_mem_into(self.addr, reg, self.rb)
75+
return self.rb[0]
76+
77+
def get2reg(self, reg):
78+
return self.getreg(reg) + self.getreg(reg+1) * 256
79+
80+
def r_w_reg(self, reg, dat, mask):
81+
self.getreg(reg)
82+
self.rb[0] = (self.rb[0] & mask) | dat
83+
self.setreg(reg, self.rb[0])
84+
85+
def ax_raw(self):
86+
return self.int16(self.get2reg(LSM6DS33_OUTX_L_XL))
87+
88+
def ay_raw(self):
89+
return self.int16(self.get2reg(LSM6DS33_OUTY_L_XL))
90+
91+
def az_raw(self):
92+
return self.int16(self.get2reg(LSM6DS33_OUTZ_L_XL))
93+
94+
def gx_raw(self):
95+
return self.int16(self.get2reg(LSM6DS33_OUTX_L_G))
96+
97+
def gy_raw(self):
98+
return self.int16(self.get2reg(LSM6DS33_OUTY_L_G))
99+
100+
def gz_raw(self):
101+
return self.int16(self.get2reg(LSM6DS33_OUTZ_L_G))
102+
103+
def a_raw(self):
104+
self.irq_v[0][0] = self.ax_raw()
105+
self.irq_v[0][1] = self.ay_raw()
106+
self.irq_v[0][2] = self.az_raw()
107+
return self.irq_v[0]
108+
109+
def g_raw(self):
110+
self.irq_v[1][0] = self.gx_raw()
111+
self.irq_v[1][1] = self.gy_raw()
112+
self.irq_v[1][2] = self.gz_raw()
113+
return self.irq_v[1]
114+
115+
def t_raw(self):
116+
return self.get2reg(LSM6DS33_OUT_TEMP_L)
117+
118+
def temperature(self):
119+
try:
120+
return self.int16(self.t_raw())/16 + 25
121+
except MemoryError:
122+
return self.int16(self.t_raw())//16 + 25
123+
124+
def scale_a(self, dat=None):
125+
if dat is None:
126+
return LSM6DS33_SCALEA[self._scale_a]
127+
else:
128+
if type(dat) is str:
129+
if not dat in LSM6DS33_SCALEA: return
130+
self._scale_a = LSM6DS33_SCALEA.index(dat)
131+
else: return
132+
self.r_w_reg(LSM6DS33_CTRL1_XL, self._scale_a<<2, 0xF3)
133+
134+
def scale_g(self, dat=None):
135+
if (dat is None) or (dat == ''):
136+
return LSM6DS33_SCALEG[self._scale_g]
137+
else:
138+
if type(dat) is str:
139+
if not dat in LSM6DS33_SCALEG: return
140+
self._scale_g = LSM6DS33_SCALEG.index(dat)
141+
else: return
142+
self.r_w_reg(LSM6DS33_CTRL2_G, self._scale_g<<1, 0xF1)
143+
144+
def wakeup_mode(self, on = None, pin = None, callback = None, ths = 0x20):
145+
if on == None:
146+
return self._wakeup_mode
147+
if on == True:
148+
self._wakeup_mode = 1
149+
# ENABLE SLOPE_FDS
150+
self.r_w_reg(LSM6DS33_TAP_CFG, 0x10, 0xEF)
151+
# WAKE_UP_THS = 20
152+
self.setreg(LSM6DS33_WAKE_UP_THS, ths)
153+
# INT1_WU=1
154+
self.r_w_reg(LSM6DS33_MD1_CFG, 0x20, 0xDF)
155+
if pin != None and callback != None:
156+
pin.init(Pin.IN)
157+
pin.irq(handler=callback, trigger=Pin.IRQ_RISING)
158+
else:
159+
self._wakeup_mode = 0
160+
self.r_w_reg(LSM6DS33_TAP_CFG, 0x00, 0xEF)
161+
self.r_w_reg(LSM6DS33_MD1_CFG, 0x00, 0xDF)
162+
163+
def power(self, on=None):
164+
if on is None:
165+
return self._power
166+
else:
167+
self._power = on
168+
if on:
169+
self.r_w_reg(LSM6DS33_CTRL1_XL, self._power_a, 0x0F)
170+
self.r_w_reg(LSM6DS33_CTRL2_G, self._power_g, 0x0F)
171+
else:
172+
self._power_a = self.getreg(LSM6DS33_CTRL1_XL) & 0xF0
173+
self._power_g = self.getreg(LSM6DS33_CTRL2_G) & 0xF0
174+
self.r_w_reg(LSM6DS33_CTRL1_XL, 0, 0x0F)
175+
self.r_w_reg(LSM6DS33_CTRL2_G, 0, 0x0F)
176+
177+
def convert_a(self, a):
178+
return LSM6DS33_COEA[self._scale_a]*0.061*a
179+
180+
def convert_g(self, g):
181+
return LSM6DS33_COEG[self._scale_g]*4.375*g
182+
183+
def ax(self):
184+
self.convert_a(self.ax_raw())
185+
186+
def ay(self):
187+
self.convert_a(self.ay_raw())
188+
189+
def az(self):
190+
self.convert_a(self.az_raw())
191+
192+
def gx(self):
193+
self.convert_g(self.gx_raw())
194+
195+
def gy(self):
196+
self.convert_g(self.gy_raw())
197+
198+
def gz(self):
199+
self.convert_g(self.gz_raw())
200+
201+
def a(self):
202+
self.irq_v[0][0] = self.ax()
203+
self.irq_v[0][1] = self.ay()
204+
self.irq_v[0][2] = self.az()
205+
return self.irq_v[0]
206+
207+
def g(self):
208+
self.irq_v[1][0] = self.gx()
209+
self.irq_v[1][1] = self.gy()
210+
self.irq_v[1][2] = self.gz()
211+
return self.irq_v[1]

0 commit comments

Comments
 (0)