Skip to content

Instantly share code, notes, and snippets.

@ErinLMoore
Created March 24, 2023 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ErinLMoore/faa70bd59e68bfb7e6b723563ee67a21 to your computer and use it in GitHub Desktop.
Save ErinLMoore/faa70bd59e68bfb7e6b723563ee67a21 to your computer and use it in GitHub Desktop.
Adafruit Neotrellis Micropython coe
# SPDX-FileCopyrightText: 2022 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
from adafruit_neotrellis.neotrellis import NeoTrellis
from adafruit_neotrellis.multitrellis import MultiTrellis
from random import randint
###### Settings ########
i2c_bus = board.I2C()
trellis = MultiTrellis([
[NeoTrellis(i2c_bus, False, addr=0x2E), NeoTrellis(i2c_bus, False, addr=0x2F)],
[NeoTrellis(i2c_bus, False, addr=0x30), NeoTrellis(i2c_bus, False, addr=0x31)],
])
trelli = [
[NeoTrellis(i2c_bus, False, addr=0x2E), NeoTrellis(i2c_bus, False, addr=0x2F)],
[NeoTrellis(i2c_bus, False, addr=0x30), NeoTrellis(i2c_bus, False, addr=0x31)],
]
trellis.brightness = 0.5
MAX_X = 7 #leds in column
MAX_Y = 7 #leds in row
# some color definitions
OFF = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
ORANGE = (255, 100, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
INDIGO = (100, 0, 255)
PURPLE = (255, 0, 150)
COLORS = [OFF, YELLOW, BLUE, RED, GREEN, CYAN, ORANGE, INDIGO, PURPLE]
the_matrix = [ [0] * (MAX_X + 1) for _ in range(MAX_Y + 1)]
####################################################################
####################life function ##############33
OFF = 0
LIFE_MODE = [0]
BORN = 3
SURVIVES = [2,3]
def life_callback(x, y, edge):
if edge == NeoTrellis.EDGE_RISING:
if the_matrix[y][x] != OFF:
the_matrix[y][x] = OFF
else:
the_matrix[y][x] = randint(1, len(COLORS))
show_matrix_colors(the_matrix)
check_for_switch(x,y,edge)
check_for_life_switch(x,y,edge)
def calc_life():
if LIFE_MODE[0] == 1:
new_matrix = [x[:] for x in the_matrix]
[maybe_life(x,y, new_matrix) for y in range(MAX_Y + 1) for x in range(MAX_X + 1)]
[update_matrix(new_matrix, y, x) for y in range(MAX_Y + 1) for x in range(MAX_X + 1)]
def maybe_life(x,y, new_matrix):
neighbors = list(map(toroid_neighbors, get_neighbors_moore(x,y)))
frequency = neighbor_frequencies(neighbors)
if the_matrix[y][x] == OFF and OFF in frequency and frequency[OFF] == (8 - BORN):
new_matrix[y][x] = randint(1, len(COLORS))
if the_matrix[y][x] != OFF and OFF in frequency and (frequency[OFF] < (8 - SURVIVES[1]) or frequency[OFF] > (8 - SURVIVES[0])):
new_matrix[y][x] = 0
def check_for_life_switch(x,y,edge):
if (x,y) == (7,0) :
if edge == NeoTrellis.EDGE_RISING:
PRESSED[0] = True
if edge == NeoTrellis.EDGE_FALLING:
PRESSED[0] = False
elif (x,y) == (7,7):
if edge == NeoTrellis.EDGE_RISING:
PRESSED[1] = True
if edge == NeoTrellis.EDGE_FALLING:
PRESSED[1] = False
if PRESSED == [True, True]:
print("Switching Life Mode...")
switch_life_mode()
print("Life Mode Switched")
print(LIFE_MODE[0])
def switch_life_mode():
PRESSED[0] = False
PRESSED[1] = False
LIFE_MODE[0] = LIFE_MODE[0] ^ 1
################3
##################### wires functions #################################3
WIRES_MODE = [0]
OFF = 0
CONDUCTOR = 1
ELECTRON_HEAD = 2
ELECTRON_TAIL = 3
def wires_callback(x, y, edge):
if edge == NeoTrellis.EDGE_RISING:
the_matrix[y][x] = the_matrix[y][x] + 1
if the_matrix[y][x] > ELECTRON_TAIL:
the_matrix[y][x] = OFF
show_matrix_colors(the_matrix)
check_for_switch(x,y,edge)
check_for_wires_switch(x,y,edge)
def calc_wires():
if WIRES_MODE[0] == 1:
new_matrix = [x[:] for x in the_matrix]
[maybe_change(x, y, new_matrix) for y in range(MAX_Y + 1) for x in range(MAX_X + 1)]
[update_matrix(new_matrix, y, x) for y in range(MAX_Y + 1) for x in range(MAX_X + 1)]
def maybe_change(x, y, new_matrix):
neighbors = list(map(toroid_neighbors, get_neighbors_moore(x,y)))
if the_matrix[y][x] == ELECTRON_HEAD:
new_matrix[y][x] = ELECTRON_TAIL
elif the_matrix[y][x] == ELECTRON_TAIL:
new_matrix[y][x] = CONDUCTOR
elif the_matrix[y][x] == CONDUCTOR and enough_neighbors(neighbors) == True:
new_matrix[y][x] = ELECTRON_HEAD
def enough_neighbors(neighbors):
frequency = neighbor_frequencies(neighbors)
if ELECTRON_HEAD in frequency and (frequency[ELECTRON_HEAD] == 1 or frequency[ELECTRON_HEAD] == 2):
return True
else: return False
# conductor → electron head if exactly one or two of the neighbouring cells are electron heads, otherwise remains conductor.
def check_for_wires_switch(x,y,edge):
if (x,y) == (7,0) :
if edge == NeoTrellis.EDGE_RISING:
PRESSED[0] = True
if edge == NeoTrellis.EDGE_FALLING:
PRESSED[0] = False
elif (x,y) == (7,7):
if edge == NeoTrellis.EDGE_RISING:
PRESSED[1] = True
if edge == NeoTrellis.EDGE_FALLING:
PRESSED[1] = False
if PRESSED == [True, True]:
print("Switching Wires Mode...")
switch_wires_mode()
print("Wires Mode Switched")
print(WIRES_MODE[0])
def switch_wires_mode():
PRESSED[0] = False
PRESSED[1] = False
the_matrix[0][7] = 0
the_matrix[7][7] = 0
WIRES_MODE[0] = WIRES_MODE[0] ^ 1
########################## sandpile functions #############################
MAX_PILE_SIZE = 3 #it will topple if it goes over this number. 3 topples to 4 neighbors, 7 to 8.
TOPPLE_AMOUNT = MAX_PILE_SIZE + 1
def sandpile_callback(x, y, edge):
if edge == NeoTrellis.EDGE_RISING:
the_matrix[y][x] = the_matrix[y][x] + 1
show_matrix_colors(the_matrix)
check_for_switch(x,y,edge)
def calc_sandpile():
new_matrix = [x[:] for x in the_matrix]
[maybe_overflow(x, y, new_matrix) for y in range(MAX_Y + 1) for x in range(MAX_X + 1)]
[update_matrix(new_matrix, y, x) for y in range(MAX_Y + 1) for x in range(MAX_X + 1)]
def maybe_overflow(x, y, new_matrix):
if the_matrix[y][x] > MAX_PILE_SIZE:
new_matrix[y][x] = the_matrix[y][x] - TOPPLE_AMOUNT
neighborhood = get_neighbors_vn if TOPPLE_AMOUNT <= 4 else get_neighbors_moore
[increment_neighbor(neighbor, new_matrix) for neighbor in neighborhood(x,y)]
def increment_neighbor(neighbor, new_matrix):
n_x = neighbor[0]
n_y = neighbor[1]
if neighbor_in_range(neighbor) == True:
new_matrix[n_y][n_x] = the_matrix[n_y][n_x] + 1
def neighbor_in_range(value):
x_ok = value[0] >= 0 and value[0] <= MAX_X
y_ok = value[1] >= 0 and value[1] <= MAX_Y
return x_ok and y_ok
#####################################################
####################### shared functions ##################################
MODE = [0]
CALLBACKS = [life_callback, sandpile_callback, wires_callback]
CALCS = [calc_life, calc_sandpile, calc_wires]
PRESSED = [False, False]
def update_matrix(new_matrix, y, x):
the_matrix[y][x] = new_matrix[y][x]
def neighbor_frequencies(neighbors):
neighbor_values = [the_matrix[neighbor[1]][neighbor[0]] for neighbor in neighbors]
frequency = {}
for i in neighbor_values:
frequency[i] = frequency.get(i,0) + 1
return frequency
def get_neighbors_vn(x, y):
return [(x - 1, y), (x + 1, y), (x, y + 1), (x, y - 1)]
def get_neighbors_moore(x, y):
return [(x - 1, y), (x + 1, y), (x, y + 1), (x, y - 1), (x - 1, y + 1), (x - 1, y - 1), (x + 1, y + 1), (x + 1, y - 1)]
def toroid_neighbors(neighbor):
x = neighbor[0]
y = neighbor[1]
if x < 0:
x = MAX_X
elif x > MAX_X:
x = 0
if y < 0:
y = MAX_Y
elif y > MAX_Y:
y = 0
return (x,y)
def change_color(x, y, value):
#OFF is a color
color = value if value < len(COLORS) else len(COLORS) -1
trellis.color(x, y, COLORS[color])
def show_matrix_colors(the_matrix):
[change_color(x, y, the_matrix[y][x]) for y in range(MAX_Y + 1) for x in range(MAX_X + 1)]
def check_for_switch(x,y, edge):
if (x,y) == (0,0) :
if edge == NeoTrellis.EDGE_RISING:
PRESSED[0] = True
if edge == NeoTrellis.EDGE_FALLING:
PRESSED[0] = False
elif (x,y) == (0,7):
if edge == NeoTrellis.EDGE_RISING:
PRESSED[1] = True
if edge == NeoTrellis.EDGE_FALLING:
PRESSED[1] = False
if PRESSED == [True, True]:
print("Switching...")
switch_mode()
print(CALLBACKS[MODE[0]])
time.sleep(1)
print("Mode Switched!")
def switch_mode():
PRESSED[0] = False
PRESSED[1] = False
MODE[0] = MODE[0] + 1
if MODE[0] >= len(CALLBACKS):
MODE[0] = 0
init()
#############################################
################### init neotrellis ########
def init():
[test_and_set_callback(x, y, COLORS[y+1]) for y in range(MAX_Y + 1) for x in range(MAX_X + 1)]
for i in range(MAX_Y + 1):
the_matrix[i] = [0] * (MAX_X + 1)
show_matrix_colors(the_matrix)
def test_and_set_callback(x, y, color):
trellis.activate_key(x, y, NeoTrellis.EDGE_RISING)
trellis.activate_key(x, y, NeoTrellis.EDGE_FALLING)
trellis.set_callback(x, y, CALLBACKS[MODE[0]])
trellis.color(x, y, color)
init()
########################################
######## main loop #####################
while True:
# The NeoTrellis can only be read every 17 milliseconds or so
trellis.sync()
time.sleep(0.02)
show_matrix_colors(the_matrix)
CALCS[MODE[0]]()
############################################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment