# Standalone MicroPython Voice Animation: Working Gears # Exposes run(text="", frames=...) and runs automatically if executed directly. import time import math 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 draw_gear(d, gcx, gcy, r, teeth_count, rotation, c=1): # Draw gear boundary d.rect(gcx - r, gcy - r, r * 2, r * 2, c) # Inner shaft hole d.fill_rect(gcx - 5, gcy - 5, 10, 10, c) d.fill_rect(gcx - 2, gcy - 2, 4, 4, 0) # Draw gear teeth extending outwards for i in range(teeth_count): angle = rotation + i * (2 * math.pi / teeth_count) # Inner teeth start x1 = gcx + int((r - 2) * math.cos(angle)) y1 = gcy + int((r - 2) * math.sin(angle)) # Outer teeth end x2 = gcx + int((r + 10) * math.cos(angle)) y2 = gcy + int((r + 10) * math.sin(angle)) d.line(x1, y1, x2, y2, c) # Add tiny horizontal heads to teeth for thickness perp_angle = angle + math.pi / 2 tx1 = x2 - int(3 * math.cos(perp_angle)) ty1 = y2 - int(3 * math.sin(perp_angle)) tx2 = x2 + int(3 * math.cos(perp_angle)) ty2 = y2 + int(3 * math.sin(perp_angle)) d.line(tx1, ty1, tx2, ty2, 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 label = text if text else "WORKING..." frame = 0 try: while True: if frames is not None and frames > 0 and frame >= frames: break display.clear(0) # Draw two rotating, interlocking gears # Large Gear (Left & slightly up) rot1 = frame * 0.08 draw_gear(display, cx - 45, cy - 10, r=32, teeth_count=8, rotation=rot1, c=1) # Small Gear (Right & slightly down) # Rotates counter-clockwise, offset to interlock teeth rot2 = -frame * 0.106 + (math.pi / 8) draw_gear(display, cx + 45, cy + 20, r=24, teeth_count=6, rotation=rot2, c=1) # Little decorative background computer dots dot_phase = (frame // 4) % 4 for i in range(4): fill_color = 1 if i == dot_phase else 0 display.rect(cx - 80 + i * 16, cy + 70, 8, 8, 1) if fill_color: display.fill_rect(cx - 78 + i * 16, cy + 72, 4, 4, 1) # Draw centered text label at the bottom draw_center_text(display, label, height - 30, width, scale=1, c=1) display.show() frame += 1 try: time.sleep_ms(50) except AttributeError: time.sleep(0.05) except KeyboardInterrupt: print("Animation interrupted by user.") if __name__ in ('__main__', '__name__'): run()