Skip to content

Commit 261472d

Browse files
authored
Add files via upload
1 parent 58c3bdd commit 261472d

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed

QT_Py_Cube/cube.py

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# SPDX-FileCopyrightText: 2022 Charlyn Gonda for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
import time
5+
import adafruit_dotstar
6+
7+
from adafruit_led_animation.animation.rainbowchase import RainbowChase
8+
from adafruit_led_animation.color import AMBER, JADE, CYAN, GOLD, PINK
9+
from adafruit_pixel_framebuf import PixelFramebuffer
10+
11+
12+
class Cube():
13+
def __init__(
14+
self,
15+
top_cin,
16+
top_din,
17+
side_panels_cin,
18+
side_panels_din,
19+
bottom_cin,
20+
bottom_din):
21+
22+
# static numbers
23+
self.num_pixels = 64*4
24+
self.num_pixels_topbottom = 64
25+
self.pixel_width = 8*4
26+
self.pixel_height = 8
27+
28+
# top pixels
29+
top_pixels = adafruit_dotstar.DotStar(
30+
top_cin, top_din, self.num_pixels_topbottom,
31+
brightness=0.03, auto_write=False)
32+
self.pixel_framebuf_top = PixelFramebuffer(
33+
top_pixels,
34+
self.pixel_height,
35+
self.pixel_height,
36+
rotation=1,
37+
alternating=False,
38+
)
39+
40+
# side pixels
41+
self.side_pixels = adafruit_dotstar.DotStar(
42+
side_panels_cin, side_panels_din, self.num_pixels,
43+
brightness=0.03, auto_write=False)
44+
self.pixel_framebuf_sides = PixelFramebuffer(
45+
self.side_pixels,
46+
self.pixel_height,
47+
self.pixel_width,
48+
rotation=1,
49+
alternating=False,
50+
reverse_y=True,
51+
reverse_x=False
52+
)
53+
self.rainbow_sides = RainbowChase(
54+
self.side_pixels, speed=0.1, size=3, spacing=6)
55+
56+
# bottom pixels
57+
pixels_bottom = adafruit_dotstar.DotStar(
58+
bottom_cin, bottom_din, self.num_pixels_topbottom,
59+
brightness=0.03, auto_write=False)
60+
self.pixel_framebuf_bottom = PixelFramebuffer(
61+
pixels_bottom,
62+
self.pixel_height,
63+
self.pixel_height,
64+
rotation=0,
65+
alternating=False,
66+
reverse_y=False,
67+
reverse_x=True
68+
)
69+
70+
# scrolling word state vars
71+
self.last_color_time = -1
72+
self.color_wait = 1
73+
self.word = ''
74+
self.total_scroll_len = 0
75+
self.scroll_x_pos = -self.pixel_width
76+
self.color_idx = 0
77+
self.color_list = [AMBER, JADE, CYAN, PINK, GOLD]
78+
self.done_scrolling = False
79+
80+
# whether or not the cube is already clear
81+
self.clear = False
82+
83+
# top pixel vars
84+
self.top_pixel_coords = []
85+
self.top_pixel_color = CYAN
86+
87+
# upside down mode
88+
self.bottom_last = -1
89+
self.bottom_wait = 1
90+
self.bottom_squares = [[0, 0, 8, 8], [
91+
1, 1, 6, 6], [2, 2, 4, 4], [3, 3, 2, 2]]
92+
self.bottom_squares_idx = 0
93+
94+
def update(self, word, color, coords):
95+
self.word = word
96+
self.total_scroll_len = (len(self.word) * 5) + len(self.word)
97+
self.top_pixel_coords = coords
98+
self.top_pixel_color = color
99+
100+
def scroll_word_and_update_top(self):
101+
if self.scroll_x_pos >= self.total_scroll_len:
102+
self.scroll_x_pos = -self.pixel_width
103+
self.clear_cube()
104+
self.done_scrolling = True
105+
else:
106+
self.done_scrolling = False
107+
self.clear = False
108+
109+
self.__scroll_framebuf(self.word, self.scroll_x_pos, 0)
110+
self.__display_top_pixels()
111+
self.scroll_x_pos = self.scroll_x_pos + 1
112+
113+
def clear_cube(self, clear_top=False):
114+
if not self.clear:
115+
self.pixel_framebuf_sides.fill(0)
116+
self.pixel_framebuf_sides.display()
117+
self.side_pixels.fill(0)
118+
self.side_pixels.show()
119+
self.pixel_framebuf_bottom.fill(0)
120+
self.pixel_framebuf_bottom.display()
121+
if clear_top:
122+
self.pixel_framebuf_top.fill(0)
123+
self.pixel_framebuf_top.display()
124+
self.clear = True
125+
126+
def upside_down_mode(self):
127+
self.clear_cube(True)
128+
self.rainbow_sides.animate()
129+
now = time.monotonic()
130+
self.__bottom_square_animation(now)
131+
132+
def waiting_mode(self):
133+
self.pixel_framebuf_top.pixel(3, 3, CYAN)
134+
self.pixel_framebuf_top.pixel(4, 4, PINK)
135+
self.pixel_framebuf_top.display()
136+
137+
def __bottom_square_animation(self, now):
138+
self.pixel_framebuf_bottom.fill(0)
139+
color_int = self._rgb_to_int(CYAN)
140+
if now > self.bottom_last + self.bottom_wait:
141+
self.__coord_wrap()
142+
self.bottom_last = now
143+
x, y, w, h = self.bottom_squares[self.bottom_squares_idx]
144+
self.pixel_framebuf_bottom.rect(x, y, w, h, color_int)
145+
self.pixel_framebuf_bottom.display()
146+
147+
def __coord_wrap(self):
148+
self.bottom_squares_idx = self.bottom_squares_idx + 1
149+
if self.bottom_squares_idx >= len(self.bottom_squares):
150+
self.bottom_squares_idx = 0
151+
152+
def __display_top_pixels(self):
153+
self.pixel_framebuf_top.fill(0)
154+
155+
for coord in self.top_pixel_coords:
156+
x, y = coord.split(":")
157+
self.pixel_framebuf_top.pixel(int(x), int(y), self.top_pixel_color)
158+
self.pixel_framebuf_top.display()
159+
160+
def __scroll_framebuf(self, word, shift_x, shift_y):
161+
self.pixel_framebuf_sides.fill(0)
162+
163+
color = self.__next_color()
164+
color_int = self._rgb_to_int(color)
165+
166+
# negate x so that the word can be shown from left to right
167+
self.pixel_framebuf_sides.text(word, -shift_x, shift_y, color_int)
168+
self.pixel_framebuf_sides.display()
169+
170+
def __next_color(self):
171+
if self.color_idx >= len(self.color_list):
172+
self.color_idx = 0
173+
174+
result = self.color_list[self.color_idx]
175+
now = time.monotonic()
176+
if now >= self.last_color_time + self.color_wait:
177+
self.color_idx = self.color_idx + 1
178+
self.last_color_time = now
179+
180+
return result
181+
182+
@staticmethod
183+
def _rgb_to_int(rgb):
184+
return rgb[0] << 16 | rgb[1] << 8 | rgb[2]

0 commit comments

Comments
 (0)