Skip to content

Commit 42eb4a4

Browse files
authored
Code for new guide Infinity Mirror Collar
https://learn.adafruit.com/admin/guides/3223/editor/21466
1 parent ad144b2 commit 42eb4a4

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

ItsyBitsy_Infinity_Collar/code.py

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
"""
2+
Code for the LED Infinity Mirror Collar. Allows the animation sequence
3+
and color to be controlled by input from the Adafruit Bluefruit App
4+
"""
5+
import board
6+
import random
7+
import neopixel
8+
import digitalio
9+
from adafruit_debouncer import Debouncer
10+
11+
# LED Animation modules
12+
from adafruit_led_animation.animation.comet import Comet
13+
from adafruit_led_animation.animation.chase import Chase
14+
from adafruit_led_animation.animation.rainbowcomet import RainbowComet
15+
from adafruit_led_animation.animation.pulse import Pulse
16+
from adafruit_led_animation.sequence import AnimationSequence
17+
from adafruit_led_animation.color import colorwheel
18+
19+
20+
# Bluetooth modules
21+
from adafruit_ble import BLERadio
22+
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
23+
from adafruit_ble.services.nordic import UARTService
24+
from adafruit_bluefruit_connect.packet import Packet
25+
from adafruit_bluefruit_connect.color_packet import ColorPacket
26+
from adafruit_bluefruit_connect.button_packet import ButtonPacket
27+
28+
# NeoPixel control pin
29+
pixel_pin = board.D5
30+
31+
# Number of pixels in the collar (arranged in two rows)
32+
pixel_num = 24
33+
34+
pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.5, auto_write=False)
35+
36+
# Create a switch from the ItsyBity's on-board pushbutton to toggle charge mode
37+
mode_pin = digitalio.DigitalInOut(board.SWITCH)
38+
mode_pin.direction = digitalio.Direction.INPUT
39+
mode_pin.pull = digitalio.Pull.UP
40+
switch = Debouncer(mode_pin)
41+
42+
# Create the animations
43+
comet = Comet(pixels, speed=0.06, color=(180,0,255), tail_length=10, bounce=True)
44+
chase = Chase(pixels, speed=0.05, size=3, spacing=3, color=(0,255,255), reverse=True)
45+
rainbow_comet = RainbowComet(pixels, speed=.06)
46+
pulse = Pulse(pixels, speed=.04, color=(255,0,0), period = 0.2)
47+
48+
49+
# Our animations sequence
50+
seconds_per_animation = 10
51+
animations = AnimationSequence(comet, rainbow_comet, chase, advance_interval=seconds_per_animation, auto_clear=True)
52+
# Current display determines whether we are showing the animation sequence or the pulse animation
53+
current_display = animations
54+
55+
# Mode changes the color of random animations randomly
56+
random_color_mode = True
57+
58+
def random_animation_color(anims):
59+
if random_color_mode:
60+
anims.color = colorwheel(random.randint(0,255))
61+
62+
animations.add_cycle_complete_receiver(random_animation_color)
63+
64+
65+
# After we complete three pulse cycles, return to main animations list
66+
def pulse_finished(anim):
67+
global current_display
68+
current_display = animations
69+
70+
pulse.add_cycle_complete_receiver(pulse_finished)
71+
pulse.notify_cycles = 3
72+
73+
74+
# Bluetooth
75+
ble = BLERadio()
76+
uart_service = UARTService()
77+
advertisement = ProvideServicesAdvertisement(uart_service)
78+
79+
# Set charge_mode to True to turn off the LED Animations and Bluetooth
80+
# e.g. when charging the battery
81+
charge_mode = False
82+
83+
# Checks the ItsyBitsy's switch button
84+
def check_switch():
85+
global charge_mode
86+
switch.update()
87+
if switch.fell: #Switch changed state
88+
charge_mode = not charge_mode
89+
# if display has just been turned off, clear all LEDs, disconnect, stop advertising
90+
if charge_mode:
91+
pixels.fill((0,0,0))
92+
pixels.show()
93+
if ble.connected:
94+
for conn in ble.connections:
95+
conn.disconnect()
96+
if ble.advertising:
97+
ble.stop_advertising()
98+
99+
# Main program loop
100+
while True:
101+
# Check whether charge mode has been changed
102+
check_switch()
103+
if charge_mode:
104+
pass
105+
else:
106+
current_display.animate()
107+
if ble.connected:
108+
if uart_service.in_waiting:
109+
#Packet is arriving
110+
packet = Packet.from_stream(uart_service)
111+
if isinstance(packet, ButtonPacket) and packet.pressed:
112+
if packet.button == ButtonPacket.BUTTON_1:
113+
# Animation colors change to a random new value after every animation sequence
114+
random_color_mode = True
115+
elif packet.button == ButtonPacket.BUTTON_2:
116+
# Animation colors stay the same unless manually changed
117+
random_color_mode = False
118+
elif packet.button == ButtonPacket.BUTTON_3:
119+
# Stay on the same animation
120+
animations._advance_interval = None
121+
elif packet.button == ButtonPacket.BUTTON_4:
122+
# Auto-advance animations
123+
animations._advance_interval = seconds_per_animation*1000
124+
elif packet.button == ButtonPacket.LEFT:
125+
# Go to first animation in the sequence
126+
animations.activate(0)
127+
elif packet.button == ButtonPacket.RIGHT:
128+
# Go to the next animation in the sequence
129+
animations.next()
130+
elif isinstance(packet, ColorPacket):
131+
animations.color = packet.color
132+
pulse.color = packet.color
133+
# temporarily change to pulse display to show off the new color
134+
current_display = pulse
135+
136+
else:
137+
if not ble.advertising:
138+
ble.start_advertising(advertisement)

0 commit comments

Comments
 (0)