Simple test¶
Ensure your device works with this simple test.
1# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
2# SPDX-License-Identifier: MIT
3
4import time
5import board
6import busio
7import adafruit_lis3dh
8
9# Hardware I2C setup. Use the CircuitPlayground built-in accelerometer if available;
10# otherwise check I2C pins.
11if hasattr(board, "ACCELEROMETER_SCL"):
12 i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
13 lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)
14else:
15 i2c = board.I2C() # uses board.SCL and board.SDA
16 lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c)
17
18# Hardware SPI setup:
19# spi = board.SPI()
20# cs = digitalio.DigitalInOut(board.D5) # Set to correct CS pin!
21# lis3dh = adafruit_lis3dh.LIS3DH_SPI(spi, cs)
22
23# PyGamer or MatrixPortal I2C Setup:
24# i2c = board.I2C() # uses board.SCL and board.SDA
25# lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)
26
27
28# Set range of accelerometer (can be RANGE_2_G, RANGE_4_G, RANGE_8_G or RANGE_16_G).
29lis3dh.range = adafruit_lis3dh.RANGE_2_G
30
31# Loop forever printing accelerometer values
32while True:
33 # Read accelerometer values (in m / s ^ 2). Returns a 3-tuple of x, y,
34 # z axis values. Divide them by 9.806 to convert to Gs.
35 x, y, z = [
36 value / adafruit_lis3dh.STANDARD_GRAVITY for value in lis3dh.acceleration
37 ]
38 print("x = %0.3f G, y = %0.3f G, z = %0.3f G" % (x, y, z))
39 # Small delay to keep things responsive but give time for interrupt processing.
40 time.sleep(0.1)
Tap test¶
Illustrates tap different capabilities
1# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
2# SPDX-License-Identifier: MIT
3
4import time
5import board
6import busio
7import digitalio
8import adafruit_lis3dh
9
10# Hardware I2C setup. Use the CircuitPlayground built-in accelerometer if available;
11# otherwise check I2C pins.
12if hasattr(board, "ACCELEROMETER_SCL"):
13 i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
14 int1 = digitalio.DigitalInOut(board.ACCELEROMETER_INTERRUPT)
15 lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1)
16else:
17 i2c = board.I2C() # uses board.SCL and board.SDA
18 int1 = digitalio.DigitalInOut(
19 board.D9
20 ) # Set this to the correct pin for the interrupt!
21 lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)
22
23# Hardware SPI setup:
24# spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
25# cs = digitalio.DigitalInOut(board.D5) # Set to correct CS pin!
26# int1 = digitalio.DigitalInOut(board.D6) # Set to correct pin for interrupt!
27# lis3dh = adafruit_lis3dh.LIS3DH_SPI(spi, cs, int1=int1)
28
29# Set range of accelerometer (can be RANGE_2_G, RANGE_4_G, RANGE_8_G or RANGE_16_G).
30lis3dh.range = adafruit_lis3dh.RANGE_8_G
31
32# Set tap detection to double taps. The first parameter is a value:
33# - 0 = Disable tap detection.
34# - 1 = Detect single taps.
35# - 2 = Detect double taps.
36# The second parameter is the threshold and a higher value means less sensitive
37# tap detection. Note the threshold should be set based on the range above:
38# - 2G = 40-80 threshold
39# - 4G = 20-40 threshold
40# - 8G = 10-20 threshold
41# - 16G = 5-10 threshold
42lis3dh.set_tap(2, 60)
43
44# Loop forever printing if a double tap is detected.
45while True:
46 if lis3dh.tapped:
47 print("Tapped!")
48 time.sleep(0.01)
ADC test¶
Get the voltage readings
1# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
2# SPDX-License-Identifier: MIT
3
4# Analog to digital converter example.
5# Will loop forever printing ADC channel 1 raw and mV values every second.
6# NOTE the ADC can only read voltages in the range of ~900mV to 1800mV!
7
8import time
9import board
10import busio
11import adafruit_lis3dh
12
13# Uncomment if using SPI
14# import digitalio
15
16
17# Hardware I2C setup. Use the CircuitPlayground built-in accelerometer if available;
18# otherwise check I2C pins.
19if hasattr(board, "ACCELEROMETER_SCL"):
20 i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
21 lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)
22else:
23 i2c = board.I2C() # uses board.SCL and board.SDA
24 lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c)
25
26# Hardware SPI setup:
27# spi = board.SPI()
28# cs = digitalio.DigitalInOut(board.D5) # Set to correct CS pin!
29# lis3dh = adafruit_lis3dh.LIS3DH_SPI(spi, cs)
30
31# PyGamer I2C Setup:
32# i2c = board.I2C(A)
33# lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)
34
35
36# Loop forever printing ADC readings.
37while True:
38 # Read raw ADC value. Specify which ADC to read: 1, 2, or 3.
39 adc1_raw = lis3dh.read_adc_raw(1)
40 # Or read the ADC value in millivolts:
41 adc1_mV = lis3dh.read_adc_mV(1)
42 print("ADC 1 = {} ({} mV)".format(adc1_raw, adc1_mV))
43 time.sleep(1)
Spinner Example¶
Creates a spinner
1# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
2# SPDX-License-Identifier: MIT
3
4# Circuit Playground Express CircuitPython Fidget Spinner
5# This is meant to work with the Circuit Playground Express board:
6# https://www.adafruit.com/product/3333
7# Needs this LIS3DH module and the NeoPixel module installed:
8# https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH
9# https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel
10# Author: Tony DiCola
11# License: MIT License (https://opensource.org/licenses/MIT)
12# pylint: disable=redefined-outer-name
13import math
14import time
15
16import board
17import busio
18
19from micropython import const
20
21import neopixel
22import adafruit_lis3dh
23
24# Configuration:
25ACCEL_RANGE = adafruit_lis3dh.RANGE_16_G # Accelerometer range.
26TAP_THRESHOLD = 20 # Accelerometer tap threshold. Higher values
27# mean you need to tap harder to start a spin.
28SPINNER_DECAY = 0.5 # Decay rate for the spinner. Set to a value
29# from 0 to 1.0 where lower values mean the
30# spinner slows down faster.
31PRIMARY_COLOR = (0, 255, 0) # Color of the spinner dots.
32SECONDARY_COLOR = (0, 0, 0) # Background color of the spinner.
33
34
35# Define a class that represents the fidget spinner.
36class FidgetSpinner:
37 def __init__(self, decay=0.5):
38 self._decay = decay
39 self._velocity = 0.0
40 self._elapsed = 0.0
41 self._position = 0.0
42
43 def spin(self, velocity):
44 self._velocity = velocity
45 self._elapsed = 0.0
46
47 def get_position(self, delta):
48 # Increment elapsed time and compute the current velocity after a
49 # decay of the initial velocity.
50 self._elapsed += delta
51 current_velocity = self._velocity * math.pow(self._decay, self._elapsed)
52 self._position += current_velocity * delta
53 # Make sure the position stays within values that range from 0 to <10.
54 self._position = math.fmod(self._position, 10.0)
55 if self._position < 0.0:
56 self._position += 10.0
57 return self._position
58
59
60# pylint: disable=no-member
61# Initialize NeoPixels and accelerometer.
62pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, auto_write=False)
63pixels.fill((0, 0, 0))
64pixels.show()
65i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
66lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=25)
67
68# Set accelerometer range.
69lis3dh.range = ACCEL_RANGE
70# Enable single click detection, but use a custom CLICK_CFG register value
71# to only detect clicks on the X axis (instead of all 3 X, Y, Z axes).
72lis3dh.set_tap(1, TAP_THRESHOLD, click_cfg=0x01)
73# Enable LIS3DH FIFO in stream mode. This reaches in to the LIS3DH library to
74# call internal methods that change a few register values. This must be done
75# AFTER calling set_tap above because the set_tap function also changes
76# REG_CTRL5.
77# Define register numbers, which are not exported from the library.
78_REG_CTRL5 = const(0x24)
79_REG_CLICKSRC = const(0x39)
80# pylint: disable=protected-access
81lis3dh._write_register_byte(_REG_CTRL5, 0b01001000)
82lis3dh._write_register_byte(0x2E, 0b10000000) # Set FIFO_CTRL to Stream mode.
83# pylint: disable=protected-access
84
85# Create a fidget spinner object.
86spinner = FidgetSpinner(SPINNER_DECAY)
87
88
89# Main loop will run forever checking for click/taps from accelerometer and
90# then spinning the spinner.
91last = time.monotonic() # Keep track of the last time the loop ran.
92while True:
93 # Read the raw click detection register value and check if there was
94 # a click detected.
95 clicksrc = lis3dh._read_register_byte(
96 _REG_CLICKSRC
97 ) # pylint: disable=protected-access
98 if clicksrc & 0b01000000 > 0:
99 # Click was detected! Quickly read 32 values from the accelerometer
100 # FIFO and look for the maximum magnitude values.
101 maxval = abs(lis3dh.acceleration[0]) # Grab just the X acceleration value.
102 for i in range(31):
103 x = abs(lis3dh.acceleration[0])
104 if x > maxval:
105 maxval = x
106 # Check if this was a positive or negative spin/click event.
107 if clicksrc == 0b1010001:
108 # Positive click, spin in a positive direction.
109 spinner.spin(maxval)
110 elif clicksrc == 0b1011001:
111 # Negative click, spin in negative direction.
112 spinner.spin(-maxval)
113 # Update the amount of time that's passed since the last loop iteration.
114 current = time.monotonic()
115 delta = current - last
116 last = current
117 # Set all pixels to secondary color.
118 pixels.fill(SECONDARY_COLOR)
119 # Update the fidget spinner position and turn on the appropriate pixels.
120 pos = int(spinner.get_position(delta))
121 # Set the current position pixel and the pixel exactly opposite it (i.e. 5
122 # pixels ahead, wrapping back to the start) to the primary color.
123 pixels[pos] = PRIMARY_COLOR
124 pixels[(pos + 5) % 10] = PRIMARY_COLOR
125 pixels.show()
126 # Small delay to stay responsive but give time for interrupt processing.
127 time.sleep(0.05)
Advanced Spinner Example¶
Creates a spinner with colors and animations
1# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
2# SPDX-License-Identifier: MIT
3
4# Circuit Playground Express CircuitPython Fidget Spinner
5# This is meant to work with the Circuit Playground Express board:
6# https://www.adafruit.com/product/3333
7# Needs this LIS3DH module and the NeoPixel module installed:
8# https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH
9# https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel
10# Author: Tony DiCola
11# License: MIT License (https://opensource.org/licenses/MIT)
12# pylint: disable=redefined-outer-name
13import math
14import time
15
16import board
17import busio
18
19from micropython import const
20
21import neopixel
22import adafruit_lis3dh
23
24# Configuration:
25ACCEL_RANGE = adafruit_lis3dh.RANGE_16_G # Accelerometer range.
26TAP_THRESHOLD = 20 # Accelerometer tap threshold. Higher values
27# mean you need to tap harder to start a spin.
28SPINNER_DECAY = 0.5 # Decay rate for the spinner. Set to a value
29# from 0 to 1.0 where lower values mean the
30# spinner slows down faster.
31PRIMARY_COLOR = (0, 255, 0) # Color of the spinner dots.
32SECONDARY_COLOR = (0, 0, 0) # Background color of the spinner.
33
34
35# Define a class that represents the fidget spinner.
36class FidgetSpinner:
37 def __init__(self, decay=0.5):
38 self._decay = decay
39 self._velocity = 0.0
40 self._elapsed = 0.0
41 self._position = 0.0
42
43 def spin(self, velocity):
44 self._velocity = velocity
45 self._elapsed = 0.0
46
47 def get_position(self, delta):
48 # Increment elapsed time and compute the current velocity after a
49 # decay of the initial velocity.
50 self._elapsed += delta
51 current_velocity = self._velocity * math.pow(self._decay, self._elapsed)
52 self._position += current_velocity * delta
53 # Make sure the position stays within values that range from 0 to <10.
54 self._position = math.fmod(self._position, 10.0)
55 if self._position < 0.0:
56 self._position += 10.0
57 return self._position
58
59
60# pylint: disable=no-member
61# Initialize NeoPixels and accelerometer.
62pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, auto_write=False)
63pixels.fill((0, 0, 0))
64pixels.show()
65i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
66lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=25)
67
68# Set accelerometer range.
69lis3dh.range = ACCEL_RANGE
70# Enable single click detection, but use a custom CLICK_CFG register value
71# to only detect clicks on the X axis (instead of all 3 X, Y, Z axes).
72lis3dh.set_tap(1, TAP_THRESHOLD, click_cfg=0x01)
73# Enable LIS3DH FIFO in stream mode. This reaches in to the LIS3DH library to
74# call internal methods that change a few register values. This must be done
75# AFTER calling set_tap above because the set_tap function also changes
76# REG_CTRL5.
77# Define register numbers, which are not exported from the library.
78_REG_CTRL5 = const(0x24)
79_REG_CLICKSRC = const(0x39)
80# pylint: disable=protected-access
81lis3dh._write_register_byte(_REG_CTRL5, 0b01001000)
82lis3dh._write_register_byte(0x2E, 0b10000000) # Set FIFO_CTRL to Stream mode.
83# pylint: disable=protected-access
84
85# Create a fidget spinner object.
86spinner = FidgetSpinner(SPINNER_DECAY)
87
88
89# Main loop will run forever checking for click/taps from accelerometer and
90# then spinning the spinner.
91last = time.monotonic() # Keep track of the last time the loop ran.
92while True:
93 # Read the raw click detection register value and check if there was
94 # a click detected.
95 clicksrc = lis3dh._read_register_byte(
96 _REG_CLICKSRC
97 ) # pylint: disable=protected-access
98 if clicksrc & 0b01000000 > 0:
99 # Click was detected! Quickly read 32 values from the accelerometer
100 # FIFO and look for the maximum magnitude values.
101 maxval = abs(lis3dh.acceleration[0]) # Grab just the X acceleration value.
102 for i in range(31):
103 x = abs(lis3dh.acceleration[0])
104 if x > maxval:
105 maxval = x
106 # Check if this was a positive or negative spin/click event.
107 if clicksrc == 0b1010001:
108 # Positive click, spin in a positive direction.
109 spinner.spin(maxval)
110 elif clicksrc == 0b1011001:
111 # Negative click, spin in negative direction.
112 spinner.spin(-maxval)
113 # Update the amount of time that's passed since the last loop iteration.
114 current = time.monotonic()
115 delta = current - last
116 last = current
117 # Set all pixels to secondary color.
118 pixels.fill(SECONDARY_COLOR)
119 # Update the fidget spinner position and turn on the appropriate pixels.
120 pos = int(spinner.get_position(delta))
121 # Set the current position pixel and the pixel exactly opposite it (i.e. 5
122 # pixels ahead, wrapping back to the start) to the primary color.
123 pixels[pos] = PRIMARY_COLOR
124 pixels[(pos + 5) % 10] = PRIMARY_COLOR
125 pixels.show()
126 # Small delay to stay responsive but give time for interrupt processing.
127 time.sleep(0.05)