diff --git a/colorbar-fastloop.py b/colorbar-fastloop.py index c525d20..719a0d9 100644 --- a/colorbar-fastloop.py +++ b/colorbar-fastloop.py @@ -2,6 +2,35 @@ import time import board import neopixel import adafruit_datetime as datetime +from adafruit_seesaw import seesaw, rotaryio, digitalio +import busio + + +#### +# i2c bus setup + +SDA = board.GP0 +SCL = board.GP1 +i2c = busio.I2C(SCL, SDA) + +# END i2c bus setup +#### + + +#### +# Rotary Encoder setup + +seesaw = seesaw.Seesaw(i2c, 0x36) + +seesaw.pin_mode(24, seesaw.INPUT_PULLUP) +button = digitalio.DigitalIO(seesaw, 24) +button_held = False + +encoder = rotaryio.IncrementalEncoder(seesaw) +last_position = -1 + +# END Rotary Encoder setup +#### #### @@ -35,6 +64,13 @@ pixels.show() # END Neopixel setup #### + +# Use datetime.timedelta to convert an int of seconds to a +# string with the format MM:SS +def prettytime(seconds): + return str(datetime.timedelta(seconds=abs(seconds)))[2:] + + # Set the color on a single neopixel based on colormode and # whether yellowtime or redtime has been reached. Calling # logic should iterate over every neopixel ID that should @@ -168,8 +204,129 @@ def countdown( display_time_sign = "-" else: display_time_sign = " " - print("current time: " + display_time_sign + display_time) + # Give the user feedback + # (this string will eventually go to a ssd1306 OLED display via + # displayio, but just put it on the terminal output for now) + print("current time: " + display_time_sign + prettytime(current_time)) + + # If the button is currently being pressed + if not button.value: + # We are paused + pause = True + # There's no long-press option before pausing, so button should + # no longer be down. + button_held = False + print("Timer Paused") + # Keep looping here as long as we're paused + while pause: + # If the button is being pressed + if not button.value and not button_held: + # The button is being held down + button_held = True + # Record when the button started being pressed + button_held_timer = time.monotonic() + # Keep looping while the button is down + while not button.value: + # Continually check if button_hold_delay has elapsed + # while the button is still down + if time.monotonic() - button_held_timer > button_hold_delay: + # Button should no longer be down + button_held = False + # Reset the long-press timer as a debounce method + button_held_timer = time.monotonic() + # No longer in pause mode + pause = False + # Give the user feedback + print("Timer Reset") + # Hang around for half a second for debounce + time.sleep(0.5) + # Return from countdown() back to the main loop + return + # If the button is not being pressed and button_held is True. + # I don't understand why, but it gets hung up here sometimes, + # requiring the user to press the button multiple times to + # resume the timer again... + if button.value and button_held: + # Flip it back to False + button_held = False + # If the button is being short-pressed when it previously wasn't + # being pressed, and we are paused. + if not button.value and not button_held and pause: + # Flip it back to False + button_held = False + # Exiting pause + pause = False + # User Feedback + print("Timer Resumed") + # Hang around for half a second for debounce + time.sleep(0.5) +# Hard-coded initial value. (will replace with stored value later) +set_time_orig = 120 +set_time = set_time_orig + +# How many seconds should be added to or subtracted from set_time +# for every encoder click +set_time_step = 60 + +# How long is a long-press in seconds +button_hold_delay = 2 +# Main loop +while True: + + # Negate the position to make clockwise rotation positive + position = -encoder.position + + # If the encoder position has changed since last iteration + if position != last_position: + # If last_position is set to -1, assume it's just been + # initialized, so don't adjust anything + if last_position == -1: + pass + # Clockwise turn increases set_time by set_time_step + elif position > last_position: + set_time += set_time_step + # Counter-clockwise turn decreases set_time by set_time_step + # only until 0 + elif set_time > 0: + set_time -= set_time_step + # Update the position tracker + last_position = position + # User feedback + print("Current set time: " + prettytime(set_time)) + # If the button is being pressed, and button_held is False + if not button.value and not button_held: + # Button is being pressed + button_held = True + # Capture the current monotonic clock time to later detect a long-press + button_held_timer = time.monotonic() + # Keep looping while the button is down + while not button.value: + # Continually check if button_hold_delay has elapsed + # while the button is still down + if time.monotonic() - button_held_timer > button_hold_delay: + # Reset the set_time to the value of set_time_orig + # (eventually, set_time_orig will be read from persistent config) + set_time = set_time_orig + # Give the user feedback + print("Time reset to: " + prettytime(set_time)) + # Button should no longer be down + button_held = False + # Reset the long-press timer as a debounce method + button_held_timer = time.monotonic() + + # If the button is not being pressed, and it previously was being pressed + if button.value and button_held: + # Button is no longer being pressed + button_held = False + # Start the countdown using the configured set_time + countdown(set_time) + # Once the timer has been reset, re-init last_position. + # In effect, this will display the set_time to the user again + last_position = -1 + # Turn off all pixels + pixels.fill(BLANK) + pixels.show()