Skip to content

Commit 7ad16af

Browse files
committed
Adding active, dropped, and tapped for #3
1 parent 719d83c commit 7ad16af

File tree

4 files changed

+200
-38
lines changed

4 files changed

+200
-38
lines changed

adafruit_adxl34x.py

Lines changed: 152 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -58,36 +58,41 @@
5858
_ADXL345_MG2G_MULTIPLIER = 0.004 # 4mg per lsb
5959
_STANDARD_GRAVITY = 9.80665 # earth standard gravity
6060

61-
_ADXL345_REG_DEVID = const(0x00) # Device ID
62-
_ADXL345_REG_THRESH_TAP = const(0x1D) # Tap threshold
63-
_ADXL345_REG_OFSX = const(0x1E) # X-axis offset
64-
_ADXL345_REG_OFSY = const(0x1F) # Y-axis offset
65-
_ADXL345_REG_OFSZ = const(0x20) # Z-axis offset
66-
_ADXL345_REG_DUR = const(0x21) # Tap duration
67-
_ADXL345_REG_LATENT = const(0x22) # Tap latency
68-
_ADXL345_REG_WINDOW = const(0x23) # Tap window
69-
_ADXL345_REG_THRESH_ACT = const(0x24) # Activity threshold
70-
_ADXL345_REG_THRESH_INACT = const(0x25) # Inactivity threshold
71-
_ADXL345_REG_TIME_INACT = const(0x26) # Inactivity time
72-
_ADXL345_REG_ACT_INACT_CTL = const(0x27) # Axis enable control for [in]activity detection
73-
_ADXL345_REG_THRESH_FF = const(0x28) # Free-fall threshold
74-
_ADXL345_REG_TIME_FF = const(0x29) # Free-fall time
75-
_ADXL345_REG_TAP_AXES = const(0x2A) # Axis control for single/double tap
76-
_ADXL345_REG_ACT_TAP_STATUS = const(0x2B) # Source for single/double tap
77-
_ADXL345_REG_BW_RATE = const(0x2C) # Data rate and power mode control
78-
_ADXL345_REG_POWER_CTL = const(0x2D) # Power-saving features control
79-
_ADXL345_REG_INT_ENABLE = const(0x2E) # Interrupt enable control
80-
_ADXL345_REG_INT_MAP = const(0x2F) # Interrupt mapping control
81-
_ADXL345_REG_INT_SOURCE = const(0x30) # Source of interrupts
82-
_ADXL345_REG_DATA_FORMAT = const(0x31) # Data format control
83-
_ADXL345_REG_DATAX0 = const(0x32) # X-axis data 0
84-
_ADXL345_REG_DATAX1 = const(0x33) # X-axis data 1
85-
_ADXL345_REG_DATAY0 = const(0x34) # Y-axis data 0
86-
_ADXL345_REG_DATAY1 = const(0x35) # Y-axis data 1
87-
_ADXL345_REG_DATAZ0 = const(0x36) # Z-axis data 0
88-
_ADXL345_REG_DATAZ1 = const(0x37) # Z-axis data 1
89-
_ADXL345_REG_FIFO_CTL = const(0x38) # FIFO control
90-
_ADXL345_REG_FIFO_STATUS = const(0x39) # FIFO status
61+
_REG_DEVID = const(0x00) # Device ID
62+
_REG_THRESH_TAP = const(0x1D) # Tap threshold
63+
_REG_OFSX = const(0x1E) # X-axis offset
64+
_REG_OFSY = const(0x1F) # Y-axis offset
65+
_REG_OFSZ = const(0x20) # Z-axis offset
66+
_REG_DUR = const(0x21) # Tap duration
67+
_REG_LATENT = const(0x22) # Tap latency
68+
_REG_WINDOW = const(0x23) # Tap window
69+
_REG_THRESH_ACT = const(0x24) # Activity threshold
70+
_REG_THRESH_INACT = const(0x25) # Inactivity threshold
71+
_REG_TIME_INACT = const(0x26) # Inactivity time
72+
_REG_ACT_INACT_CTL = const(0x27) # Axis enable control for [in]activity detection
73+
_REG_THRESH_FF = const(0x28) # Free-fall threshold
74+
_REG_TIME_FF = const(0x29) # Free-fall time
75+
_REG_TAP_AXES = const(0x2A) # Axis control for single/double tap
76+
_REG_ACT_TAP_STATUS = const(0x2B) # Source for single/double tap
77+
_REG_BW_RATE = const(0x2C) # Data rate and power mode control
78+
_REG_POWER_CTL = const(0x2D) # Power-saving features control
79+
_REG_INT_ENABLE = const(0x2E) # Interrupt enable control
80+
_REG_INT_MAP = const(0x2F) # Interrupt mapping control
81+
_REG_INT_SOURCE = const(0x30) # Source of interrupts
82+
_REG_DATA_FORMAT = const(0x31) # Data format control
83+
_REG_DATAX0 = const(0x32) # X-axis data 0
84+
_REG_DATAX1 = const(0x33) # X-axis data 1
85+
_REG_DATAY0 = const(0x34) # Y-axis data 0
86+
_REG_DATAY1 = const(0x35) # Y-axis data 1
87+
_REG_DATAZ0 = const(0x36) # Z-axis data 0
88+
_REG_DATAZ1 = const(0x37) # Z-axis data 1
89+
_REG_FIFO_CTL = const(0x38) # FIFO control
90+
_REG_FIFO_STATUS = const(0x39) # FIFO status
91+
_INT_SINGLE_TAP = const(0b01000000) # SINGLE_TAP bit
92+
_INT_DOUBLE_TAP = const(0b00100000) # DOUBLE_TAP bit
93+
_INT_ACT = const(0b00010000) # ACT bit
94+
_INT_INACT = const(0b00001000) # INACT bit
95+
_INT_FREE_FALL = const(0b00000100) # FREE_FALL bit
9196

