Skip to content

Commit 16aaf9b

Browse files
committed
added tap detection
1 parent 78164eb commit 16aaf9b

File tree

1 file changed

+101
-13
lines changed

1 file changed

+101
-13
lines changed

adafruit_lsm303_accel.py

Lines changed: 101 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,10 @@
5353
from micropython import const
5454
from adafruit_bus_device.i2c_device import I2CDevice
5555
from adafruit_register.i2c_struct import UnaryStruct
56-
from adafruit_register.i2c_bit import RWBit
56+
from adafruit_register.i2c_bit import RWBit, ROBit
5757
from adafruit_register.i2c_bits import RWBits
5858
from adafruit_register.i2c_struct_array import StructArray
5959

60-
6160
__version__ = "0.0.0-auto.0"
6261
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LSM303_Accel.git"
6362

@@ -67,6 +66,8 @@
6766
_ID = const(0xD4) # (0b11010100)
6867

6968
# Accelerometer registers
69+
70+
_REG_ACCEL_WHO_AM_I = const(0x0F)
7071
_REG_ACCEL_CTRL_REG1_A = const(0x20)
7172
_REG_ACCEL_CTRL_REG2_A = const(0x21)
7273
_REG_ACCEL_CTRL_REG3_A = const(0x22)
@@ -99,7 +100,6 @@
99100
_REG_ACCEL_TIME_WINDOW_A = const(0x3D)
100101
_REG_ACCEL_ACT_THS_A = const(0x3E)
101102
_REG_ACCEL_ACT_DUR_A = const(0x3F)
102-
_REG_ACCEL_WHO_AM_I = const(0x0F)
103103

104104
# Conversion constants
105105
_LSM303ACCEL_MG_LSB = 16704.0 # magic!
@@ -140,36 +140,124 @@ class LSM303_Accel:
140140
# This reduces memory allocations but means the code is not re-entrant or
141141
# thread safe!
142142
_chip_id = UnaryStruct(_REG_ACCEL_WHO_AM_I, "B")
143-
_int2_int1_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 6, 1)
144-
_int2_int2_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 5, 1)
143+
_int2_int1_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 6)
144+
_int2_int2_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 5)
145+
_int1_latching = RWBit(_REG_ACCEL_CTRL_REG5_A, 3)
146+
_int2_latching = RWBit(_REG_ACCEL_CTRL_REG5_A, 1)
147+
_bdu = RWBit(_REG_ACCEL_CTRL_REG4_A, 7)
145148

146-
_int2_activity_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 3, 1)
147-
_int_pin_active_low = RWBit(_REG_ACCEL_CTRL_REG6_A, 1, 1)
149+
_int2_activity_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 3)
150+
_int_pin_active_low = RWBit(_REG_ACCEL_CTRL_REG6_A, 1)
148151

149152
_act_threshold = UnaryStruct(_REG_ACCEL_ACT_THS_A, "B")
150153
_act_duration = UnaryStruct(_REG_ACCEL_ACT_DUR_A, "B")
151154

152-
_data_rate = RWBits(4, _REG_ACCEL_CTRL_REG1_A, 4, 1)
153-
_enable_xyz = RWBits(3, _REG_ACCEL_CTRL_REG1_A, 0, 1)
155+
_data_rate = RWBits(4, _REG_ACCEL_CTRL_REG1_A, 4)
156+
_enable_xyz = RWBits(3, _REG_ACCEL_CTRL_REG1_A, 0)
154157
_raw_accel_data = StructArray(_REG_ACCEL_OUT_X_L_A, "<h", 3)
155158

156-
_low_power = RWBit(_REG_ACCEL_CTRL_REG1_A, 3, 1)
157-
_high_resolution = RWBit(_REG_ACCEL_CTRL_REG4_A, 3, 1)
159+
_low_power = RWBit(_REG_ACCEL_CTRL_REG1_A, 3)
160+
_high_resolution = RWBit(_REG_ACCEL_CTRL_REG4_A, 3)
158161

162+
_range = RWBits(2, _REG_ACCEL_CTRL_REG4_A, 4)
159163

