forked from smittytone/HT16K33-Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathht16k33segment.py
179 lines (145 loc) · 6.39 KB
/
ht16k33segment.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# Import the base class
from ht16k33 import HT16K33
class HT16K33Segment(HT16K33):
"""
Micro/Circuit Python class for the Adafruit 0.56-in 4-digit,
7-segment LED matrix backpack and equivalent Featherwing.
Version: 3.3.0
Bus: I2C
Author: Tony Smith (@smittytone)
License: MIT
Copyright: 2022
"""
# *********** CONSTANTS **********
HT16K33_SEGMENT_COLON_ROW = 0x04
HT16K33_SEGMENT_MINUS_CHAR = 0x10
HT16K33_SEGMENT_DEGREE_CHAR = 0x11
HT16K33_SEGMENT_SPACE_CHAR = 0x00
# The positions of the segments within the buffer
POS = (0, 2, 6, 8)
# Bytearray of the key alphanumeric characters we can show:
# 0-9, A-F, minus, degree
CHARSET = b'\x3F\x06\x5B\x4F\x66\x6D\x7D\x07\x7F\x6F\x5F\x7C\x58\x5E\x7B\x71\x40\x63'
# *********** CONSTRUCTOR **********
def __init__(self, i2c, i2c_address=0x70):
self.buffer = bytearray(16)
self.is_rotated = False
super(HT16K33Segment, self).__init__(i2c, i2c_address)
# *********** PUBLIC METHODS **********
def rotate(self):
"""
Rotate/flip the segment display.
Returns:
The instance (self)
"""
self.is_rotated = not self.is_rotated
return self
def set_colon(self, is_set=True):
"""
Set or unset the display's central colon symbol.
This method updates the display buffer, but does not send the buffer to the display itself.
Call 'update()' to render the buffer on the display.
Args:
isSet (bool): Whether the colon is lit (True) or not (False). Default: True.
Returns:
The instance (self)
"""
self.buffer[self.HT16K33_SEGMENT_COLON_ROW] = 0x02 if is_set is True else 0x00
return self
def set_glyph(self, glyph, digit=0, has_dot=False):
"""
Present a user-defined character glyph at the specified digit.
Glyph values are 8-bit integers representing a pattern of set LED segments.
The value is calculated by setting the bit(s) representing the segment(s) you want illuminated.
Bit-to-segment mapping runs clockwise from the top around the outside of the matrix; the inner segment is bit 6:
0
_
5 | | 1
| |
- <----- 6
4 | | 2
| _ |
3
This method updates the display buffer, but does not send the buffer to the display itself.
Call 'update()' to render the buffer on the display.
Args:
glyph (int): The glyph pattern.
digit (int): The digit to show the glyph. Default: 0 (leftmost digit).
has_dot (bool): Whether the decimal point to the right of the digit should be lit. Default: False.
Returns:
The instance (self)
"""
assert 0 <= digit < 4, "ERROR - Invalid digit (0-3) set in set_glyph()"
assert 0 <= glyph < 0x80, "ERROR - Invalid glyph (0x00-0x80) set in set_glyph()"
self.buffer[self.POS[digit]] = glyph
if has_dot is True: self.buffer[self.POS[digit]] |= 0x80
return self
def set_number(self, number, digit=0, has_dot=False):
"""
Present single decimal value (0-9) at the specified digit.
This method updates the display buffer, but does not send the buffer to the display itself.
Call 'update()' to render the buffer on the display.
Args:
number (int): The number to show.
digit (int): The digit to show the number. Default: 0 (leftmost digit).
has_dot (bool): Whether the decimal point to the right of the digit should be lit. Default: False.
Returns:
The instance (self)
"""
assert 0 <= digit < 4, "ERROR - Invalid digit (0-3) set in set_number()"
assert 0 <= number < 10, "ERROR - Invalid value (0-9) set in set_number()"
return self.set_character(str(number), digit, has_dot)
def set_character(self, char, digit=0, has_dot=False):
"""
Present single alphanumeric character at the specified digit.
Only characters from the class' character set are available:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d ,e, f, -.
Other characters can be defined and presented using 'set_glyph()'.
This method updates the display buffer, but does not send the buffer to the display itself.
Call 'update()' to render the buffer on the display.
Args:
char (string): The character to show.
digit (int): The digit to show the number. Default: 0 (leftmost digit).
has_dot (bool): Whether the decimal point to the right of the digit should be lit. Default: False.
Returns:
The instance (self)
"""
assert 0 <= digit < 4, "ERROR - Invalid digit set in set_character()"
char = char.lower()
char_val = 0xFF
if char == "deg":
char_val = self.HT16K33_SEGMENT_DEGREE_CHAR
elif char == '-':
char_val = self.HT16K33_SEGMENT_MINUS_CHAR
elif char == ' ':
char_val = self.HT16K33_SEGMENT_SPACE_CHAR
elif char in 'abcdef':
char_val = ord(char) - 87
elif char in '0123456789':
char_val = ord(char) - 48
assert char_val != 0xFF, "ERROR - Invalid char string set in set_character()"
self.buffer[self.POS[digit]] = self.CHARSET[char_val]
if has_dot is True: self.buffer[self.POS[digit]] |= 0x80
return self
def draw(self):
"""
Writes the current display buffer to the display itself.
Call this method after updating the buffer to update
the LED itself. Rotation handled here.
"""
if self.is_rotated:
# Swap digits 0,3 and 1,2
a = self.buffer[self.POS[0]]
self.buffer[self.POS[0]] = self.buffer[self.POS[3]]
self.buffer[self.POS[3]] = a
a = self.buffer[self.POS[1]]
self.buffer[self.POS[1]] = self.buffer[self.POS[2]]
self.buffer[self.POS[2]] = a
# Rotate each digit
for i in range(0, 4):
a = self.buffer[self.POS[i]]
b = (a & 0x07) << 3
c = (a & 0x38) >> 3
a &= 0xC0
self.buffer[self.POS[i]] = (a | b | c)
self._render()