Now let's get the Feather setup with CircuitPython, the necessary libraries, and the hourglass code.
Prepare the Feather Sense
Follow this guide for setting up CircuitPython on the Feather nRF52840 Sense:
Hourglass Code
Click the Download Project Bundle button in the code listing below to get a zip file with the project code and necessary libraries. Copy code.py and matrixsand.py to the CIRCUITPY folder.
Also copy the libraries to CIRCUITPY/lib. For quick reference, the CIRCUITPY/lib folder should have these contents (having more is OK):
Here is the main code listing for code.py. The matrixsand.py file will be found in the zip, along with everything else. Click the Download Project Bundle to get the zip.
# SPDX-FileCopyrightText: 2020 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import board
from adafruit_ht16k33 import matrix
import matrixsand
DELAY = 0.05 # overall update rate
# setup i2c
i2c = board.I2C() # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller
# check for LSM6DS33 or LSM6DS3TR-C (Adafruit Feather Sense)
try:
from adafruit_lsm6ds.lsm6ds33 import LSM6DS33 as LSM6DS # pylint: disable=unused-import
accelo = LSM6DS(i2c)
except RuntimeError:
from adafruit_lsm6ds.lsm6ds3 import LSM6DS3 as LSM6DS # pylint: disable=unused-import
accelo = LSM6DS(i2c)
# the matrices
m1 = matrix.Matrix8x8(i2c, 0x70)
m2 = matrix.Matrix8x8(i2c, 0x71)
# the sand
sand1 = matrixsand.MatrixSand(8, 8)
sand2 = matrixsand.MatrixSand(8, 8)
# simple helper
def update_matrix(m, s):
for x in range(8):
for y in range(8):
m[x,y] = s[x,y]
# fill up some sand
for sx in range(8):
for sy in range(8):
sand1[sx, sy] = True
sand1[0,0] = sand1[0,1] = sand1[1,0] = False
sand1[0,2] = sand1[1,1] = sand1[2,0] = False
update_matrix(m1, sand1)
update_matrix(m2, sand2)
updated1 = updated2 = False
while True:
# read accelo
ax, ay, az = accelo.acceleration
# rotate coords
xx = -ax - ay
yy = -ax + ay
zz = az
# move grain of sand from upper to lower?
if yy > 0 and sand1[7,7] and not sand2[0,0] and not updated2:
sand1[7,7] = False
sand2[0,0] = True
updated1 = updated2 = True
# move grain of sand from lower to upper?
elif yy <= 0 and sand2[0,0] and not sand1[7,7] and not updated1:
sand2[0,0] = False
sand1[7,7] = True
updated1 = updated2 = True
# nope, just a regular update
else:
updated1 = sand1.iterate((xx, yy, zz))
updated2 = sand2.iterate((xx, yy, zz))
# update matrices if needed
if updated1:
update_matrix(m1, sand1)
if updated2:
update_matrix(m2, sand2)
time.sleep(DELAY)
The code handles both of the accelerometers that may appear on the Adafruit Feather nRF52840 Sense.
Page last edited August 18, 2025
Text editor powered by tinymce.