Skip to content

Commit 5ba3e3e

Browse files
committed
Added range and data_ready interrupt parameters
1 parent 9fb7385 commit 5ba3e3e

File tree

3 files changed

+149
-8
lines changed

3 files changed

+149
-8
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ repos:
1818
- id: end-of-file-fixer
1919
- id: trailing-whitespace
2020
- repo: https://github.com/pycqa/pylint
21-
rev: v2.17.4
21+
rev: v3.2.6
2222
hooks:
2323
- id: pylint
2424
name: pylint (library code)

adafruit_adxl37x.py

Lines changed: 124 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import adafruit_adxl34x
3434

3535
try:
36-
from typing import Tuple, Optional
36+
from typing import Tuple, Optional, Dict
3737

3838
# This is only needed for typing
3939
import busio
@@ -48,20 +48,66 @@
4848
_ADXL347_MULTIPLIER: float = 0.049 # 49mg per lsb
4949
_STANDARD_GRAVITY: float = 9.80665 # earth standard gravity
5050

51+
_REG_DEVID: int = const(0x00) # Device ID
52+
_REG_THRESH_TAP: int = const(0x1D) # Tap threshold
53+
_REG_OFSX: int = const(0x1E) # X-axis offset
54+
_REG_OFSY: int = const(0x1F) # Y-axis offset
55+
_REG_OFSZ: int = const(0x20) # Z-axis offset
56+
_REG_DUR: int = const(0x21) # Tap duration
57+
_REG_LATENT: int = const(0x22) # Tap latency
58+
_REG_WINDOW: int = const(0x23) # Tap window
59+
_REG_THRESH_ACT: int = const(0x24) # Activity threshold
60+
_REG_THRESH_INACT: int = const(0x25) # Inactivity threshold
61+
_REG_TIME_INACT: int = const(0x26) # Inactivity time
62+
_REG_ACT_INACT_CTL: int = const(0x27) # Axis enable control for [in]activity detection
63+
_REG_THRESH_FF: int = const(0x28) # Free-fall threshold
64+
_REG_TIME_FF: int = const(0x29) # Free-fall time
65+
_REG_TAP_AXES: int = const(0x2A) # Axis control for single/double tap
66+
_REG_ACT_TAP_STATUS: int = const(0x2B) # Source for single/double tap
67+
_REG_BW_RATE: int = const(0x2C) # Data rate and power mode control
68+
_REG_POWER_CTL: int = const(0x2D) # Power-saving features control
69+
_REG_INT_ENABLE: int = const(0x2E) # Interrupt enable control
70+
_REG_INT_MAP: int = const(0x2F) # Interrupt mapping control
71+
_REG_INT_SOURCE: int = const(0x30) # Source of interrupts
72+
_REG_DATA_FORMAT: int = const(0x31) # Data format control
5173
_REG_DATAX0: int = const(0x32) # X-axis data 0
5274
_REG_DATAX1: int = const(0x33) # X-axis data 1
5375
_REG_DATAY0: int = const(0x34) # Y-axis data 0
5476
_REG_DATAY1: int = const(0x35) # Y-axis data 1
5577
_REG_DATAZ0: int = const(0x36) # Z-axis data 0
5678
_REG_DATAZ1: int = const(0x37) # Z-axis data 1
79+
_REG_FIFO_CTL: int = const(0x38) # FIFO control
80+
_REG_FIFO_STATUS: int = const(0x39) # FIFO status
81+
_INT_DATA_READY: int = const(0b10000000) # DATA_READY bit
82+
_INT_SINGLE_TAP: int = const(0b01000000) # SINGLE_TAP bit
83+
_INT_DOUBLE_TAP: int = const(0b00100000) # DOUBLE_TAP bit
84+
_INT_ACT: int = const(0b00010000) # ACT bit
85+
_INT_INACT: int = const(0b00001000) # INACT bit
86+
87+
88+
# _INT_FREE_FALL: int = const(0b00000100) # FREE_FALL bit, unused in ADXL375
5789

5890

5991
class DataRate(adafruit_adxl34x.DataRate): # pylint: disable=too-few-public-methods
6092
"""Stub class for data rate."""
6193

6294

63-
class Range(adafruit_adxl34x.Range): # pylint: disable=too-few-public-methods
64-
"""Stub class for range."""
95+
class Range: # pylint: disable=too-few-public-methods
96+
"""An enum-like class representing the possible measurement ranges in +/- G.
97+
98+
Possible values are:
99+
100+
- ``Range.RANGE_200_G``
101+
- ``Range.RANGE_100_G``
102+
- ``Range.RANGE_50_G``
103+
- ``Range.RANGE_25_G``
104+
105+
"""
106+
107+
RANGE_200_G: int = const(0b11) # +/- 200g
108+
RANGE_100_G: int = const(0b10) # +/- 100g
109+
RANGE_50_G: int = const(0b01) # +/- 50g
110+
RANGE_25_G: int = const(0b00) # +/- 25g (default value)
65111

