Skip to content

Commit 14126e4

Browse files
authored
Merge pull request adafruit#519 from adafruit/TheKitty-patch-54
Update code.py with author fixes
2 parents 0a63db8 + d41439b commit 14126e4

File tree

1 file changed

+35
-22
lines changed

1 file changed

+35
-22
lines changed

NeoTrellis_M4_Sand/code.py

+35-22
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
# up LEDs. Based on the code created by Phil Burgess and Dave Astels, see:
44
# https://learn.adafruit.com/digital-sand-dotstar-circuitpython-edition/code
55
# https://learn.adafruit.com/animated-led-sand
6-
# Ported (badly) to NeoTrellis M4 by John Thurmond
6+
# Ported to NeoTrellis M4 by John Thurmond
77
#
88
# The MIT License (MIT)
99
#
10-
# Copyright (c) 2018 Tony DiCola
11-
#
1210
# Permission is hereby granted, free of charge, to any person obtaining a copy
1311
# of this software and associated documentation files (the "Software"), to deal
1412
# in the Software without restriction, including without limitation the rights
@@ -30,6 +28,7 @@
3028
import math
3129
import random
3230
import board
31+
import audioio
3332
import busio
3433
import adafruit_trellism4
3534
import adafruit_adxl34x
@@ -38,15 +37,12 @@
3837
WIDTH = 8 # Display width in pixels
3938
HEIGHT = 4 # Display height in pixels
4039
NUMBER_PIXELS = WIDTH * HEIGHT
41-
MAX_FPS = 10 # Maximum redraw rate, frames/second
42-
40+
MAX_FPS = 20 # Maximum redraw rate, frames/second
4341
MAX_X = WIDTH * 256 - 1
4442
MAX_Y = HEIGHT * 256 - 1
4543

46-
4744
class Grain:
48-
"""A simple struct to hold position and velocity information
49-
for a single grain."""
45+
"""A simple struct to hold position and velocity information for a single grain."""
5046

5147
def __init__(self):
5248
"""Initialize grain position and velocity."""
@@ -65,6 +61,11 @@ def __init__(self):
6561
i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
6662
sensor = adafruit_adxl34x.ADXL345(i2c)
6763

64+
# Add tap detection - with a pretty hard tap
65+
sensor.enable_tap_detection(threshold=50)
66+
67+
color_mode = 0
68+
6869
oldidx = 0
6970
newidx = 0
7071
delta = 0
@@ -73,6 +74,14 @@ def __init__(self):
7374

7475
occupied_bits = [False for _ in range(WIDTH * HEIGHT)]
7576

77+
# Add Audio file...
78+
f = open("water-click.wav", "rb")
79+
wav = audioio.WaveFile(f)
80+
print("%d channels, %d bits per sample, %d Hz sample rate " %
81+
(wav.channel_count, wav.bits_per_sample, wav.sample_rate))
82+
audio = audioio.AudioOut(board.A1)
83+
#audio.play(wav)
84+
7685
def index_of_xy(x, y):
7786
"""Convert an x/column and y/row into an index into
7887
a linear pixel array.
@@ -82,7 +91,6 @@ def index_of_xy(x, y):
8291
"""
8392
return (y >> 8) * WIDTH + (x >> 8)
8493

85-
8694
def already_present(limit, x, y):
8795
"""Check if a pixel is already used.
8896
@@ -121,26 +129,28 @@ def wheel(pos):
121129
g.vy = 0
122130

123131
while True:
132+
# Check for tap and adjust color mode
133+
if sensor.events['tap']:
134+
color_mode += 1
135+
if color_mode > 2:
136+
color_mode = 0
137+
124138
# Display frame rendered on prior pass. It's done immediately after the
125139
# FPS sync (rather than after rendering) for consistent animation timing.
126140

127-
# pylint: disable=line-too-long
128141
for i in range(NUMBER_PIXELS):
142+
129143
# Some color options:
130144

131145
# Random color every refresh
132-
#trellis.pixels[(i%8, i//8)] = wheel(random.randint(1, 254)) if occupied_bits[i] else (0, 0, 0)
133-
146+
if color_mode == 0:
147+
trellis.pixels[(i%8, i//8)] = wheel(random.randint(1, 254)) if occupied_bits[i] else (0, 0, 0)
134148
# Color by pixel (meh - needs work)
135-
#trellis.pixels[(i%8, i//8)] = wheel(i*2) if occupied_bits[i] else (0, 0, 0)
136-
149+
if color_mode == 1:
150+
trellis.pixels[(i%8, i//8)] = wheel(i*2) if occupied_bits[i] else (0, 0, 0)
137151
# Change color to random on button press, or cycle when you hold one down
138-
trellis.pixels[(i%8, i//8)] = wheel(color) if occupied_bits[i] else (0, 0, 0)
139-
140-
# Set as single color
141-
#trellis.pixels[(i//8,i%8)] = (255, 0, 0) if occupied_bits[i] else (0, 0, 0)
142-
143-
# TODO: Change color depending on which button you press?
152+
if color_mode == 2:
153+
trellis.pixels[(i%8, i//8)] = wheel(color) if occupied_bits[i] else (0, 0, 0)
144154

145155
# Change color to a new random color on button press
146156
pressed = set(trellis.pressed_keys)
@@ -162,13 +172,13 @@ def wheel(pos):
162172
ay = f_y >> 3 # to grain coordinate space
163173
az = abs(f_z) >> 6 # Random motion factor
164174

165-
print("%6d %6d %6d"%(ax,ay,az))
175+
#print("%6d %6d %6d"%(ax,ay,az))
166176
az = 1 if (az >= 3) else (4 - az) # Clip & invert
167177
ax -= az # Subtract motion factor from X, Y
168178
ay -= az
169179
az2 = (az << 1) + 1 # Range of random motion to add back in
170180

171-
# Adjust axes for the NeoTrellis M4 (probably better ways to do this)
181+
# Adjust axes for the NeoTrellis M4 (reuses code above rather than fixing it - inefficient)
172182
ax2 = ax
173183
ax = -ay
174184
ay = ax2
@@ -177,6 +187,7 @@ def wheel(pos):
177187
v2 = 0 # Velocity squared
178188
v = 0.0 # Absolute velociy
179189
for g in grains:
190+
180191
g.vx += ax + random.randint(0, az2) # A little randomness makes
181192
g.vy += ay + random.randint(0, az2) # tall stacks topple better!
182193

@@ -281,5 +292,7 @@ def wheel(pos):
281292
newidx = oldidx # Not moving
282293
occupied_bits[oldidx] = False
283294
occupied_bits[newidx] = True
295+
if oldidx != newidx:
296+
audio.play(wav) # If there's an update, play the sound
284297
g.x = newx
285298
g.y = newy

0 commit comments

Comments
 (0)