Skip to content

Commit d80dc17

Browse files
committed
Plenty of work, including extracting fonts
1 parent f9e374c commit d80dc17

File tree

2 files changed

+175
-149
lines changed

2 files changed

+175
-149
lines changed

dotstar_featherwing.py

Lines changed: 125 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# The MIT License (MIT)
22
#
3-
# Copyright (c) 2017 Dave Astels for ZombieWizard
3+
# Copyright (c) 2017 Dave Astels
44
#
55
# Permission is hereby granted, free of charge, to any person obtaining a copy
66
# of this software and associated documentation files (the "Software"), to deal
@@ -34,208 +34,184 @@
3434

3535
class DotstarFeatherwing:
3636
"""Test, Image, and Animation support for the DotStar featherwing"""
37-
38-
blank_stripe = [(0, 0, 0),
39-
(0, 0, 0),
40-
(0, 0, 0),
41-
(0, 0, 0),
42-
(0, 0, 0),
43-
(0, 0, 0)]
37+
38+
blank_stripe = [(0, 0, 0),
39+
(0, 0, 0),
40+
(0, 0, 0),
41+
(0, 0, 0),
42+
(0, 0, 0),
43+
(0, 0, 0)]
4444
"""A blank stripe, used internally to separate characters as they are shifted onto the display."""
45-
46-
font_3 = {' ': [ 0, 0, 0],
47-
'A': [62, 05, 62],
48-
'B': [63, 37, 26],
49-
'C': [30, 33, 18],
50-
'D': [63, 33, 30],
51-
'E': [63, 37, 33],
52-
'F': [63, 5, 1],
53-
'G': [30, 41, 26],
54-
'H': [63, 4, 63],
55-
'I': [33, 63, 33],
56-
'J': [33, 31, 1],
57-
'K': [63, 4, 59],
58-
'L': [63, 32, 32],
59-
'M': [63, 2, 63],
60-
'N': [63, 12, 63],
61-
'O': [30, 33, 30],
62-
'P': [63, 5, 2],
63-
'Q': [30, 33, 62],
64-
'R': [63, 5, 58],
65-
'S': [18, 37, 26],
66-
'T': [ 1, 63, 1],
67-
'U': [31, 32, 63],
68-
'V': [31, 32, 31],
69-
'W': [63, 16, 63],
70-
'X': [59, 4, 59],
71-
'Y': [ 3, 60, 3],
72-
'Z': [49, 45, 35],
73-
'0': [30, 33, 30],
74-
'1': [34, 63, 32],
75-
'2': [50, 41, 38],
76-
'3': [33, 37, 26],
77-
'4': [ 7, 4, 63],
78-
'5': [23, 37, 25],
79-
'6': [30, 41, 25],
80-
'7': [49, 9, 7],
81-
'8': [26, 37, 26],
82-
'9': [38, 41, 30],
83-
'!': [ 0, 47, 0],
84-
'?': [ 2, 41, 6],
85-
'.': [ 0, 32, 0],
86-
'-': [ 8, 8, 8],
87-
'_': [32, 32, 32],
88-
'+': [ 8, 28, 8],
89-
'/': [48, 12, 3],
90-
'*': [20, 8, 20],
91-
'=': [20, 20, 20],
92-
'UNKNOWN': [63, 33, 63] }
93-
"""A sample font that uses 3 pixel wide characters."""
94-
95-
96-
def __init__(self, clock, data, brightness=1.0):
45+
46+
def __init__(self, clock, data, brightness=1.0):
9747
"""Create an interface for the display.
9848
9949
:param pin clock: The clock pin for the featherwing
10050
:param pin data: The data pin for the featherwing
10151
:param float brightness: Optional brightness (0.0-1.0) that defaults to 1.0
10252
"""
103-
self.rows = 6
104-
self.columns = 12
105-
self.display = adafruit_dotstar.DotStar(clock, data, self.rows * self.columns, brightness, False)
106-
53+
self.rows = 6
54+
self.columns = 12
55+
self.display = adafruit_dotstar.DotStar(clock, data, self.rows * self.columns, brightness, False)
56+
57+
58+
def clear(self):
59+
"""Clear the display.
60+
Does NOT update the LEDs
61+
"""
62+
self.display.fill((0,0,0))
63+
64+
65+
def fill(self, color):
66+
"""Fills the wing with a color.
67+
Does NOT update the LEDs.
68+
69+
:param (int, int, int) color: the color to fill with
70+
"""
71+
self.display.fill(color)
10772

