From c549c200ca4edc5e991654e1190a1f2435dc4e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ebbe=20Ba=C3=9F?= Date: Sat, 7 Dec 2024 21:36:08 +0100 Subject: [PATCH] added better color selection and brightness comtrol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ebbe Baß --- code.py | 112 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 45 deletions(-) diff --git a/code.py b/code.py index 8dfeb4a..e6c5571 100644 --- a/code.py +++ b/code.py @@ -3,67 +3,89 @@ import rotaryio import neopixel import time import digitalio +import microcontroller num_pixels = 10 pixels = neopixel.NeoPixel(board.GP5, num_pixels) - encoder = rotaryio.IncrementalEncoder(board.GP19, board.GP18) - button = digitalio.DigitalInOut(board.GP17) button.direction = digitalio.Direction.INPUT button.pull = digitalio.Pull.UP -button_state = None # Initialize button state to None +# Predefined colors +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 +] -lamp_state = True # Initialize lamp state to True (on) +# Brightness levels (6 steps, including 0 for off) +brightness_levels = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0] -cold_white = (200, 255, 200) -white = (255, 255, 255) -warm_white = (255, 20, 100) +# 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 -def interpolate_color(encoder_pos): - if encoder_pos <= -25: - return cold_white - elif encoder_pos >= 25: - return warm_white - else: - ratio = (encoder_pos + 25) / 50.0 - inverted_ratio = 1.0 - ratio - interpolated_color = tuple(int(cold_white[i] * inverted_ratio + warm_white[i] * ratio) for i in range(3)) - return interpolated_color - -fading_in_progress = False # Flag to indicate if fading animation is in progress +# 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) +pixels.brightness = brightness_levels[brightness_index] +current_color = colors[color_index] +pixels.fill(current_color) + +button_state = None +last_encoder_pos = encoder.position + +def fade_colors(start_color, end_color, steps=50, delay=0.02): + """Smoothly fade between two colors.""" + for step in range(steps): + ratio = step / steps + interpolated_color = tuple( + int(start_color[i] * (1 - ratio) + end_color[i] * ratio) for i in range(3) + ) + pixels.fill(interpolated_color) + time.sleep(delay) while True: + # Read encoder position for brightness control enc_pos = encoder.position - enc_pos = min(max(enc_pos, -25), 25) - print(enc_pos) - - # Process button press + 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) + pixels.brightness = brightness_levels[brightness_index] + 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" - print("pressed") elif button.value and button_state == "pressed": - lamp_state = not lamp_state # Toggle lamp state - button_state = None # Reset button state - fading_in_progress = True # Set flag to indicate fading animation is in progress - - # Perform fading animation if lamp state changed - if fading_in_progress: - if lamp_state: # Fade in - for brightness in range(255): - pixels.brightness = brightness / 255.0 - time.sleep(0.2/255) - pixels.brightness = 1.0 # Ensure full brightness is set - else: # Fade out - for brightness in range(255, -1, -1): - pixels.brightness = brightness / 255.0 - time.sleep(0.2/255) - pixels.brightness = 0.0 # Ensure brightness is completely off - fading_in_progress = False # Reset flag once fading animation is complete - - # Calculate and set current color - current_color = interpolate_color(enc_pos) - pixels.fill(current_color) + 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() + microcontroller.nvm[4:5] = color_index.to_bytes(1, "little")