66112

67113
class ADXL375(adafruit_adxl34x.ADXL345):
@@ -114,10 +160,81 @@ def acceleration(self) -> Tuple[int, int, int]:
114160

115161
@property
116162
def range(self) -> int:
117-
"""Range is fixed. Updating the range is not implemented."""
118-
raise NotImplementedError("Range not implemented. ADXL375 is fixed at 200G.")
163+
"""The measurement range of the sensor."""
164+
range_register = self._read_register_unpacked(_REG_DATA_FORMAT)
165+
return range_register & 0x03
119166

120167
@range.setter
121168
def range(self, val: int) -> None:
122-
"""Range is fixed. Updating the range is not implemented."""
123-
raise NotImplementedError("Range not implemented. ADXL375 is fixed at 200G.")
169+
# read the current value of the data format register
170+
format_register = self._read_register_unpacked(_REG_DATA_FORMAT)
171+
172+
# update the range
173+
format_register |= val
174+
175+
# Make sure that the FULL-RES bit is enabled for range scaling
176+
format_register |= 0x08
177+
178+
# write the updated values
179+
self._write_register_byte(_REG_DATA_FORMAT, format_register)
180+
181+
@property
182+
def events(self) -> Dict[str, bool]:
183+
"""
184+
:attr:`events` will return a dictionary with a key for each
185+
event type that has been enabled.
186+
The possible keys are:
187+
188+
+------------+----------------------------------------------------------------------------+
189+
| Key | Description |
190+
+============+============================================================================+
191+
| ``tap`` | True if a tap was detected recently. Whether it's looking for a single |
192+
| | or double tap is determined by the tap param of `enable_tap_detection` |
193+
+------------+----------------------------------------------------------------------------+
194+
| ``motion`` | True if the sensor has seen acceleration above the threshold |
195+
| | set with `enable_motion_detection`. |
196+
+------------+----------------------------------------------------------------------------+
197+
|``data_ready``| True if the sensor has data to be read. Can be used for more precise |
198+
| | timing if reading many samples |
199+
+------------+----------------------------------------------------------------------------+
200+
201+
202+
"""
203+
204+
interrupt_source_register = self._read_clear_interrupt_source()
205+
206+
self._event_status.clear()
207+
208+
for event_type, value in self._enabled_interrupts.items():
209+
if event_type == "motion":
210+
self._event_status[event_type] = (
211+
interrupt_source_register & _INT_ACT > 0
212+
)
213+
if event_type == "tap":
214+
if value == 1:
215+
self._event_status[event_type] = (
216+
interrupt_source_register & _INT_SINGLE_TAP > 0
217+
)
218+
else:
219+
self._event_status[event_type] = (
220+
interrupt_source_register & _INT_DOUBLE_TAP > 0
221+
)
222+
if event_type == "data_ready":
223+
self._event_status[event_type] = (
224+
interrupt_source_register & _INT_DATA_READY > 0
225+
)
226+
227+
return self._event_status
228+
229+
def enable_data_ready_interrupt(self):
230+
"""
231+
Enable Data Ready interrupt for precise data timing
232+
"""
233+
active_interrupts = self._read_register_unpacked(_REG_INT_ENABLE)
234+
235+
self._write_register_byte(_REG_INT_ENABLE, 0x0) # disable interrupts for setup
236+
237+
# add DATA_READY to the active interrupts and set them to re-enable
238+
active_interrupts |= _INT_DATA_READY
239+
self._write_register_byte(_REG_INT_ENABLE, active_interrupts)
240+
self._enabled_interrupts["data_ready"] = True

examples/adxl37x_data_ready.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# SPDX-FileCopyrightText: 2022 Kattni Rembor for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
4+
import board
5+
import digitalio
6+
import adafruit_adxl37x
7+
8+
i2c = board.STEMMA_I2C() # uses board.SCL and board.SDA
9+
accelerometer = adafruit_adxl37x.ADXL375(i2c)
10+
11+
interrupt = digitalio.DigitalInOut(board.GP3) # Set interrupt dio pin
12+
13+
print("Accelerometer starting...")
14+
accelerometer.data_rate = (
15+
accelerometer.DataRate.RATE_800_HZ
16+
) # Set Data Rate of accelerometer
17+
accelerometer.range = adafruit_adxl37x.Range.RANGE_200_G # Set Full Data Range 200g
18+
accelerometer.enable_data_ready_interrupt() # Enable Data Ready Interrupt
19+
20+
while True:
21+
if interrupt.value:
22+
# ADXL375 interrupt pin stays HIGH until data is read, so simply reading the logic state
23+
# is sufficient instead of having to catch the rising edge.
24+
print("%f %f %f m/s^2" % accelerometer.acceleration)

0 commit comments

Comments
 (0)