diff --git a/colorbar-fastloop.py b/colorbar-fastloop.py index 0f3e3b8..a140d49 100644 --- a/colorbar-fastloop.py +++ b/colorbar-fastloop.py @@ -15,7 +15,7 @@ brightness = 0.1 pixels = neopixel.NeoPixel( pixel_pin, num_pixels, - brightness = brightness, + brightness=brightness, auto_write=False, pixel_order="GRBW" ) @@ -34,6 +34,37 @@ pixels.show() # END Neopixel setup #### +# 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 +# be updated during the current update interval, and then +# call pixels.show() after all pixels have been set. It's +# up to the calling logic to calculate whether the yellow +# or red parameters should be set to True. Behavior when +# red and yellow are both set to True depends on how the +# colormode is configured. +def colorizer(pxnum, colormode, yellow=False, red=False): + # Every pixel from lowest to currently highest + if colormode == "fill": + if red: + pixels[pxnum] = RED + elif yellow: + pixels[pxnum] = YELLOW + else: + pixels[pxnum] = GREEN + elif colormode == "candybar": + if pixels[pxnum] == BLANK: + if red: + pixels[pxnum] = RED + elif yellow: + pixels[pxnum] = YELLOW + else: + pixels[pxnum] = GREEN + else: + pass + else: + # Invalid colormodes end up here + raise Exception("Invalid colormode: " + colormode) # Count down from the given total seconds, using the chosen # colormode (how the colors are filled into each pixel), @@ -41,7 +72,12 @@ pixels.show() # that the bar should show yellow), and redtime (same as # yellowtime). The colormode determines what happens at # yellowtime and redtime. -def countdown(seconds, colormode="fill", yellowtime=120, redtime=60, update_interval=1): +def countdown( + seconds, + colormode="fill", + yellowtime=120, + redtime=60, + update_interval=1): # Turn all pixels off pixels.fill(BLANK) @@ -53,10 +89,16 @@ def countdown(seconds, colormode="fill", yellowtime=120, redtime=60, update_inte # Init the elapsed time variable elapsed_time = 0 - # Pre-calculate rtime and ytime - rtime = seconds - redtime - ytime = seconds - yellowtime - + # This begins what I like to call the "Are We There Yet?" + # loop. Instead of making the script wait for an interval + # before continuing as a form of forced timed pacing, we + # simply write an infinite loop that will iterate very + # quickly between update intervals, essentially repeatedly + # asking the CPU to calculate whether it's time to do an + # update yet. The high frequency of the update interval + # checks will make sure our update is fired on-time. + # + # ...unless we decide to configure a way to kill the loop entirely, I guess...? ;) while True: # Get the current time now = time.monotonic() @@ -64,13 +106,21 @@ def countdown(seconds, colormode="fill", yellowtime=120, redtime=60, update_inte # Is it time for an update yet? if now >= last_update_time + update_interval: - # d the last update time + # Update the last update time last_update_time = now # Do update stuff + + # Loop over every pixel ID that should be lit + # based on the elapsed time for pixel in range(round(num_pixels * (elapsed_time / seconds))): # Set pixel color stuff - pass + if elapsed_time >= seconds - redtime: + colorizer(pixel, colormode, red=True) + elif elapsed_time >= seconds - yellowtime: + colorizer(pixel, colormode, yellow=True) + else: + colorizer(pixel, colormode) # Display the result IRL pixels.show()