Created
February 5, 2024 22:47
-
-
Save matthewhenderson/38985765c1011ff794a3e173642181c1 to your computer and use it in GitHub Desktop.
Raspberry Pi Sense Hat pomodoro app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ## =========================== | |
| ## Raspberry Pi Pomodoro | |
| ## Requires: Sense Hat | |
| ## | |
| ## Run: Click the center button | |
| ## on the joystick to start a | |
| ## 20 minute Pomodoro timer | |
| ## where the matrix fills up | |
| ## green over the course of | |
| ## the 20 minute time period. | |
| ## =========================== | |
| from sense_hat import SenseHat | |
| import time | |
| import random | |
| sense = SenseHat() | |
| ## ========================== | |
| ## ===== INTRO TOMATO ======= | |
| ## ========================== | |
| def set_tomato_design(tc,sc): | |
| nc = (0, 0, 0) | |
| ## Tomato design matrix | |
| ## tc = tomato body color | |
| ## sc = tomato stem color | |
| ## nc = no color; off | |
| tomato_design = [ | |
| [nc, nc, sc, sc, sc, nc, nc, nc], | |
| [nc, tc, tc, sc, tc, tc, tc, nc], | |
| [tc, tc, tc, tc, tc, tc, tc, tc], | |
| [tc, tc, tc, tc, tc, tc, tc, tc], | |
| [tc, tc, tc, tc, tc, tc, tc, tc], | |
| [tc, tc, tc, tc, tc, tc, tc, tc], | |
| [nc, tc, tc, tc, tc, tc, tc, nc], | |
| [nc, nc, tc, tc, tc, tc, nc, nc] | |
| ] | |
| ## Rotate 180 degrees | |
| rotated_design = [row[::-1] for row in tomato_design[::-1]] | |
| for y in range(8): | |
| for x in range(8): | |
| sense.set_pixel(x, y, rotated_design[y][x]) | |
| def fade_color(start_color, end_color, steps): | |
| fade_steps = [] | |
| r_step = (end_color[0] - start_color[0]) / steps | |
| g_step = (end_color[1] - start_color[1]) / steps | |
| b_step = (end_color[2] - start_color[2]) / steps | |
| for step in range(steps + 1): | |
| r = int(start_color[0] + (r_step * step)) | |
| g = int(start_color[1] + (g_step * step)) | |
| b = int(start_color[2] + (b_step * step)) | |
| fade_steps.append((r, g, b)) | |
| return fade_steps | |
| def throbbing_tomato(duration=2, cycles=8): | |
| bright_red = (255, 0, 0) | |
| dim_red = (128, 0, 0) | |
| bright_green = (0, 255, 0) | |
| dim_green = (0, 128, 0) | |
| steps = 10 | |
| set_tomato_design(bright_red,bright_green) | |
| time.sleep(2) | |
| for _ in range(cycles): | |
| ## ===== Fade in ===== | |
| tomato_color_steps = fade_color(dim_red, bright_red, steps) | |
| stem_color_steps = fade_color(dim_green, bright_green, steps) | |
| for step in range(steps + 1): | |
| set_tomato_design(tomato_color_steps[step], stem_color_steps[step]) | |
| time.sleep(0.1) | |
| ## ===== Fade out ===== | |
| tomato_color_steps = fade_color(bright_red, dim_red, steps) | |
| stem_color_steps = fade_color(bright_green, dim_green, steps) | |
| for step in range(steps + 1): | |
| set_tomato_design(tomato_color_steps[step], stem_color_steps[step]) | |
| time.sleep(0.1) | |
| sense.clear() | |
| ## ========================== | |
| ## === RUNNING POMODORO ===== | |
| ## ========================== | |
| def pomodoro_session(): | |
| sense.clear() | |
| start_time = int(time.time()) | |
| ## Start animation of tomato | |
| throbbing_tomato() | |
| ## Run pomodoro for 20 minutes | |
| ## filling matrix over that time | |
| while True: | |
| current_time = int(time.time()) | |
| elapsed_time = current_time - start_time | |
| update_leds(elapsed_time) | |
| if elapsed_time >= 20 * 60: | |
| break | |
| ## Check for button press while running | |
| events = sense.stick.get_events() | |
| for event in events: | |
| ## Exit if the center button is pressed | |
| if event.action == "pressed" and event.direction == "middle": | |
| return | |
| ## Update LEDs every second | |
| time.sleep(1) | |
| ## Show end animation and clear matrix | |
| fireworks() | |
| sense.clear() | |
| def update_leds(elapsed_time): | |
| green_intensity = 150 | |
| total_leds = 64 | |
| led_per_sequence = 20 * 60 / total_leds | |
| leds_to_light = int(elapsed_time / led_per_sequence) | |
| for led in range(total_leds): | |
| if led < leds_to_light: | |
| sense.set_pixel(led % 8, led // 8, (0, green_intensity, 0)) | |
| else: | |
| sense.set_pixel(led % 8, led // 8, (0, 0, 0)) | |
| ## ========================== | |
| ## === FINAL FIREWORKS ====== | |
| ## ========================== | |
| def fireworks(): | |
| for _ in range(10): | |
| for y in range(8): | |
| for x in range(8): | |
| r = random.randint(0, 255) | |
| g = random.randint(0, 255) | |
| b = random.randint(0, 255) | |
| sense.set_pixel(x, y, (r, g, b)) | |
| time.sleep(0.3) | |
| sense.clear() | |
| ## ========================== | |
| ## ======= EXECUTE ========== | |
| ## ========================== | |
| def main(): | |
| while True: | |
| events = sense.stick.get_events() | |
| for event in events: | |
| if event.action == "pressed" and event.direction == "middle": | |
| pomodoro_session() | |
| ## Delay to reduce CPU usage and allow for button press detection | |
| time.sleep(0.05) | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment