/
colorschemes.py
103 lines (85 loc) · 4.33 KB
/
colorschemes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""This module contains a few concrete colour cycles to play with"""
from colorcycletemplate import ColorCycleTemplate
class StrandTest(ColorCycleTemplate):
"""Runs a simple strand test (9 LEDs wander through the strip)."""
color = None
def init(self, strip, num_led):
self.color = 0x000000 # Initialize with black
def update(self, strip, num_led, num_steps_per_cycle, current_step,
current_cycle):
# One cycle = The 9 Test-LEDs wander through numStepsPerCycle LEDs.
if current_step == 0:
self.color >>= 8 # Red->green->blue->black
if self.color == 0:
self.color = 0xFF0000 # If black, reset to red
len = 9
if num_led - 1 < len:
len = num_led - 1
# The head pixel that will be turned on in this cycle
head = (current_step + len) % num_steps_per_cycle
tail = current_step # The tail pixel that will be turned off
strip.set_pixel_rgb(head, self.color) # Paint head
strip.set_pixel_rgb(tail, 0) # Clear tail
return 1 # Repaint is necessary
class TheaterChase(ColorCycleTemplate):
"""Runs a 'marquee' effect around the strip."""
def update(self, strip, num_led, num_steps_per_cycle, current_step,
current_cycle):
# One cycle = One trip through the color wheel, 0..254
# Few cycles = quick transition, lots of cycles = slow transition
# Note: For a smooth transition between cycles, numStepsPerCycle must
# be a multiple of 7
start_index = current_step % 7 # One segment is 2 blank, and 5 filled
color_index = strip.wheel(int(round(255/num_steps_per_cycle *
current_step, 0)))
for pixel in range(num_led):
# Two LEDs out of 7 are blank. At each step, the blank
# ones move one pixel ahead.
if ((pixel+start_index) % 7 == 0) or ((pixel+start_index) % 7 == 1):
strip.set_pixel_rgb(pixel, 0)
else: strip.set_pixel_rgb(pixel, color_index)
return 1
class RoundAndRound(ColorCycleTemplate):
"""Runs three LEDs around the strip."""
def init(self, strip, num_led):
strip.set_pixel_rgb(0, 0xFF0000)
strip.set_pixel_rgb(1, 0xFF0000, 5) # Only 5% brightness
strip.set_pixel_rgb(2, 0xFF0000)
def update(self, strip, num_led, num_steps_per_cycle, current_step,
current_cycle):
# Simple class to demonstrate the "rotate" method
strip.rotate()
return 1
class Solid(ColorCycleTemplate):
"""Paints the strip with one colour."""
def init(self, strip, num_led):
for led in range(0, num_led):
strip.set_pixel_rgb(led,0xFFFFFF,5) # Paint 5% white
def update(self, strip, num_led, num_steps_per_cycle, current_step,
current_cycle):
# Do nothing: Init lit the strip, and update just keeps it this way
return 0
class Rainbow(ColorCycleTemplate):
"""Paints a rainbow effect across the entire strip."""
def update(self, strip, num_led, num_steps_per_cycle, current_step,
current_cycle):
# One cycle = One trip through the color wheel, 0..254
# Few cycles = quick transition, lots of cycles = slow transition
# -> LED 0 goes from index 0 to 254 in numStepsPerCycle cycles.
# So it might have to step up more or less than one index
# depending on numStepsPerCycle.
# -> The other LEDs go up to 254, then wrap around to zero and go up
# again until the last one is just below LED 0. This way, the
# strip always shows one full rainbow, regardless of the
# number of LEDs
scale_factor = 255 / num_led # Index change between two neighboring LEDs
start_index = 255 / num_steps_per_cycle * current_step # LED 0
for i in range(num_led):
# Index of LED i, not rounded and not wrapped at 255
led_index = start_index + i * scale_factor
# Now rounded and wrapped
led_index_rounded_wrapped = int(round(led_index, 0)) % 255
# Get the actual color out of the wheel
pixel_color = strip.wheel(led_index_rounded_wrapped)
strip.set_pixel_rgb(i, pixel_color)
return 1 # All pixels are set in the buffer, so repaint the strip now