from neopixel import Neopixel
import random
import utime
import math
print("test")
normal_repeats = 2 # Number of times the normal heartbeat pattern repeats
dying_cycles = 2 # Number of cycles for the dying rhythm
# Since a single normal heartbeat pattern consists of 2 cycles, and there are dying_cycles:
HEART_BEAT_CYCLES = (normal_repeats * 2) + dying_cycles
# This matrix which has 5 columns and 11 rows
# it describes the order in which the LEDs are wired
# to the microcontroller. The first LED is on the bottom left
# and starts up the first column, then goes down the second column
# and so on until it reaches the top of the fifth column.
led_portrat_matrix = [
[10, 11, 32, 33, 54],
[9, 12, 31, 34, 53],
[8, 13, 30, 35, 52],
[7, 14, 29, 36, 51],
[6, 15, 28, 37, 50],
[5, 16, 27, 38, 49],
[4, 17, 26, 39, 48],
[3, 18, 25, 40, 47],
[2, 19, 24, 41, 46],
[1, 20, 23, 42, 45],
[0, 21, 22, 43, 44]]
#np = NeoPixel(machine.Pin(0), len(led_portrat_matrix) * len(led_portrat_matrix[0]))
np = Neopixel(55, 0, 6, "GRB")
# Given a item in the matrix, give an array of all items that are one row below it.
# If the item is in the last row, return None
def get_items_below(item):
items_below = []
for row in range(len(led_portrat_matrix)):
for col in range(len(led_portrat_matrix[row])):
if led_portrat_matrix[row][col] == item:
# Append the items from the rows below the current row in the same column
for below_row in range(row + 1, len(led_portrat_matrix)):
items_below.append(led_portrat_matrix[below_row][col])
return items_below
return None
def bleed_rhythm(item):
items = get_items_below(item)
for item in items:
np[item] = (0, 255, 0)
np.write()
yield
def heart_beat_rhythm1(cycles):
# Yields values between 0 and 255 to mimic a heartbeat brightness pattern
for _ in range(cycles):
for i in [50, 100, 150, 200, 255, 200, 150, 100, 50, 0]:
yield i
def heart_beat_rhythm(normal_cycles, dying_cycles):
# Normal heartbeats
for _ in range(normal_cycles): # Number of times to repeat the normal heartbeat pattern
for cycle in range(2): # A single normal heartbeat pattern
for i in range(-90, 0, 10):
yield int(255 * (1 + math.sin(math.radians(i))) / 2)
for _ in range(2):
yield int(255 * (1 + math.sin(math.radians(-90))) / 2)
for i in range(-90, 0, 10):
yield int(255 * (1 + math.sin(math.radians(i))) / 2)
for _ in range(4):
yield int(255 * (1 + math.sin(math.radians(-90))) / 2)
last_brightness = 0
# Dying rhythm
for dying_cycle in range(1, dying_cycles + 1): # Gradually reducing brightness
for i in range(-90, 0, 10):
yield int((255 / dying_cycle) * (1 + math.sin(math.radians(i))) / 2)
for _ in range(2):
yield int((200 / dying_cycle) * (1 + math.sin(math.radians(-90))) / 2)
for i in range(-90, 0, 10):
yield int((150 / dying_cycle) * (1 + math.sin(math.radians(i))) / 2)
for _ in range(4):
yield int((255 / dying_cycle) * (1 + math.sin(math.radians(-90))) / 2)
def fade_out(items_below, max_brightness):
max_steps = max_brightness
for step in range(max_steps):
for index, row in enumerate(items_below):
# Calculate the brightness based on the position in the array and the current step
factor = (len(items_below) - 1 - index) / len(items_below)
brightness = max(max_brightness - step * (1 + factor), 0)
np.set_pixel(row, (0, int(brightness), 0))
np.show()
utime.sleep_ms(10)
excluded_first_row = [item for row in led_portrat_matrix[:-1] for item in row]
# Run both generators simultaneously for 10 cycles
while True:
chosen_pixel = random.choice(excluded_first_row)
#chosen_pixel = random.randint(0, len(led_portrat_matrix) * len(led_portrat_matrix[0]) - 1)
print(f"Chosen pixel: Index {chosen_pixel}")
print(get_items_below(chosen_pixel))
heart = heart_beat_rhythm(normal_repeats, dying_cycles)
items_below = get_items_below(chosen_pixel)
fade_in_values = [0] * len(items_below)
current_item_below = 0 # Add this line to define the variable
max_brightness = 0
# Run both generators simultaneously for 10 cycles
for cycle in range(HEART_BEAT_CYCLES *24 -1):
brightness = next(heart)
np.set_pixel(chosen_pixel,(0, brightness, 0))
if brightness > 0 and cycle > random.randint(3, 12) and len(items_below) > 0:
# Iterate through the LEDs and gradually increase brightness
for index in range(min(current_item_below + 1, len(items_below))):
if fade_in_values[index] < brightness -10:
fade_in_values[index] += 5
max_brightness = fade_in_values[index]
np.set_pixel(items_below[index], (0, min(255, int(fade_in_values[index])), 0))
# Move on to the next LED if the current one has reached full brightness
if fade_in_values[current_item_below] >= 25 and current_item_below < len(items_below) - 1:
current_item_below += 1
np.show()
utime.sleep_ms(random.randint(50, 80))
#np[chosen_pixel] = (0, 0, brightness)
#items_below.insert(0, chosen_pixel)
fade_out(items_below, max_brightness)