Skip to content

Stop mixing single and double tap detection. #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 37 additions & 39 deletions adafruit_lis3dh.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,10 @@ def __init__(self):

@property
def data_rate(self):
"""Get/set the data rate of the accelerometer. Can be DATA_RATE_400_HZ,
DATA_RATE_200_HZ, DATA_RATE_100_HZ, DATA_RATE_50_HZ, DATA_RATE_25_HZ,
DATA_RATE_10_HZ, DATA_RATE_1_HZ, DATA_RATE_POWERDOWN, DATA_RATE_LOWPOWER_1K6HZ,
or DATA_RATE_LOWPOWER_5KHZ.
"""
"""The data rate of the accelerometer. Can be DATA_RATE_400_HZ, DATA_RATE_200_HZ,
DATA_RATE_100_HZ, DATA_RATE_50_HZ, DATA_RATE_25_HZ, DATA_RATE_10_HZ,
DATA_RATE_1_HZ, DATA_RATE_POWERDOWN, DATA_RATE_LOWPOWER_1K6HZ, or
DATA_RATE_LOWPOWER_5KHZ."""
ctl1 = self._read_register_byte(REG_CTRL1)
return (ctl1 >> 4) & 0x0F

Expand All @@ -98,9 +97,8 @@ def data_rate(self, rate):

@property
def range(self):
"""Get/set the range of the accelerometer. Can be RANGE_2_G, RANGE_4_G,
RANGE_8_G, or RANGE_16_G.
"""
"""The range of the accelerometer. Can be RANGE_2_G, RANGE_4_G, RANGE_8_G, or
RANGE_16_G."""
ctl4 = self._read_register_byte(REG_CTRL4)
return (ctl4 >> 4) & 0x03

Expand Down Expand Up @@ -183,35 +181,35 @@ def read_adc_mV(self, adc): # pylint: disable=invalid-name
# y1 = 900
return 1800+(raw+32512)*(-900/65024)

def read_click_raw(self):
"""Read the raw click register byte value."""
return self._read_register_byte(REG_CLICKSRC)

def read_click(self):
"""Read a 2-tuple of bools where the first value is True if a single
click was detected and the second value is True if a double click was
detected.
"""
raw = self.read_click_raw()
return (raw & 0x10 > 0, raw & 0x20 > 0)

def set_click(self, click, threshold, *,
time_limit=10, time_latency=20, time_window=255, click_cfg=None):
"""Set the click detection parameters. Must specify at least:
click - Set to 0 to disable click detection, 1 to detect only single
clicks, and 2 to detect single & double clicks.
threshold - A threshold for the click detection. The higher the value
the less sensitive the detection. This changes based on
the accelerometer range. Good values are 5-10 for 16G,
10-20 for 8G, 20-40 for 4G, and 40-80 for 2G.
Optionally specify (see datasheet for meaning of these):
time_limit - Time limit register value (default 10).
time_latency - Time latency register value (default 20).
time_window - Time window register value (default 255).
"""
if (click < 0 or click > 2) and click_cfg is None:
raise ValueError('Click must be 0 (disabled), 1 (single click), or 2 (double click)!')
if click == 0 and click_cfg is None:
@property
def tapped(self):
"""True if a tap was detected recently. Whether its a single tap or double tap is
determined by the tap param on `set_tap`. This may be True over multiple reads
even if only a single tap or single double tap occurred."""
raw = self._read_register_byte(REG_CLICKSRC)
return raw & 0x40 > 0

def set_tap(self, tap, threshold, *,
time_limit=10, time_latency=20, time_window=255, click_cfg=None):
"""Set the tap detection parameters.

.. note:: Tap related registers are called CLICK_ in the datasheet.

:param int tap: 0 to disable tap detection, 1 to detect only single
taps, and 2 to detect only double taps.
:param int threshold: A threshold for the tap detection. The higher the value
the less sensitive the detection. This changes based on the accelerometer
range. Good values are 5-10 for 16G, 10-20 for 8G, 20-40 for 4G, and 40-80 for
2G.
:param int time_limit: TIME_LIMIT register value (default 10).
:param int time_latency: TIME_LATENCY register value (default 20).
:param int time_window: TIME_WINDOW register value (default 255).
:param int click_cfg: CLICK_CFG register value."""
if (tap < 0 or tap > 2) and click_cfg is None:
raise ValueError('Tap must be 0 (disabled), 1 (single tap), or 2 (double tap)!')
if threshold > 127 or threshold < 0:
raise ValueError('Threshold out of range (0-127)')
if tap == 0 and click_cfg is None:
# Disable click interrupt.
r = self._read_register_byte(REG_CTRL3)
r &= ~(0x80) # Turn off I1_CLICK.
Expand All @@ -224,9 +222,9 @@ def set_click(self, click, threshold, *,
if click_cfg is not None:
# Custom click configuration register value specified, use it.
self._write_register_byte(REG_CLICKCFG, click_cfg)
elif click == 1:
elif tap == 1:
self._write_register_byte(REG_CLICKCFG, 0x15) # Turn on all axes & singletap.
elif click == 2:
elif tap == 2:
self._write_register_byte(REG_CLICKCFG, 0x2A) # Turn on all axes & doubletap.
self._write_register_byte(REG_CLICKTHS, threshold)
self._write_register_byte(REG_TIMELIMIT, time_limit)
Expand Down
6 changes: 3 additions & 3 deletions examples/spinner.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ def get_position(self, delta):
lis3dh.range = ACCEL_RANGE
# Enable single click detection, but use a custom CLICK_CFG register value
# to only detect clicks on the X axis (instead of all 3 X, Y, Z axes).
lis3dh.set_click(1, TAP_THRESHOLD, click_cfg=0x01)
lis3dh.set_tap(1, TAP_THRESHOLD, click_cfg=0x01)
# Enable LIS3DH FIFO in stream mode. This reaches in to the LIS3DH library to
# call internal methods that change a few register values. This must be done
# AFTER calling set_click above because the set_click function also changes
# AFTER calling set_tap above because the set_tap function also changes
# REG_CTRL5.
# pylint: disable=protected-access
lis3dh._write_register_byte(adafruit_lis3dh.REG_CTRL5, 0b01001000)
Expand All @@ -85,7 +85,7 @@ def get_position(self, delta):
while True:
# Read the raw click detection register value and check if there was
# a click detected.
clicksrc = lis3dh.read_click_raw()
clicksrc = lis3dh._read_register_byte(adafruit_lis3dh.REG_CLICKSRC) # pylint: disable=protected-access
if clicksrc & 0b01000000 > 0:
# Click was detected! Quickly read 32 values from the accelerometer
# FIFO and look for the maximum magnitude values.
Expand Down
6 changes: 3 additions & 3 deletions examples/spinner_advanced.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,10 @@ def update(self, position, primary, secondary):
lis3dh.range = ACCEL_RANGE
# Enable single click detection, but use a custom CLICK_CFG register value
# to only detect clicks on the X axis (instead of all 3 X, Y, Z axes).
lis3dh.set_click(1, TAP_THRESHOLD, click_cfg=0x01)
lis3dh.set_tap(1, TAP_THRESHOLD, click_cfg=0x01)
# Enable LIS3DH FIFO in stream mode. This reaches in to the LIS3DH library to
# call internal methods that change a few register values. This must be done
# AFTER calling set_click above because the set_click function also changes
# AFTER calling set_tap above because the set_tap function also changes
# REG_CTRL5. The FIFO stream mode will keep track of the 32 last X,Y,Z accel
# readings in a FIFO buffer so they can be read later to see a history of
# recent acceleration. This is handy to look for the maximum/minimum impulse
Expand Down Expand Up @@ -219,7 +219,7 @@ def update(self, position, primary, secondary):
# Read the raw click detection register value and check if there was
# a click detected. Remember only the X axis causes clicks because of
# the register configuration set previously.
clicksrc = lis3dh.read_click_raw()
clicksrc = lis3dh._read_register_byte(adafruit_lis3dh.REG_CLICKSRC) # pylint: disable=protected-access
if clicksrc & 0b01000000 > 0:
# Click was detected! Quickly read 32 values from the accelerometer
# and look for the maximum magnitude values. Because the
Expand Down
39 changes: 20 additions & 19 deletions examples/click.py → examples/tap.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Click detection example.
# Tap detection example.
# Will loop forever printing when a single or double click is detected.
# Open the serial port after running to see the output printed.
# Author: Tony DiCola
import time
import board
import adafruit_lis3dh

Expand All @@ -12,7 +11,12 @@
# Hardware I2C setup:
import busio
i2c = busio.I2C(board.SCL, board.SDA)
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c)
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)

# Hardware I2C setup on CircuitPlayground Express:
# import busio
# i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
# lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)

# Software I2C setup:
#import bitbangio
Expand All @@ -29,26 +33,23 @@
# Set range of accelerometer (can be RANGE_2_G, RANGE_4_G, RANGE_8_G or RANGE_16_G).
lis3dh.range = adafruit_lis3dh.RANGE_2_G

# Set click detection to double and single clicks. The first parameter is a value:
# - 0 = Disable click detection.
# - 1 = Detect single clicks.
# - 2 = Detect single and double clicks.
# Set tap detection to double taps. The first parameter is a value:
# - 0 = Disable tap detection.
# - 1 = Detect single taps.
# - 2 = Detect double taps.
# The second parameter is the threshold and a higher value means less sensitive
# click detection. Note the threshold should be set based on the range above:
# tap detection. Note the threshold should be set based on the range above:
# - 2G = 40-80 threshold
# - 4G = 20-40 threshold
# - 8G = 10-20 threshold
# - 16G = 5-10 threshold
lis3dh.set_click(2, 80)
lis3dh.set_tap(2, 80)

# Loop forever printing if a single or double click is detected.
# Loop forever printing if a double tap is detected. A single double tap may cause multiple
# `tapped` reads to return true so we make sure the last once was False.
last_tap = False
while True:
# Read the click detection. Two booleans are returned, single click and
# double click detected. Each can be independently true/false.
single, double = lis3dh.read_click()
if single:
print('Single click!')
if double:
print('Double click!')
# Small delay to keep things responsive but give time for interrupt processing.
time.sleep(0.05)
tap = lis3dh.tapped
if tap and not last_tap:
print('Double tap!')
last_tap = tap