diff --git a/code.py b/code.py index 4c8478c..c2ba390 100644 --- a/code.py +++ b/code.py @@ -6,87 +6,69 @@ import digitalio import microcontroller num_pixels = 10 - -pixels = neopixel.NeoPixel(board.GP5, num_pixels) +pixels = neopixel.NeoPixel(board.GP5, num_pixels, auto_write=False) encoder = rotaryio.IncrementalEncoder(board.GP19, board.GP18) button = digitalio.DigitalInOut(board.GP17) button.direction = digitalio.Direction.INPUT button.pull = digitalio.Pull.UP -# Predefined colors +# Predefined colors and brightness levels colors = [ - (255, 0, 0), # Red - (0, 255, 0), # Green - (0, 0, 255), # Blue - (255, 255, 255), # White - (200, 255, 200), # Cold white - (255, 20, 100), # Warm white + (255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 255), + (200, 255, 200), (255, 20, 100), (0, 0, 0) ] +brightness_levels = [i / 10 for i in range(11)] -# Brightness levels (6 steps, including 0 for off) -brightness_levels = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0] +# Check and initialize non-volatile memory (NVM) +if len(microcontroller.nvm) < 2: + microcontroller.nvm = bytearray(2) + microcontroller.nvm[0] = 8 # Default brightness index + microcontroller.nvm[1] = 0 # Default color index -# Check and initialize non-volatile memory -if len(microcontroller.nvm) < 5: - microcontroller.nvm = bytearray(5) # Initialize with 5 bytes - microcontroller.nvm[0:4] = b"0.80" # Default brightness - microcontroller.nvm[4:5] = (0).to_bytes(1, "little") # Default color index - -# Load settings from non-volatile memory -try: - brightness_index = int(float(microcontroller.nvm[0:4].decode()) * 5) - color_index = int.from_bytes(microcontroller.nvm[4:5], "little") - if color_index >= len(colors): - color_index = 0 # Reset to default if out of range -except ValueError: - brightness_index = 4 # Default brightness (0.8) - color_index = 0 # Default color index (red) +brightness_index = min(microcontroller.nvm[0], len(brightness_levels) - 1) +color_index = min(microcontroller.nvm[1], len(colors) - 1) pixels.brightness = brightness_levels[brightness_index] -current_color = colors[color_index] -pixels.fill(current_color) +pixels.fill(colors[color_index]) +pixels.show() -button_state = None last_encoder_pos = encoder.position +button_state = False -def fade_colors(start_color, end_color, steps=50, delay=0.02): - """Smoothly fade between two colors.""" - for step in range(steps): +def fade_colors(start_color, end_color, steps=20, delay=0.01): + """Smoothly transition between two colors.""" + for step in range(steps + 1): ratio = step / steps - interpolated_color = tuple( + pixels.fill(tuple( int(start_color[i] * (1 - ratio) + end_color[i] * ratio) for i in range(3) - ) - pixels.fill(interpolated_color) + )) + pixels.show() time.sleep(delay) while True: - # Read encoder position for brightness control + # Handle encoder movement for brightness adjustment enc_pos = encoder.position if enc_pos != last_encoder_pos: - step_change = enc_pos - last_encoder_pos - last_encoder_pos = enc_pos - brightness_index = min(max(brightness_index + step_change, 0), len(brightness_levels) - 1) + brightness_index = min(max(brightness_index + (enc_pos - last_encoder_pos), 0), len(brightness_levels) - 1) pixels.brightness = brightness_levels[brightness_index] + pixels.show() + last_encoder_pos = enc_pos print(f"Brightness: {brightness_levels[brightness_index]:.2f}") - # Handle button press to cycle colors - if not button.value and button_state is None: - button_state = "pressed" - elif button.value and button_state == "pressed": - new_color_index = (color_index + 1) % len(colors) - fade_colors(colors[color_index], colors[new_color_index]) - color_index = new_color_index - current_color = colors[color_index] # Update current_color - pixels.fill(current_color) # Apply the new color - print(f"Selected color: {current_color}") - button_state = None - - # Set the pixels to the current color (if not transitioning) - if brightness_levels[brightness_index] > 0.0: # Only fill if brightness > 0 - pixels.fill(current_color) - - # Save settings to non-volatile memory - brightness_value = brightness_levels[brightness_index] - microcontroller.nvm[0:4] = f"{brightness_value:.2f}".encode() # Save brightness as a string (e.g., "0.80") - microcontroller.nvm[4:5] = color_index.to_bytes(1, "little") # Save color index as a single byte + # Handle button press for color change + if not button.value: + if not button_state: + new_color_index = (color_index + 1) % len(colors) + fade_colors(colors[color_index], colors[new_color_index]) + color_index = new_color_index + pixels.fill(colors[color_index]) + pixels.show() + print(f"Selected color: {colors[color_index]}") + button_state = True # Prevent multiple detections + else: + button_state = False # Reset when button is released + # Save settings only if they have changed + if microcontroller.nvm[0] != brightness_index or microcontroller.nvm[1] != color_index: + microcontroller.nvm[0] = brightness_index + microcontroller.nvm[1] = color_index diff --git a/neopixel.mpy b/neopixel.mpy new file mode 100644 index 0000000..5291001 Binary files /dev/null and b/neopixel.mpy differ