Skip to content

Commit e20caf4

Browse files
author
Melissa LeBlanc-Williams
committed
Added Palette Rotation Example
1 parent edefe7e commit e20caf4

File tree

4 files changed

+252
-12
lines changed

4 files changed

+252
-12
lines changed

adafruit_featherwing/dotstar_featherwing.py

Lines changed: 160 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
import board
3535
import adafruit_dotstar as dotstar
3636

37+
# Library Function Ideas
38+
# Gradient (probably just for example)
39+
# 20 40 60 80 100
40+
3741
class DotStarFeatherWing:
3842
"""Class representing a `DotStar FeatherWing
3943
<https://www.adafruit.com/product/3449>`_.
@@ -48,21 +52,168 @@ def __init__(self, clock=board.D13, data=board.D11, brightness=0.2):
4852
self.rows = 6
4953
self.columns = 12
5054
self._brightness = brightness
55+
self._auto_write = True
5156
self._dotstar = dotstar.DotStar(clock, data, self.rows * self.columns,
52-
brightness=self._brightness)
57+
brightness=self._brightness, auto_write=False)
5358

5459
def __setitem__(self, indices, value):
55-
x, y = indices
56-
self._dotstar[y * self.columns + x] = value
60+
"""
61+
indices can be one of two things:
62+
x and y ints that are calculated to the DotStar index
63+
a single int that specifies the DotStar index
64+
value can be one of three things:
65+
a (r,g,b) list/tuple
66+
a (r,g,b, brightness) list/tuple
67+
a single, longer int that contains RGB values, like 0xFFFFFF
68+
brightness, if specified should be a float 0-1
69+
"""
70+
self._dotstar[self._get_index(indices)] = value
71+
self._update()
5772

5873
def __getitem__(self, indices):
59-
x, y = indices
60-
return self._dotstar[y * self.columns + x]
74+
return self._dotstar[self._get_index(indices)]
75+
76+
def _get_index(self, indices):
77+
if isinstance(indices, int):
78+
if not 0 <= indices < self.rows * self.columns:
79+
raise ValueError('The index of {} is out of range'.format(indices))
80+
return indices
81+
elif isinstance(indices, slice):
82+
return indices
83+
elif len(indices) == 2:
84+
x, y = indices
85+
if not 0 <= x < self.columns:
86+
raise ValueError('The X value of {} is out of range'.format(x))
87+
if not 0 <= y < self.rows:
88+
raise ValueError('The Y value of {} is out of range'.format(y))
89+
return y * self.columns + x
90+
else:
91+
raise ValueError('Index must be 1 or 2 number')
92+
93+
def fill(self, color=0):
94+
"""
95+
Fills all of the DotStars with a color or unlit if empty.
96+
97+
:param color: (Optional) The text or number to display (default=0)
98+
:type color: list/tuple or int
99+
100+
This example shows various ways of using the fill() function
101+
102+
.. code-block:: python
61103
62-
def fill(self, color):
63-
"""Fills the wing with a color.
64-
Does NOT update the LEDs.
104+
import time
105+
from adafruit_featherwing import dotstar_featherwing
106+
107+
dotstar = dotstar_featherwing.DotStarFeatherWing()
108+
dotstar.fill((255, 255, 255)) # Fill White
109+
time.sleep(1)
110+
dotstar.fill((255, 255, 255, 0.5)) # Fill White Half Brightness
111+
time.sleep(1)
112+
dotstar.fill(0xFF0000) # Fill Red
113+
time.sleep(1)
114+
dotstar.fill() # Clear all lit DotStars
65115
66-
:param (int, int, int) color: the color to fill with
67116
"""
68117
self._dotstar.fill(color)
118+
self._update()
119+
120+
def show(self):
121+
"""
122+
Update the DotStars. This is only needed if auto_write is set to False
123+
This can be very useful for more advanced graphics effects.
124+
125+
This example changes the blink rate and prints out the current setting
126+
127+
.. code-block:: python
128+
129+
import time
130+
from adafruit_featherwing import dotstar_featherwing
131+
132+
dotstar = dotstar_featherwing.DotStarFeatherWing()
133+
dotstar.fill() # Clear any lit Dotstars
134+
dotstar.auto_write = False
135+
dotstar[0, 0] = (255, 255, 255) # Set White
136+
time.sleep(1)
137+
dotstar.show() # Update the DotStars
138+
139+
"""
140+
self._dotstar.show()
141+
142+
def shift_right(self, rotate=False):
143+
"""
144+
Shift all pixels right
145+
146+
:param rotate: (Optional) Rotate the shifted pixel to the beginning (default=False)
147+
148+
This example shifts pixels
149+
150+
.. code-block:: python
151+
152+
import time
153+
from adafruit_featherwing import dotstar_featherwing
154+
155+
dotstar = dotstar_featherwing.DotStarFeatherWing()
156+
dotstar.fill() # Clear any lit Dotstars
157+
dotstar.auto_write = False
158+
dotstar[0, 0] = (255, 255, 255) # Set White
159+
time.sleep(1)
160+
dotstar.show() # Update the DotStars
161+
162+
"""
163+
for y in range(0, self.rows):
164+
for x in range(self.columns - 1, 0, -1):
165+
self._dotstar[y * self.columns + x] = self._dotstar[y * self.columns + x - 1]
166+
lastPixel = self._dotstar[(y + 1) * self.columns - 1] if rotate else 0
167+
self._dotstar[y * self.columns] = lastPixel
168+
self._update()
169+
170+
def shift_left(self, rotate=False):
171+
"""Shift all pixels left"""
172+
for y in range(0, self.rows):
173+
for x in range(0, self.columns - 1):
174+
self._dotstar[y * self.columns + x] = self._dotstar[y * self.columns + x + 1]
175+
lastPixel = self._dotstar[y * self.columns] if rotate else 0
176+
self._dotstar[(y + 1) * self.columns - 1] = lastPixel
177+
self._update()
178+
179+
def shift_up(self, rotate=False):
180+
"""Shift all pixels up"""
181+
for x in range(0, self.columns):
182+
for y in range(self.rows - 1, 0, -1):
183+
self._dotstar[y * self.columns + x] = self._dotstar[(y - 1) * self.columns + x]
184+
lastPixel = self._dotstar[(self.rows - 1) * self.columns + x] if rotate else 0
185+
self._dotstar[x] = lastPixel
186+
self._update()
187+
188+
def shift_down(self, rotate=False):
189+
"""Shift all pixels down"""
190+
for x in range(0, self.columns):
191+
for y in range(0, self.rows - 1):
192+
self._dotstar[y * self.columns + x] = self._dotstar[(y + 1) * self.columns + x]
193+
lastPixel = self._dotstar[x] if rotate else 0
194+
self._dotstar[(self.rows - 1) * self.columns + x] = lastPixel
195+
self._update()
196+
197+
def _update(self):
198+
if self._auto_write:
199+
self._dotstar.show()
200+
201+
@property
202+
def auto_write(self):
203+
"""Whether or not we are automatically updating
204+
If set to false, be sure to call show() to update"""
205+
return self._auto_write
206+
207+
@auto_write.setter
208+
def auto_write(self, write):
209+
if isinstance(write, bool):
210+
self._auto_write = write
211+
212+
@property
213+
def brightness(self):
214+
"""Overall brightness of the display"""
215+
return self._dotstar.brightness
216+
217+
@brightness.setter
218+
def brightness(self, brightness):
219+
self._dotstar.brightness = min(max(brightness, 0.0), 1.0)