9297
class DataRate: #pylint: disable=too-few-public-methods
9398
"""An enum-like class representing the possible data rates.
@@ -153,42 +158,148 @@ class ADXL345:
153158
:param address: The I2C device address for the sensor. Default is ``0x53``.
154159
155160
"""
156-
def __init__(self, i2c, address=_ADXL345_DEFAULT_ADDRESS):
161+
def __init__(self, i2c, address=_ADXL345_DEFAULT_ADDRESS, int1=None, int2=None):
157162

158163
self._i2c = i2c_device.I2CDevice(i2c, address)
159164
self._buffer = bytearray(6)
160165
# set the 'measure' bit in to enable measurement
161-
self._write_register_byte(_ADXL345_REG_POWER_CTL, 0x08)
166+
self._write_register_byte(_REG_POWER_CTL, 0x08)
167+
self._int1 = int1
168+
self._int2 = int2
169+
self._tap = None
162170

163171
@property
164172
def acceleration(self):
165173
"""The x, y, z acceleration values returned in a 3-tuple in m / s ^ 2."""
166-
x, y, z = unpack('<hhh', self._read_register(_ADXL345_REG_DATAX0, 6))
174+
x, y, z = unpack('<hhh', self._read_register(_REG_DATAX0, 6))
167175
x = x * _ADXL345_MG2G_MULTIPLIER * _STANDARD_GRAVITY
168176
y = y * _ADXL345_MG2G_MULTIPLIER * _STANDARD_GRAVITY
169177
z = z * _ADXL345_MG2G_MULTIPLIER * _STANDARD_GRAVITY
170178
return (x, y, z)
171179

180+
@property
181+
def tapped(self):
182+
"""
183+
True if a tap was detected recently. Whether it's looking for a single or double tap is
184+
determined by the tap param on ``tap_parameters``.
185+
186+
"""
187+
if self._int2 and not self._int2.value:
188+
return False
189+
190+
interrupt_source_register = self._read_clear_interrupt_source()
191+
if self._tap == 1:
192+
return interrupt_source_register & _INT_SINGLE_TAP > 0
193+
if self._tap == 2:
194+
return interrupt_source_register & _INT_DOUBLE_TAP > 0
195+
196+
return False
197+
198+
@property
199+
def dropped(self):
200+
"""True if the sensor was in freefall"""
201+
202+
return self._read_clear_interrupt_source() & _INT_FREE_FALL > 0
203+
204+
@property
205+
def active(self):
206+
"""True if the sensor has seen acceleration above the threshold set with
207+
``active_parameters``."""
208+
return self._read_clear_interrupt_source() & _INT_ACT > 0
209+
210+
def active_parameters(self, threshold=0x5):
211+
"""
212+
The activity detection parameters.
213+
214+
:param int threshold: The value that acceleration on any axis must exceed to\
215+
register as active. The scale factor is 62.5 mg/LSB.
216+
217+
"""
218+
self._write_register_byte(_REG_INT_ENABLE, 0x0) # disable interrupts for setup
219+
self._write_register_byte(_REG_ACT_INACT_CTL, 0b01110000) # enable activity on X,Y,Z
220+
self._write_register_byte(_REG_THRESH_ACT, threshold)
221+
self._write_register_byte(_REG_INT_ENABLE, _INT_ACT) # Inactive interrupt only
222+
223+
def dropped_parameters(self, threshold=0x5, time=0x14):
224+
"""
225+
Freefall detection parameters:
226+
227+
:param int threshold: The value that acceleration on all axes must be under to\
228+
register as dropped. The scale factor is 62.5 mg/LSB.
229+
230+
:param int time: The amount of time that acceleration on all axes must be less than\
231+
``threshhold`` to register as dropped. The scale factor is 5 ms/LSB. Values between 100 ms\
232+
and 350 ms (0x14 to 0x46) are recommended.
233+
"""
234+
self._write_register_byte(_REG_INT_ENABLE, 0x0) # disable interrupts for setup
235+
self._write_register_byte(_REG_THRESH_FF, threshold)
236+
self._write_register_byte(_REG_TIME_FF, time)
237+
self._write_register_byte(_REG_INT_ENABLE, 0b00000100) # FREE_FALL interrupt only
238+
239+
def tap_parameters(self, tap, threshold, *, time_duration=10, time_latency=20, time_window=255):
240+
"""
241+
The tap detection parameters.
242+
243+
:param int tap: 0 to disable tap detection, 1 to detect only single taps, and 2 to detect\
244+
only double taps.
245+
246+
:param int threshold: A threshold for the tap detection. The scale factor is 62.5 mg/LSB\
247+
The higher the value the less sensitive the detection. This changes based on the\
248+
accelerometer range.
249+
250+
:param int time_duration: This caps the duration of the impulse above ``threshhold``.\
251+
Anything above ``time_duration`` won't register as a tap. The scale factor is 625 µs/LSB
252+
253+
:param int time_latency(double tap only): The length of time after the initial impulse falls below\
254+
``threshold`` to start the window looking for a second impulse.\
255+
The scale factor is 1.25 ms/LSB.
256+
257+
:param int time_window(double tap only): The length of the window in which to look for a\
258+
second tap. The scale factor is 1.25 ms/LSB
259+
"""
260+
if tap == 0:
261+
self._write_register_byte(_REG_INT_ENABLE, 0x0) # disable all interrupts
262+
self._write_register_byte(_REG_TAP_AXES, 0x0) # disable all axes for tap
263+
return
264+
self._write_register_byte(_REG_INT_ENABLE, 0x0) # disable interrupts for setup
265+
self._write_register_byte(_REG_TAP_AXES, 0b00000111) # enable X, Y, Z axes for tap
266+
self._write_register_byte(_REG_THRESH_TAP, threshold)
267+
self._write_register_byte(_REG_DUR, time_duration)
268+
269+
self._tap = tap # save to determine which register to check later
270+
if tap == 1:
271+
if self._int2:
272+
self._write_register_byte(_REG_INT_MAP, _INT_SINGLE_TAP) # send SINGLE_TAP to INT2
273+
self._write_register_byte(_REG_INT_ENABLE, _INT_SINGLE_TAP) # DOUBLE_TAP interrupt only
274+
elif tap == 2:
275+
self._write_register_byte(_REG_LATENT, time_latency)
276+
self._write_register_byte(_REG_WINDOW, time_window)
277+
if self._int2:
278+
self._write_register_byte(_REG_INT_MAP, _INT_DOUBLE_TAP) # send DOUBLE_TAP to INT2
279+
self._write_register_byte(_REG_INT_ENABLE, _INT_DOUBLE_TAP) # DOUBLE_TAP interrupt only
280+
else:
281+
raise ValueError("tap must be 0 to disable, 1 for single tap, or 2 for double tap")
282+
172283
@property
173284
def data_rate(self):
174285
"""The data rate of the sensor."""
175-
rate_register = unpack("<b", self._read_register(_ADXL345_REG_BW_RATE, 1))[0]
286+
rate_register = unpack("<b", self._read_register(_REG_BW_RATE, 1))[0]
176287
return rate_register & 0x0F
177288