73+
74+
def show(self):
75+
"""Update the LEDs.
76+
"""
77+
self.display.show()
78+
79+
80+
def set_color(self, row, column, color):
81+
"""Set the color of the specified pixel.
82+
83+
:param int row: The row (0-5) of the pixel to set
84+
:param int column: The column (0-11) of the pixel to set
85+
:param (int, int, int) color: The color to set the pixel to
86+
"""
87+
self.display[row * self.columns + column] = color
88+
89+
10890
def shift_into_left(self, stripe):
10991
""" Shift a column of pixels into the left side of the display.
11092
111-
:param [int] stripe: A column of pixel colours
93+
:param [(int, int, int)] stripe: A column of pixel colors
11294
"""
113-
for r in range(self.rows):
114-
rightmost = r * self.columns
115-
for c in range(self.columns - 1):
116-
self.display[rightmost + c] = self.display[rightmost + c + 1]
117-
self.display[rightmost + self.columns - 1] = stripe[r]
118-
self.display.show()
95+
for r in range(self.rows):
96+
rightmost = r * self.columns
97+
for c in range(self.columns - 1):
98+
self.display[rightmost + c] = self.display[rightmost + c + 1]
99+
self.display[rightmost + self.columns - 1] = stripe[r]
100+
self.display.show()
119101

120102

121-
def shift_into_right(self, stripe):
103+
def shift_into_right(self, stripe):
122104
""" Shift a column of pixels into the rightside of the display.
123105
124-
:param [int] stripe: A column of pixel colours
106+
:param [(int, int, int)] stripe: A column of pixel colors
125107
"""
126-
for r in range(self.rows):
127-
leftmost = ((r + 1) * self.columns) - 1
128-
for c in range(self.columns - 1):
129-
self.display[leftmost - c] = self.display[(leftmost - c) -1]
130-
self.display[(leftmost - self.columns) + 1] = stripe[r]
131-
self.display.show()
132-
133-
134-
def number_to_pixels(self, x, colour):
108+
for r in range(self.rows):
109+
leftmost = ((r + 1) * self.columns) - 1
110+
for c in range(self.columns - 1):
111+
self.display[leftmost - c] = self.display[(leftmost - c) -1]
112+
self.display[(leftmost - self.columns) + 1] = stripe[r]
113+
self.display.show()
114+
115+
116+
def number_to_pixels(self, x, color):
135117
"""Convert an integer (0..63) into an array of 6 pixels.
136118
137119
:param int x: integer to convert into binary pixel values; LSB is topmost.
138-
:param (int) colour: the colour to set "on" pixels to
120+
:param (int, int, int) color: the color to set "on" pixels to
139121
"""
140-
val = x
141-
pixels = []
142-
for b in range(self.rows):
143-
if val & 1 == 0:
144-
pixels.append((0, 0, 0))
145-
else:
146-
pixels.append(colour)
147-
val = val >> 1
148-
return pixels
149-
150-
151-
def character_to_numbers(self, font, char):
122+
val = x
123+
pixels = []
124+
for b in range(self.rows):
125+
if val & 1 == 0:
126+
pixels.append((0, 0, 0))
127+
else:
128+
pixels.append(color)
129+
val = val >> 1
130+
return pixels
131+
132+
133+
def character_to_numbers(self, font, char):
152134
"""Convert a letter to the sequence of column values to display.
153135
154136
:param {char -> [int]} font: the font to use to convert characters to glyphs
155137
:param char letter: the char to convert
156138
"""
157-
return font[letter]
158-
139+
return font[char]
159140

160-
def clear(self):
161-
"""Clear the display.
162-
Does NOT update the LEDs
163-
"""
164-
self.display.fill((0,0,0))
165141

166-
167-
def shift_in_character(self, font, c, colour=(0x00, 0x40, 0x00), delay=0.2):
142+
def shift_in_character(self, font, c, color=(0x00, 0x40, 0x00), delay=0.2):
168143
"""Shifts a single character onto the display from the right edge.
169144
170145
:param {char -> [int]} font: the font to use to convert characters to glyphs
171146
:param char c: the char to convert
172-
:param (int) colour: the color to use for each pixel turned on
147+
:param (int, int, int) color: the color to use for each pixel turned on
173148
:param float delay: the time to wait between shifting in columns
174149
"""
175150
if c.upper() in font:
176-
matrix = self.character_to_numbers(font, c.upper())
177-
else:
178-
matrix = self.character_to_numbers(font, 'UNKNOWN')
179-
for stripe in matrix:
180-
self.shift_into_right(self.number_to_pixels(stripe, colour))
151+
matrix = self.character_to_numbers(font, c.upper())
152+
else:
153+
matrix = self.character_to_numbers(font, 'UNKNOWN')
154+
for stripe in matrix:
155+
self.shift_into_right(self.number_to_pixels(stripe, color))
181156
time.sleep(delay)
182-
self.shift_into_right(self.blank_stripe)
157+
self.shift_into_right(self.blank_stripe)
183158
time.sleep(delay)
184159

185160

186-
def shift_in_string(self, font, s, colour=(0x00, 0x40, 0x00), delay=0.2):
161+
def shift_in_string(self, font, s, color=(0x00, 0x40, 0x00), delay=0.2):
187162
"""Shifts a string onto the display from the right edge.
188163
189164
:param {char -> [int]} font: the font to use to convert characters to glyphs
190165
:param string s: the char to convert
191-
:param (int) colour: the color to use for each pixel turned on
166+
:param (int, int, int)) color: the color to use for each pixel turned on
192167
:param float delay: the time to wait between shifting in columns
193168
"""
194-
for c in s:
195-
self.shift_in_character(font, c, colour, delay)
169+
for c in s:
170+
self.shift_in_character(font, c, color, delay)
196171