docs/examples.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,9 @@ Ensure your device works with this simple test.
1919
:caption: examples/featherwing_dotstar_simpletest.py
2020
:linenos:
2121

22+
.. literalinclude:: ../examples/featherwing_dotstar_palettetest.py
23+
:caption: examples/featherwing_dotstar_palettetest.py
24+
:linenos:
25+
2226

2327

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""
2+
This creates a palette of colors, draws a pattern and
3+
rotates through the palette creating a moving rainbow.
4+
"""
5+
6+
from math import sqrt,cos,sin,radians
7+
from adafruit_featherwing import dotstar_featherwing
8+
9+
dotstar = dotstar_featherwing.DotStarFeatherWing()
10+
11+
# Remap the calculated rotation to 0 - 255
12+
def remap(vector):
13+
return int(((255 * vector + 85) * 0.75) + 0.5)
14+
15+
# Calculate the Hue rotation starting with Red as 0 degrees
16+
def rotate(degrees):
17+
cosA = cos(radians(degrees))
18+
sinA = sin(radians(degrees))
19+
red = cosA + (1.0 - cosA) / 3.0
20+
green = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA
21+
blue = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA
22+
return (remap(red), remap(green), remap(blue))
23+
24+
palette = []
25+
pixels = []
26+
27+
# Generate a rainbow palette
28+
for degree in range(0, 360):
29+
color = rotate(degree)
30+
palette.append(color[0] << 16 | color[1] << 8 | color[2])
31+
32+
# Create the Pattern
33+
for y in range(0, dotstar.rows):
34+
for x in range(0, dotstar.columns):
35+
pixels.append(x * 30 + y * -30)
36+
37+
# Clear the screen
38+
dotstar.fill()
39+
40+
# Start the Animation
41+
dotstar.auto_write = False
42+
while True:
43+
for color in range(0, 360, 10):
44+
for index in range(0, 72):
45+
palette_index = pixels[index] + color
46+
if palette_index >= 360:
47+
palette_index -= 360
48+
elif palette_index < 0:
49+
palette_index += 360
50+
dotstar[index] = palette[palette_index]
51+
dotstar.show()

examples/featherwing_dotstar_simpletest.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from time import sleep
77
import random
8+
from math import sqrt,cos,sin,radians
89
from adafruit_featherwing import dotstar_featherwing
910

1011
dotstar = dotstar_featherwing.DotStarFeatherWing()
@@ -14,13 +15,46 @@
1415
def random_color():
1516
return random.randrange(0, 8) * 32
1617

17-
for i in range(0, 15):
18+
# Fill screen with random colors at random brightnesses
19+
for i in range(0, 5):
1820
dotstar.fill((random_color(), random_color(), random_color()))
21+
dotstar.brightness = random.randrange(2, 10) / 10
1922
sleep(.2)
2023

21-
# MAIN LOOP
24+
# Set display to 30% brightness
25+
dotstar.brightness = 0.3
26+
27+
# Create a gradiant drawing each pixel
28+
for x in range(0, dotstar.columns):
29+
for y in range(dotstar.rows - 1, -1, -1):
30+
dotstar[x, y] = (y * 42, 255, y * 42, 1)
31+
32+
#Rotate everything left 36 frames
33+
for i in range(0, 36):
34+
dotstar.shift_down(True)
35+
36+
# Draw dual gradiant and then update
37+
dotstar.auto_write = False
38+
for y in range(0, dotstar.rows):
39+
for x in range(0, 6):
40+
dotstar[x, y] = (y * 84, x * 42, x * 42, 1)
41+
for x in range(6, 12):
42+
dotstar[x, y] = (255 - (y * 84), 255 - ((x - 6) * 42), 255 - ((x - 6) * 42), 1)
43+
44+
# Rotate everything left 36 frames
45+
for i in range(0, 36):
46+
dotstar.shift_left(True)
47+
dotstar.shift_up(True)
48+
dotstar.show()
49+
dotstar.auto_write = True
50+
51+
# Shift without rotating in bits for an animated screen wipe
52+
for i in range(0, 6):
53+
dotstar.shift_up()
54+
55+
# Show pixels in random locations of random color
56+
# Bottom left corner is (0,0)
2257
while True:
23-
# Fill screen with a random color
2458
x = random.randrange(0, dotstar.columns)
2559
y = random.randrange(0, dotstar.rows)
2660
dotstar[x, y] = (random_color(), random_color(), random_color())

0 commit comments

Comments
 (0)