# Standalone MicroPython Voice Animation: Update Progress # Exposes run(text="", frames=...) and runs automatically if executed directly. import time try: import board_config display = getattr(board_config, 'display_instance', None) except Exception: board_config = None display = None def draw_center_text(d, msg, y, w, scale=1, c=1): char_w = 8 * scale x = max(0, (w - len(msg) * char_w) // 2) if hasattr(d, 'text_large') and scale > 1: try: d.text_large(msg, x, y, scale, c) return except Exception: pass d.text(msg, x, y, c) def run(text="", frames=100): if not display: print("board_config.display_instance is not available. Skipping animation.") return width = getattr(display, 'width', 400) height = getattr(display, 'height', 300) cx, cy = width // 2, height // 2 frame = 0 try: while True: if frames is not None and frames > 0 and frame >= frames: break display.clear(0) # Draw a sliding downward-pointing arrow in the top half # Offset slides down and wraps around to create motion arrow_slide = (frame * 3) % 24 ay = cy - 45 + arrow_slide # Arrow Shaft display.fill_rect(cx - 6, ay - 24, 12, 24, 1) # Arrow Head (triangle) display.line(cx - 18, ay, cx, ay + 15, 1) display.line(cx + 18, ay, cx, ay + 15, 1) display.line(cx - 18, ay, cx + 18, ay, 1) # Fill the head slightly display.fill_rect(cx - 6, ay, 12, 8, 1) # Draw static receiver container (horizontal tray) below the arrow path tray_y = cy + 12 display.line(cx - 30, tray_y, cx - 30, tray_y + 10, 1) display.line(cx - 30, tray_y + 10, cx + 30, tray_y + 10, 1) display.line(cx + 30, tray_y + 10, cx + 30, tray_y, 1) # Calculate update progress percentage # (Cycles 0 to 100 over 25 frames, or follows frame count) percent = (frame * 4) % 101 # Progress bar outline bar_y = cy + 45 display.rect(cx - 90, bar_y, 180, 16, 1) # Progress bar fill fill_width = int(176 * percent / 100) if fill_width > 0: display.fill_rect(cx - 88, bar_y + 2, fill_width, 12, 1) # Draw label + percentage text label = text if text else "UPDATING SYSTEM..." pct_label = f"{label} {percent}%" draw_center_text(display, pct_label, height - 30, width, scale=1, c=1) display.show() frame += 1 try: time.sleep_ms(55) except AttributeError: time.sleep(0.055) except KeyboardInterrupt: print("Animation interrupted by user.") if __name__ in ('__main__', '__name__'): run()