3
3
# up LEDs. Based on the code created by Phil Burgess and Dave Astels, see:
4
4
# https://learn.adafruit.com/digital-sand-dotstar-circuitpython-edition/code
5
5
# https://learn.adafruit.com/animated-led-sand
6
- # Ported (badly) to NeoTrellis M4 by John Thurmond
6
+ # Ported to NeoTrellis M4 by John Thurmond
7
7
#
8
8
# The MIT License (MIT)
9
9
#
10
- # Copyright (c) 2018 Tony DiCola
11
- #
12
10
# Permission is hereby granted, free of charge, to any person obtaining a copy
13
11
# of this software and associated documentation files (the "Software"), to deal
14
12
# in the Software without restriction, including without limitation the rights
30
28
import math
31
29
import random
32
30
import board
31
+ import audioio
33
32
import busio
34
33
import adafruit_trellism4
35
34
import adafruit_adxl34x
38
37
WIDTH = 8 # Display width in pixels
39
38
HEIGHT = 4 # Display height in pixels
40
39
NUMBER_PIXELS = WIDTH * HEIGHT
41
- MAX_FPS = 10 # Maximum redraw rate, frames/second
42
-
40
+ MAX_FPS = 20 # Maximum redraw rate, frames/second
43
41
MAX_X = WIDTH * 256 - 1
44
42
MAX_Y = HEIGHT * 256 - 1
45
43
46
-
47
44
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."""
50
46
51
47
def __init__ (self ):
52
48
"""Initialize grain position and velocity."""
@@ -65,6 +61,11 @@ def __init__(self):
65
61
i2c = busio .I2C (board .ACCELEROMETER_SCL , board .ACCELEROMETER_SDA )
66
62
sensor = adafruit_adxl34x .ADXL345 (i2c )
67
63
64
+ # Add tap detection - with a pretty hard tap
65
+ sensor .enable_tap_detection (threshold = 50 )
66
+
67
+ color_mode = 0
68
+
68
69
oldidx = 0
69
70
newidx = 0
70
71
delta = 0
@@ -73,6 +74,14 @@ def __init__(self):
73
74
74
75
occupied_bits = [False for _ in range (WIDTH * HEIGHT )]
75
76
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
+
76
85
def index_of_xy (x , y ):
77
86
"""Convert an x/column and y/row into an index into
78
87
a linear pixel array.
@@ -82,7 +91,6 @@ def index_of_xy(x, y):
82
91
"""
83
92
return (y >> 8 ) * WIDTH + (x >> 8 )
84
93
85
-
86
94
def already_present (limit , x , y ):
87
95
"""Check if a pixel is already used.
88
96
@@ -121,26 +129,28 @@ def wheel(pos):
121
129
g .vy = 0
122
130
123
131
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
+
124
138
# Display frame rendered on prior pass. It's done immediately after the
125
139
# FPS sync (rather than after rendering) for consistent animation timing.
126
140
127
- # pylint: disable=line-too-long
128
141
for i in range (NUMBER_PIXELS ):
142
+
129
143
# Some color options:
130
144
131
145
# 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 )
134
148
# 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 )
137
151
# 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 )
144
154
145
155
# Change color to a new random color on button press
146
156
pressed = set (trellis .pressed_keys )
@@ -162,13 +172,13 @@ def wheel(pos):
162
172
ay = f_y >> 3 # to grain coordinate space
163
173
az = abs (f_z ) >> 6 # Random motion factor
164
174
165
- print ("%6d %6d %6d" % (ax ,ay ,az ))
175
+ # print("%6d %6d %6d"%(ax,ay,az))
166
176
az = 1 if (az >= 3 ) else (4 - az ) # Clip & invert
167
177
ax -= az # Subtract motion factor from X, Y
168
178
ay -= az
169
179
az2 = (az << 1 ) + 1 # Range of random motion to add back in
170
180
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 )
172
182
ax2 = ax
173
183
ax = - ay
174
184
ay = ax2
@@ -177,6 +187,7 @@ def wheel(pos):
177
187
v2 = 0 # Velocity squared
178
188
v = 0.0 # Absolute velociy
179
189
for g in grains :
190
+
180
191
g .vx += ax + random .randint (0 , az2 ) # A little randomness makes
181
192
g .vy += ay + random .randint (0 , az2 ) # tall stacks topple better!
182
193
@@ -281,5 +292,7 @@ def wheel(pos):
281
292
newidx = oldidx # Not moving
282
293
occupied_bits [oldidx ] = False
283
294
occupied_bits [newidx ] = True
295
+ if oldidx != newidx :
296
+ audio .play (wav ) # If there's an update, play the sound
284
297
g .x = newx
285
298
g .y = newy
0 commit comments