197-
198-
# Display an image
199-
def display_image(self, image, colour):
200-
"""Display an mono-coloured image.
172+
173+
# Display an image
174+
def display_image(self, image, color):
175+
"""Display an mono-colored image.
201176
202177
:param [string] image: the textual bitmap, 'X' for set pixels, anything else for others
203-
:param (int) colour: the colour to set "on" pixels to
178+
:param (int) color: the color to set "on" pixels to
204179
"""
205-
self.display_coloured_image(image, {'X': colour})
206-
180+
self.display_colored_image(image, {'X': color})
181+
207182

208-
def display_coloured_image(self, image, colours):
209-
"""Display an multi-coloured image.
183+
def display_colored_image(self, image, colors):
184+
"""Display an multi-colored image.
210185
211-
:param [string] image: the textual bitmap, character are looked up in colours for the
212-
corresponding pixel colour, anything not in the map is off
213-
:param {char -> [int]} colours: a map of characters in the image data to colours to use
186+
:param [string] image: the textual bitmap, character are looked up in colors for the
187+
corresponding pixel color, anything not in the map is off
188+
:param {char -> (int, int, int)} colors: a map of characters in the image data to colors to use
214189
"""
215-
for r in range(self.rows):
216-
for c in range(self.columns):
217-
index = r * self.columns + ((self.columns - 1) - c)
218-
key = image[r][c]
219-
if key in colours:
220-
self.display[index] = colours[key]
221-
else:
222-
self.display[index] = (0, 0, 0)
223-
self.display.show()
224-
225-
226-
def display_animation(self, animation, colours, delay=0.1):
227-
"""Display a multi-coloured animation.
228-
229-
:param [[string]] animation: a list of textual bitmaps, each as described in display_coloured_image
230-
:param {char -> [int]} colours: a map of characters in the image data to colours to use
190+
for r in range(self.rows):
191+
for c in range(self.columns):
192+
index = r * self.columns + ((self.columns - 1) - c)
193+
key = image[r][c]
194+
if key in colors:
195+
self.display[index] = colors[key]
196+
else:
197+
self.display[index] = (0, 0, 0)
198+
self.display.show()
199+
200+
201+
def display_animation(self, animation, colors, count=1, delay=0.1):
202+
"""Display a multi-colored animation.
203+
204+
:param [[string]] animation: a list of textual bitmaps, each as described in display_colored_image
205+
:param {char -> (int, int, int)} colors: a map of characters in the image data to colors to use
231206
:param float delay: the amount of time (seconds) to wait between frames
232207
"""
233-
self.clear()
234-
while True:
235-
for frame in animation:
236-
self.display_coloured_image(frame, colours)
237-
time.sleep(delay)
238-
208+
self.clear()
209+
while count > 0:
210+
for frame in animation:
211+
self.display_colored_image(frame, colors)
212+
time.sleep(delay)
213+
count = count - 1
214+
239215

240216

241217

font3.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
font = {' ': [ 0, 0, 0],
2+
'A': [62, 05, 62],
3+
'B': [63, 37, 26],
4+
'C': [30, 33, 18],
5+
'D': [63, 33, 30],
6+
'E': [63, 37, 33],
7+
'F': [63, 5, 1],
8+
'G': [30, 41, 26],
9+
'H': [63, 4, 63],
10+
'I': [33, 63, 33],
11+
'J': [33, 31, 1],
12+
'K': [63, 4, 59],
13+
'L': [63, 32, 32],
14+
'M': [63, 2, 63],
15+
'N': [63, 12, 63],
16+
'O': [30, 33, 30],
17+
'P': [63, 5, 2],
18+
'Q': [30, 33, 62],
19+
'R': [63, 5, 58],
20+
'S': [18, 37, 26],
21+
'T': [ 1, 63, 1],
22+
'U': [31, 32, 63],
23+
'V': [31, 32, 31],
24+
'W': [63, 16, 63],
25+
'X': [59, 4, 59],
26+
'Y': [ 3, 60, 3],
27+
'Z': [49, 45, 35],
28+
'0': [30, 33, 30],
29+
'1': [34, 63, 32],
30+
'2': [50, 41, 38],
31+
'3': [33, 37, 26],
32+
'4': [ 7, 4, 63],
33+
'5': [23, 37, 25],
34+
'6': [30, 41, 25],
35+
'7': [49, 9, 7],
36+
'8': [26, 37, 26],
37+
'9': [38, 41, 30],
38+
'!': [ 0, 47, 0],
39+
'?': [ 2, 41, 6],
40+
'.': [ 0, 32, 0],
41+
# '-': [ 8, 8, 8],
42+
# '_': [32, 32, 32],
43+
# '+': [ 8, 28, 8],
44+
# '/': [48, 12, 3],
45+
# '*': [20, 8, 20],
46+
# '=': [20, 20, 20],
47+
'UNKNOWN': [63, 33, 63] }
48+
"""A sample font that uses 3 pixel wide characters."""
49+
50+

0 commit comments

Comments
 (0)