import machine
import neopixel
import time
# Pin configurations
PIN = 5
LED_COUNT = 16
POTENTIOMETER_PIN = 2
BUTTON_PIN = 13
POT_MAX_VALUE = 4095
# Initialization
np = neopixel.NeoPixel(machine.Pin(PIN), LED_COUNT)
pot = machine.ADC(machine.Pin(POTENTIOMETER_PIN))
button = machine.Pin(BUTTON_PIN, machine.Pin.IN, machine.Pin.PULL_UP)
# Define the colors for up to 8 players
SEGMENT_COLORS = [
(0, 255, 0), (0, 0, 255), (255, 165, 0), (255, 0, 0),
(255, 255, 0), (75, 0, 130), (255, 20, 147), (0, 255, 255)
]
# Mode settings
SET_PLAYER_COUNT = 0
SET_TIMER_DURATION = 1
TIMER_RUNNING = 2
# Initial settings
mode = SET_PLAYER_COUNT
player_count = 6
timer_duration = 10 # Default to 10 seconds
leds_on = LED_COUNT # Initialize the variable to keep track of the number of LEDs that are currently on
current_player = 0 # Initialize the current player index
# Timer states
RUNNING = 1
PAUSED = 0
state = PAUSED
def get_player_count():
pot_value = pot.read()
return max(2, round((pot_value / POT_MAX_VALUE) * (len(SEGMENT_COLORS) - 1)) + 1)
def display_segments(player_count):
np.fill((0, 0, 0)) # Clear the LEDs first
segment_length = LED_COUNT // player_count
extra_leds = LED_COUNT % player_count
led_index = 0
for i in range(player_count):
color = SEGMENT_COLORS[i % len(SEGMENT_COLORS)]
for _ in range(segment_length + (1 if i < extra_leds else 0)):
np[led_index] = color
led_index += 1
np.write()
def get_timer_duration():
pot_value = pot.read()
return max(10, round((pot_value / POT_MAX_VALUE) * 60)) # 10 to 60 seconds
def update_leds_for_duration(duration):
"""Updates LEDs based on the timer duration selected using the potentiometer."""
led_count = round((duration - 10) / 50 * (LED_COUNT - 1) + 1)
np.fill((0, 0, 0)) # Clear all LEDs
for i in range(led_count):
np[i] = (255, 255, 255) # Set LEDs to white based on the timer duration
np.write()
def check_timer_duration_change():
"""Checks and updates the timer duration setting from the potentiometer."""
global timer_duration
current_duration = get_timer_duration()
if current_duration != timer_duration:
timer_duration = current_duration
update_leds_for_duration(timer_duration)
def start_timer():
global state, last_update_time, leds_on
state = RUNNING
leds_on = LED_COUNT # Reset LEDs to full on start
last_update_time = time.ticks_ms()
np.fill((0, 255, 0)) # Set all LEDs to green
np.write()
print("Timer started")
def pause_timer():
global state
if state == RUNNING:
state = PAUSED
print("Timer paused")
def resume_timer():
global state, last_update_time
if state == PAUSED:
state = RUNNING
last_update_time = time.ticks_ms() # Reset the last update time to avoid jump in countdown
print("Timer resumed")
def update_timer_setting_display():
"""Updates the LED display to show the current timer setting."""
duration = get_timer_duration()
led_count = round((duration - 10) / 50 * (LED_COUNT - 1) + 1)
np.fill((0, 0, 0)) # Clear all LEDs
for i in range(led_count):
np[i] = (255, 255, 255) # Set LEDs to white based on the timer duration
np.write()
def display_segments(player_count):
np.fill((0, 0, 0)) # Clear the LEDs first
segment_length = LED_COUNT // player_count
extra_leds = LED_COUNT % player_count
led_index = 0
for i in range(player_count):
color = SEGMENT_COLORS[i % len(SEGMENT_COLORS)] # Use modulo for safety
for _ in range(segment_length + (1 if i < extra_leds else 0)):
np[led_index] = color
led_index += 1
np.write()
def button_press():
"""Handles button press events for mode transitions and function activation."""
global mode, state, timer_duration
if not button.value(): # Check if the button is pressed
time.sleep(0.05) # Debounce delay
if not button.value(): # Confirm button press
while not button.value(): # Wait until the button is released
time.sleep(0.01)
if mode == SET_TIMER_DURATION:
# Transition between states if in timer setting mode
if state == PAUSED:
start_timer() # Start the timer if paused
elif state == RUNNING:
pause_timer() # Pause the timer if running
elif state == PAUSED:
resume_timer() # Resume the timer if paused
elif mode == SET_PLAYER_COUNT:
mode = SET_TIMER_DURATION # Move to timer duration setting mode
timer_duration = get_timer_duration()
update_leds_for_duration(timer_duration) # Show timer setting visually
def update_timer():
global last_update_time, leds_on, state, current_player, player_count
if state != RUNNING:
return # Only update if the timer is running
current_time = time.ticks_ms()
interval = (timer_duration * 1000) // LED_COUNT # Total duration divided by the number of LEDs
if time.ticks_diff(current_time, last_update_time) >= interval:
last_update_time = current_time
leds_on -= 1 # Decrease the number of LEDs to be lit
np.fill((0, 0, 0)) # Clear all LEDs first
# Light up the remaining LEDs in the current player's color
for i in range(leds_on):
np[i] = SEGMENT_COLORS[current_player % len(SEGMENT_COLORS)]
np.write()
if leds_on == 0:
state = PAUSED # Pause the timer after the last LED is turned off
current_player = (current_player + 1) % player_count # Move to the next player
leds_on = LED_COUNT # Reset the LEDs for the next round
display_segments(player_count) # Display the current player's color
print("Timer finished, switch to player", current_player + 1)
def main_loop():
global mode, state, timer_duration
while True:
button_press()
if mode == SET_PLAYER_COUNT:
current_player_count = get_player_count()
if current_player_count != player_count:
player_count = current_player_count
display_segments(player_count)
elif mode == SET_TIMER_DURATION:
current_duration = get_timer_duration()
if current_duration != timer_duration:
timer_duration = current_duration
update_timer_setting_display() # Update display to reflect current timer duration
if state == RUNNING:
update_timer()
time.sleep(0.01) # Sleep to prevent excessive CPU usage
# Display initial player count
player_count = get_player_count()
display_segments(player_count)
while True:
button_press()
if mode == SET_PLAYER_COUNT:
current_player_count = get_player_count()
if current_player_count != player_count:
player_count = current_player_count
display_segments(player_count)
elif mode == SET_TIMER_DURATION:
current_duration = get_timer_duration()
if current_duration != timer_duration:
timer_duration = current_duration
update_timer_setting_display() # Update display to reflect current timer duration
if state == RUNNING:
update_timer()
time.sleep(0.01) # Sleep to prevent excessive CPU usage
# At the bottom of your script file
if __name__ == "__main__":
main_loop() # Or use your current while loop if preferred