160-
_range = RWBits(2, _REG_ACCEL_CTRL_REG4_A, 4, 1)
164+
# filter _REG_ACCEL_CTRL_REG2_A
165+
# CTRL_REG5_A boot (7)
166+
_int1_src = UnaryStruct(_REG_ACCEL_INT1_SOURCE_A, "B")
167+
_tap_src = UnaryStruct(_REG_ACCEL_CLICK_SRC_A, "B")
168+
169+
_tap_interrupt_enable = RWBit(_REG_ACCEL_CTRL_REG3_A, 7, 1)
170+
_tap_config = UnaryStruct(_REG_ACCEL_CLICK_CFG_A, "B")
171+
_tap_interrupt_active = ROBit(_REG_ACCEL_CLICK_SRC_A, 6, 1)
172+
_tap_threshold = UnaryStruct(_REG_ACCEL_CLICK_THS_A, "B")
173+
_tap_time_limit = UnaryStruct(_REG_ACCEL_TIME_LIMIT_A, "B")
174+
_tap_time_latency = UnaryStruct(_REG_ACCEL_TIME_LATENCY_A, "B")
175+
_tap_time_window = UnaryStruct(_REG_ACCEL_TIME_WINDOW_A, "B")
161176

162-
_BUFFER = bytearray(6)
163177

178+
179+
_BUFFER = bytearray(6)
164180
def __init__(self, i2c):
165181
self._accel_device = I2CDevice(i2c, _ADDRESS_ACCEL)
166182
self.i2c_device = self._accel_device
167183
#self._write_u8(self._accel_device, _REG_ACCEL_CTRL_REG1_A, 0x27) # Enable the accelerometer
168184
self._data_rate = 2
169185
self._enable_xyz = 0b111
186+
self._int1_latching = True
187+
self._int2_latching = True
188+
self._bdu = True
189+
190+
# self._write_register_byte(_REG_CTRL5, 0x80)
191+
# time.sleep(0.01) # takes 5ms
170192
self._cached_mode = 0
171193
self._cached_range = 0
172194

195+
def set_tap(self, tap, threshold, *,
196+
time_limit=10, time_latency=20, time_window=255, tap_cfg=None):
197+
"""
198+
The tap detection parameters.
199+
.. note:: Tap related registers are called ``CLICK_`` in the datasheet.
200+
:param int tap: 0 to disable tap detection, 1 to detect only single
201+
taps, and 2 to detect only double taps.
202+
:param int threshold: A threshold for the tap detection. The higher the value
203+
the less sensitive the detection. This changes based on
204+
the accelerometer range. Good values are 5-10 for 16G,
205+
10-20 for 8G, 20-40 for 4G, and 40-80 for 2G.
206+
:param int time_limit: TIME_LIMIT register value (default 10).
207+
:param int time_latency: TIME_LATENCY register value (default 20).
208+
:param int time_window: TIME_WINDOW register value (default 255).
209+
:param int click_cfg: CLICK_CFG register value.
210+
"""
211+
if (tap < 0 or tap > 2) and tap_cfg is None:
212+
raise ValueError('Tap must be 0 (disabled), 1 (single tap), or 2 (double tap)!')
213+
if threshold > 127 or threshold < 0:
214+
raise ValueError('Threshold out of range (0-127)')
215+
216+
217+
if tap == 0 and tap_cfg is None:
218+
# Disable click interrupt.
219+
self._tap_interrupt_enable = False
220+
self._tap_config = 0
221+
return
222+
223+
self._tap_interrupt_enable = True
224+
225+
if tap_cfg is None:
226+
if tap == 1:
227+
tap_cfg = 0x15 # Turn on all axes & singletap.
228+
if tap == 2:
229+
tap_cfg = 0x2A # Turn on all axes & doubletap.
230+
# Or, if a custom tap configuration register value specified, use it.
231+
self._tap_config = tap_cfg
232+
233+
self._tap_threshold = threshold # why and?
234+
self._tap_time_limit = time_limit
235+
self._tap_time_latency = time_latency
236+
self._tap_time_window = time_window
237+
238+
@property
239+
def tapped(self):
240+
"""
241+
True if a tap was detected recently. Whether its a single tap or double tap is
242+
determined by the tap param on ``set_tap``. ``tapped`` may be True over
243+
multiple reads even if only a single tap or single double tap occurred if the
244+
interrupt (int) pin is not specified.
245+
The following example uses ``i2c`` and specifies the interrupt pin:
246+
.. code-block:: python
247+
import adafruit_lis3dh
248+
import digitalio
249+
i2c = busio.I2C(board.SCL, board.SDA)
250+
int1 = digitalio.DigitalInOut(board.D11) # pin connected to interrupt
251+
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)
252+
lis3dh.range = adafruit_lis3dh.RANGE_8_G
253+
"""
254+
tap_src = self._tap_src
255+
# print("tap_src: %s"%bin(tap_src))
256+
# print("int1_src: %s"%bin(self._int1_src))
257+
# if tap_src & 0b1000000 > 0:
258+
# print("TAPPED!")
259+
return tap_src & 0b1000000 > 0
260+
173261
@property
174262
def raw_acceleration(self):
175263
"""The raw accelerometer sensor values.

0 commit comments

Comments
 (0)