led_animation.py
1 # SPDX-FileCopyrightText: 2024 Jeff Epler, written for Adafruit Industries 2 # SPDX-FileCopyrightText: 2021 Scott Shawcroft, written for Adafruit Industries 3 # 4 # SPDX-License-Identifier: MIT 5 6 import time 7 8 import adafruit_pioasm 9 import adafruit_pixelbuf 10 import adafruit_rp1pio 11 import board 12 from adafruit_led_animation.animation.rainbow import Rainbow 13 from adafruit_led_animation.animation.rainbowchase import RainbowChase 14 from adafruit_led_animation.animation.rainbowcomet import RainbowComet 15 from adafruit_led_animation.animation.rainbowsparkle import RainbowSparkle 16 from adafruit_led_animation.sequence import AnimationSequence 17 18 # chosen because it's on a connector on the braincraft hat 19 NEOPIXEL = board.D13 20 21 # NeoPixels are 800khz bit streams. We are choosing zeros as <312ns hi, 936 lo> 22 # and ones as <700 ns hi, 556 ns lo>. 23 # The first two instructions always run while only one of the two final 24 # instructions run per bit. We start with the low period because it can be 25 # longer while waiting for more data. 26 program = """ 27 .program ws2812 28 .side_set 1 29 .wrap_target 30 bitloop: 31 out x 1 side 0 [6]; Drive low. Side-set still takes place before instruction stalls. 32 jmp !x do_zero side 1 [3]; Branch on the bit we shifted out previous delay. Drive high. 33 do_one: 34 jmp bitloop side 1 [4]; Continue driving high, for a one (long pulse) 35 do_zero: 36 nop side 0 [4]; Or drive low, for a zero (short pulse) 37 .wrap 38 """ 39 40 assembled = adafruit_pioasm.assemble(program) 41 42 43 class Pi5Pixelbuf(adafruit_pixelbuf.PixelBuf): 44 def __init__(self, pin, size, **kwargs): 45 self._pin = pin 46 self.sm = adafruit_rp1pio.StateMachine( 47 assembled, 48 frequency=12_800_000, # to get appropriate sub-bit times in PIO program 49 first_sideset_pin=pin, 50 auto_pull=True, 51 out_shift_right=False, 52 pull_threshold=8, 53 ) 54 #print("real frequency", self.sm.frequency) 55 super().__init__(size=size, **kwargs) 56 57 def _transmit(self, buf): 58 self.sm.write(buf) 59 60 pixels = Pi5Pixelbuf(NEOPIXEL, 120, auto_write=True, byteorder="BGR") 61 62 pixels.fill(0x10102) 63 pixels.show() 64 time.sleep(2) 65 66 rainbow = Rainbow(pixels, speed=0.02, period=2) 67 rainbow_chase = RainbowChase(pixels, speed=0.02, size=5, spacing=3) 68 rainbow_comet = RainbowComet(pixels, speed=0.02, tail_length=7, bounce=True) 69 rainbow_sparkle = RainbowSparkle(pixels, speed=0.02, num_sparkles=15) 70 71 72 animations = AnimationSequence( 73 rainbow, 74 rainbow_chase, 75 rainbow_comet, 76 rainbow_sparkle, 77 advance_interval=5, 78 auto_clear=True, 79 ) 80 81 try: 82 while True: 83 animations.animate() 84 finally: 85 time.sleep(.01) 86 pixels.fill(0) 87 pixels.show()