178289
@data_rate.setter
179290
def data_rate(self, val):
180-
self._write_register_byte(_ADXL345_REG_BW_RATE, val)
291+
self._write_register_byte(_REG_BW_RATE, val)
181292

182293
@property
183294
def range(self):
184295
"""The measurement range of the sensor."""
185-
range_register = unpack("<b", self._read_register(_ADXL345_REG_DATA_FORMAT, 1))[0]
296+
range_register = unpack("<b", self._read_register(_REG_DATA_FORMAT, 1))[0]
186297
return range_register & 0x03
187298

188299
@range.setter
189300
def range(self, val):
190301
# read the current value of the data format register
191-
format_register = unpack("<b", self._read_register(_ADXL345_REG_DATA_FORMAT, 1))[0]
302+
format_register = unpack("<b", self._read_register(_REG_DATA_FORMAT, 1))[0]
192303

193304
# clear the bottom 4 bits and update the data rate
194305
format_register &= ~0x0F
@@ -198,7 +309,10 @@ def range(self, val):
198309
format_register |= 0x08
199310

200311
# write the updated values
201-
self._write_register_byte(_ADXL345_REG_DATA_FORMAT, format_register)
312+
self._write_register_byte(_REG_DATA_FORMAT, format_register)
313+
314+
def _read_clear_interrupt_source(self):
315+
return unpack("<b", self._read_register(_REG_INT_SOURCE, 1))[0]
202316

203317
def _read_register(self, register, length):
204318
self._buffer[0] = register & 0xFF

examples/adxl34x_active_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import time
2+
import audioio
3+
import board
4+
import busio
5+
import digitalio
6+
import adafruit_adxl34x
7+
8+
i2c = busio.I2C(board.SCL, board.SDA)
9+
10+
accelerometer = adafruit_adxl34x.ADXL345(i2c)
11+
accelerometer.active_parameters()
12+
while True:
13+
print("%f %f %f"%accelerometer.acceleration)
14+
15+
print("Active: %s"%accelerometer.active)
16+
time.sleep(0.5)

examples/adxl34x_dropped_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import time
2+
import audioio
3+
import board
4+
import busio
5+
import digitalio
6+
import adafruit_adxl34x
7+
8+
i2c = busio.I2C(board.SCL, board.SDA)
9+
10+
accelerometer = adafruit_adxl34x.ADXL345(i2c)
11+
accelerometer.dropped_parameters()
12+
while True:
13+
print("%f %f %f"%accelerometer.acceleration)
14+
15+
print("Dropped: %s"%accelerometer.dropped)
16+
time.sleep(0.5)

examples/adxl34x_tapped_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import time
2+
import audioio
3+
import board
4+
import busio
5+
import digitalio
6+
import adafruit_adxl34x
7+
8+
i2c = busio.I2C(board.SCL, board.SDA)
9+
10+
accelerometer = adafruit_adxl34x.ADXL345(i2c)
11+
accelerometer.tap_parameters(1, 10)
12+
while True:
13+
print("%f %f %f"%accelerometer.acceleration)
14+
15+
print("Tapped: %s"%accelerometer.tapped)
16+
time.sleep(0.5)

0 commit comments

Comments
 (0)