import machine import time import neopixel # ============================================================ # NEOPIXELS # ============================================================ # 3-LED strip on GP17 STRIP_PIN = 17 STRIP_LEDS = 3 strip = neopixel.NeoPixel(machine.Pin(STRIP_PIN), STRIP_LEDS) # Single flashing LED on GP28 SINGLE_PIN = 28 single = neopixel.NeoPixel(machine.Pin(SINGLE_PIN), 1) # ============================================================ # BUTTONS (GP20, GP21, GP22) # ============================================================ button_pins = [20, 21, 22] buttons = [machine.Pin(pin, machine.Pin.IN, machine.Pin.PULL_UP) for pin in button_pins] # ============================================================ # COLOR PALETTE (index-based) # ============================================================ colors = [ (0, 0, 0), # 0 Off (255, 0, 0), # 1 Red (0, 255, 0), # 2 Green (0, 0, 255), # 3 Blue (255, 255, 0), # 4 Yellow (0, 255, 255), # 5 Cyan (255, 0, 255), # 6 Magenta (255, 128, 0), # 7 Orange (128, 0, 255), # 8 Purple (255, 20, 147), # 9 Pink (128, 255, 0), # 10 Lime (255, 255, 255) # 11 White ] # ============================================================ # STATE FOR PIXELS 0-2 (buttons) # ============================================================ color_index = [0, 0, 0] # Color for each strip LED brightness = [5, 5, 5] # Brightness 0–100% last_state = [1, 1, 1] press_time = [0, 0, 0] # ============================================================ # FLASHING SINGLE PIXEL (GP28) # ============================================================ FLASH_COLOR_INDEX = 1 # Choose color from palette (0–10) FLASH_BRIGHTNESS = 5 # 0–100% FLASH_INTERVAL_MS = 500 # Flash speed flash_on = False last_flash_time = time.ticks_ms() # ============================================================ # HELPER FUNCTIONS # ============================================================ def apply_brightness(color, level): r, g, b = color factor = level / 100 return (int(r * factor), int(g * factor), int(b * factor)) def update_strip(): for i in range(STRIP_LEDS): strip[i] = apply_brightness(colors[color_index[i]], brightness[i]) strip.write() def single_on(): c = apply_brightness(colors[FLASH_COLOR_INDEX], FLASH_BRIGHTNESS) single[0] = c single.write() def single_off(): single[0] = (0, 0, 0) single.write() # ============================================================ # INITIAL STATE # ============================================================ update_strip() single_off() class HeartbeatNeoPixel: def __init__(self, neopixel_obj, pixel_index=0, color=(255, 0, 0), brightness=50, interval_ms=500): self.np = neopixel_obj self.index = pixel_index self.color = color self.brightness = brightness self.interval = interval_ms self.state = False self.last_time = time.ticks_ms() def apply_brightness(self, c): r, g, b = c factor = self.brightness / 100 return (int(r * factor), int(g * factor), int(b * factor)) def update(self): now = time.ticks_ms() if time.ticks_diff(now, self.last_time) >= self.interval: self.state = not self.state self.last_time = now if self.state: self.np[self.index] = self.apply_brightness(self.color) else: self.np[self.index] = (0, 0, 0) self.np.write() # heartbeat = HeartbeatNeoPixel( # neopixel_obj=single, # pixel_index=0, # color=colors[FLASH_COLOR_INDEX], # brightness=FLASH_BRIGHTNESS, # interval_ms=FLASH_INTERVAL_MS # ) # ============================================================ # MAIN LOOP # ============================================================ while True: now = time.ticks_ms() # ----------------------------- # BUTTONS → control pixels 0–2 # ----------------------------- heartbeat.update() for i in range(3): state = buttons[i].value() if last_state[i] == 1 and state == 0: press_time[i] = now if last_state[i] == 0 and state == 1: duration = time.ticks_diff(now, press_time[i]) if duration > 500: # LONG PRESS → adjust brightness brightness[i] += 10 if brightness[i] > 100: brightness[i] = 10 else: # SHORT PRESS → next color color_indimport machine import time import neopixel # ============================================================ # HEARTBEAT CLASS (NeoPixel version) # ============================================================ class HeartbeatNeoPixel: def __init__(self, neopixel_obj, pixel_index=0, color=(255, 0, 0), brightness=50, interval_ms=500): self.np = neopixel_obj self.index = pixel_index self.color = color self.brightness = brightness self.interval = interval_ms self.state = False self.last_time = time.ticks_ms() def apply_brightness(self, c): r, g, b = c factor = self.brightness / 100 return (int(r * factor), int(g * factor), int(b * factor)) def update(self): now = time.ticks_ms() if time.ticks_diff(now, self.last_time) >= self.interval: self.state = not self.state self.last_time = now if self.state: self.np[self.index] = self.apply_brightness(self.color) else: self.np[self.index] = (0, 0, 0) self.np.write() # ============================================================ # NEOPIXEL SETUP # ============================================================ # 3-LED strip on GP17 STRIP_PIN = 17 STRIP_LEDS = 3 strip = neopixel.NeoPixel(machine.Pin(STRIP_PIN), STRIP_LEDS) # Single heartbeat pixel on GP28 SINGLE_PIN = 28 single = neopixel.NeoPixel(machine.Pin(SINGLE_PIN), 1) # ============================================================ # BUTTONS (GP20, GP21, GP22) # ============================================================ button_pins = [20, 21, 22] buttons = [machine.Pin(pin, machine.Pin.IN, machine.Pin.PULL_UP) for pin in button_pins] # ============================================================ # COLOR PALETTE # ============================================================ colors = [ (255, 0, 0), # 0 Red (0, 255, 0), # 1 Green (0, 0, 255), # 2 Blue (255, 255, 0), # 3 Yellow (0, 255, 255), # 4 Cyan (255, 0, 255), # 5 Magenta (255, 128, 0), # 6 Orange (128, 0, 255), # 7 Purple (255, 20, 147), # 8 Pink (128, 255, 0), # 9 Lime (255, 255, 255) # 10 White ] # ============================================================ # STATE FOR PIXELS 0–2 (BUTTON CONTROLLED) # ============================================================ color_index = [0, 0, 0] brightness = [50, 50, 50] last_state = [1, 1, 1] press_time = [0, 0, 0] # ============================================================ # HEARTBEAT PIXEL CONFIG # ============================================================ FLASH_COLOR_INDEX = 7 # choose from palette (0–10) FLASH_BRIGHTNESS = 100 FLASH_INTERVAL_MS = 500 # speed of heartbeat blink heartbeat = HeartbeatNeoPixel( neopixel_obj=single, pixel_index=0, color=colors[FLASH_COLOR_INDEX], brightness=FLASH_BRIGHTNESS, interval_ms=FLASH_INTERVAL_MS ) # ============================================================ # HELPER FUNCTIONS # ============================================================ def apply_brightness(color, level): r, g, b = color factor = level / 100 return (int(r * factor), int(g * factor), int(b * factor)) def update_strip(): for i in range(STRIP_LEDS): strip[i] = apply_brightness(colors[color_index[i]], brightness[i]) strip.write() # ============================================================ # INITIAL STATE # ============================================================ update_strip() # ============================================================ # MAIN LOOP # ============================================================ while True: now = time.ticks_ms() # -------------------------------------------- # BUTTON HANDLING FOR PIXELS 0, 1, 2 # -------------------------------------------- for i in range(3): state = buttons[i].value() if last_state[i] == 1 and state == 0: press_time[i] = now if last_state[i] == 0 and state == 1: duration = time.ticks_diff(now, press_time[i]) if duration > 500: # LONG PRESS → brightness brightness[i] += 10 if brightness[i] > 100: brightness[i] = 10 else: # SHORT PRESS → next color color_index[i] = (color_index[i] + 1) % len(colors) update_strip() time.sleep_ms(200) # debounce last_state[i] = state # -------------------------------------------- # HEARTBEAT PIXEL UPDATE (GP28) # -------------------------------------------- heartbeat.update() time.sleep_ms(10) ex[i] = (color_index[i] + 1) % len(colors) update_strip() time.sleep_ms(200) # debounce last_state[i] = state # ----------------------------- # FLASHING SINGLE PIXEL (GP28) # ----------------------------- # if time.ticks_diff(now, last_flash_time) >= FLASH_INTERVAL_MS: # flash_on = not flash_on # last_flash_time = now # # if flash_on: # single_on() # else: # single_off() time.sleep_ms(10)