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
#

import time
import board
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

# the accelo

# 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:
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)
```

This guide was first published on Jun 06, 2020. It was last updated on Jun 16, 2024.