Skip to content

Commit 2dceb26

Browse files
author
Tobias Oberstein
committed
Merge remote-tracking branch 'fschioler/patch-1'
2 parents 9ff733d + 209cec5 commit 2dceb26

File tree

1 file changed

+277
-0
lines changed

1 file changed

+277
-0
lines changed
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
#!/usr/bin/python
2+
3+
import time
4+
from Adafruit_LEDBackpack import LEDBackpack
5+
6+
# ===========================================================================
7+
# Quad Alphabumeric Display
8+
# Handles a display consisting of one or more 4-digit segments.
9+
#
10+
# Products:
11+
# http://www.adafruit.com/products/1911
12+
# http://www.adafruit.com/products/1912
13+
# ===========================================================================
14+
15+
class QuadAlphanum:
16+
disp = []
17+
maxDigit = 0
18+
debug = False
19+
20+
# The pixel matrix has been copied from the Adafruit Arduino library.
21+
alphafonttable = [
22+
0b0000000000000001,
23+
0b0000000000000010,
24+
0b0000000000000100,
25+
0b0000000000001000,
26+
0b0000000000010000,
27+
0b0000000000100000,
28+
0b0000000001000000,
29+
0b0000000010000000,
30+
0b0000000100000000,
31+
0b0000001000000000,
32+
0b0000010000000000,
33+
0b0000100000000000,
34+
0b0001000000000000,
35+
0b0010000000000000,
36+
0b0100000000000000,
37+
0b1000000000000000,
38+
0b0000000000000000,
39+
0b0000000000000000,
40+
0b0000000000000000,
41+
0b0000000000000000,
42+
0b0000000000000000,
43+
0b0000000000000000,
44+
0b0000000000000000,
45+
0b0000000000000000,
46+
0b0001001011001001,
47+
0b0001010111000000,
48+
0b0001001011111001,
49+
0b0000000011100011,
50+
0b0000010100110000,
51+
0b0001001011001000,
52+
0b0011101000000000,
53+
0b0001011100000000,
54+
0b0000000000000000, #
55+
0b0000000000000110, # !
56+
0b0000001000100000, # "
57+
0b0001001011001110, # #
58+
0b0001001011101101, # $
59+
0b0000110000100100, # %
60+
0b0010001101011101, # &
61+
0b0000010000000000, # '
62+
0b0010010000000000, # (
63+
0b0000100100000000, # )
64+
0b0011111111000000, # *
65+
0b0001001011000000, # +
66+
0b0000100000000000, # ,
67+
0b0000000011000000, # -
68+
0b0100000000000000, # .
69+
0b0000110000000000, # /
70+
0b0000110000111111, # 0
71+
0b0000000000000110, # 1
72+
0b0000000011011011, # 2
73+
0b0000000010001111, # 3
74+
0b0000000011100110, # 4
75+
0b0010000001101001, # 5
76+
0b0000000011111101, # 6
77+
0b0000000000000111, # 7
78+
0b0000000011111111, # 8
79+
0b0000000011101111, # 9
80+
0b0001001000000000, # :
81+
0b0000101000000000, # ;
82+
0b0010010000000000, # <
83+
0b0000000011001000, # =
84+
0b0000100100000000, # >
85+
0b0001000010000011, # ?
86+
0b0000001010111011, # @
87+
0b0000000011110111, # A
88+
0b0001001010001111, # B
89+
0b0000000000111001, # C
90+
0b0001001000001111, # D
91+
0b0000000011111001, # E
92+
0b0000000001110001, # F
93+
0b0000000010111101, # G
94+
0b0000000011110110, # H
95+
0b0001001000000000, # I
96+
0b0000000000011110, # J
97+
0b0010010001110000, # K
98+
0b0000000000111000, # L
99+
0b0000010100110110, # M
100+
0b0010000100110110, # N
101+
0b0000000000111111, # O
102+
0b0000000011110011, # P
103+
0b0010000000111111, # Q
104+
0b0010000011110011, # R
105+
0b0000000011101101, # S
106+
0b0001001000000001, # T
107+
0b0000000000111110, # U
108+
0b0000110000110000, # V
109+
0b0010100000110110, # W
110+
0b0010110100000000, # X
111+
0b0001010100000000, # Y
112+
0b0000110000001001, # Z
113+
0b0000000000111001, # [
114+
0b0010000100000000, #
115+
0b0000000000001111, # ]
116+
0b0000110000000011, # ^
117+
0b0000000000001000, # _
118+
0b0000000100000000, # `
119+
0b0001000001011000, # a
120+
0b0010000001111000, # b
121+
0b0000000011011000, # c
122+
0b0000100010001110, # d
123+
0b0000100001011000, # e
124+
0b0000000001110001, # f
125+
0b0000010010001110, # g
126+
0b0001000001110000, # h
127+
0b0001000000000000, # i
128+
0b0000000000001110, # j
129+
0b0011011000000000, # k
130+
0b0000000000110000, # l
131+
0b0001000011010100, # m
132+
0b0001000001010000, # n
133+
0b0000000011011100, # o
134+
0b0000000101110000, # p
135+
0b0000010010000110, # q
136+
0b0000000001010000, # r
137+
0b0010000010001000, # s
138+
0b0000000001111000, # t
139+
0b0000000000011100, # u
140+
0b0010000000000100, # v
141+
0b0010100000010100, # w
142+
0b0010100011000000, # x
143+
0b0010000000001100, # y
144+
0b0000100001001000, # z
145+
0b0000100101001001, # {
146+
0b0001001000000000, # |
147+
0b0010010010001001, # }
148+
0b0000010100100000, # ~
149+
0b0011111111111111
150+
]
151+
152+
# Constructor
153+
def __init__(self, address=0x70, segments=1, debug=False):
154+
"Construct a display consisting of one or more 4-digit segments."
155+
# Save the upper limit for convenience
156+
self.maxDigit = 4 * segments
157+
self.debug = debug
158+
for segment in range(segments):
159+
addr = address + segment
160+
if (debug):
161+
print "Initializing a new instance of LEDBackpack at 0x%02X" % addr
162+
self.disp.append( LEDBackpack(address=addr, debug=debug) )
163+
164+
def writeDigitRaw(self, value, pos, update=True):
165+
"Sets a digit using a raw 16-bit value"
166+
if (pos < 0 or pos >= self.maxDigit):
167+
# The position is out of range: To be expected by "setMessage()"
168+
return
169+
# Set the appropriate character
170+
self.disp[pos/4].setBufferRow(pos%4, value, update)
171+
172+
def writeDigitAscii(self, char, pos, dot=False, update=True):
173+
"Lookup pixels from ascii table."
174+
if ord(char) < 0 or ord(char) > 127:
175+
if (self.debug):
176+
print "Invalid character: " + ord(char)
177+
return
178+
# Lookup and convert to font
179+
font = self.alphafonttable[ord(char)]
180+
if (dot):
181+
font |= (1<<14)
182+
self.writeDigitRaw(font, pos, update)
183+
184+
def setMessage(self, text, pos=0):
185+
"Write a message on the display. No scroll. Return next free position."
186+
for char in text:
187+
if char == '.' and pos > 0 and pos <= self.maxDigit:
188+
# Dot: Update previous digit with a dot instead of writing a new letter.
189+
buffer = self.disp[(pos-1)/4].getBuffer()
190+
# Retrieved data has "font" format, not ASCII
191+
font = buffer[(pos-1)%4]
192+
# Set the dot
193+
font |= (1<<14)
194+
# Rewrite the last letter as a modified "font"
195+
self.writeDigitRaw(font, pos-1, False)
196+
else:
197+
# Normal case
198+
self.writeDigitAscii(char, pos, False, False)
199+
pos += 1
200+
self.writeDisplay()
201+
return pos
202+
203+
def scrollMessage(self, text, scrollSpeed=0.3):
204+
"Scroll a message across the display."
205+
for char in text:
206+
if char == '.':
207+
# Dot: Update last digit with dot instead of writing new letter.
208+
buffer = self.disp[(self.maxDigit-1)/4].getBuffer()
209+
# Retrieved data has "font" format, not ASCII
210+
font = buffer[(self.maxDigit-1)%4]
211+
# Set the dot
212+
font |= (1<<14)
213+
# Rewrite the last letter as a modified "font"
214+
self.writeDigitRaw(font, self.maxDigit-1, True)
215+
# Do not sleep to ensure a semmingly fixed scroll speed
216+
else:
217+
# Normal case
218+
self.scrollLetter(char)
219+
time.sleep(scrollSpeed)
220+
221+
def scrollLetter(self, char, dot=False):
222+
"Scroll the display and write the last letter"
223+
# Scroll all characters without updating the segments
224+
self.shiftLeft()
225+
# Write last character without updating the last segment
226+
self.writeDigitAscii(char, self.maxDigit-1, dot, update=False)
227+
# Update all segments
228+
self.writeDisplay()
229+
230+
def shiftLeft(self):
231+
buffer = self.disp[0].getBuffer()
232+
for segment in range(0, len(self.disp)):
233+
for x in range (0, 3):
234+
# Shift 3 first columns of segment, no update during shift
235+
self.disp[segment].setBufferRow(x, buffer[x+1], False)
236+
if (segment + 1 < len(self.disp)):
237+
# Unless this is th last digit:
238+
# Transfer first column of next segment and update
239+
next_buffer = self.disp[segment+1].getBuffer()
240+
self.disp[segment].setBufferRow(3, next_buffer[0], False)
241+
buffer = next_buffer
242+
243+
def writeDisplay(self):
244+
"""Explicitely update the display.
245+
Used if you have written to the buffer with no update.
246+
"""
247+
for segment in self.disp:
248+
segment.writeDisplay()
249+
250+
def clear(self):
251+
"Clears the entire display"
252+
for segment in self.disp:
253+
segment.clear()
254+
255+
def setBrightness(self, brightness):
256+
"Set brightness for all displays"
257+
for segment in self.disp:
258+
segment.setBrightness(brightness)
259+
260+
# No use to handle multiple blinking segments:
261+
# They will never blink in sync anyway.
262+
263+
if __name__ == '__main__':
264+
"Self test / demo."
265+
screen = QuadAlphanum(0x70, 1, True)
266+
screen.setMessage("TEST.")
267+
time.sleep(2)
268+
screen.clear()
269+
screen.setMessage("fixed", 1)
270+
time.sleep(2)
271+
screen.scrollMessage(" and scrolling text.")
272+
for brightness in range (15, 0, -1):
273+
time.sleep(0.25)
274+
screen.setBrightness(brightness)
275+
screen.clear()
276+
screen.setMessage("Done.")
277+
screen.setBrightness(15)

0 commit comments

Comments
 (0)