Skip to content

Commit 414da64

Browse files
committed
Add alphanumeric font and scrolling
1 parent 04713d7 commit 414da64

File tree

5 files changed

+193
-39
lines changed

5 files changed

+193
-39
lines changed

README.md

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,21 @@ tm.write([127, 255, 127, 127])
2727
# all LEDS off
2828
tm.write([0, 0, 0, 0])
2929
30-
# display "0123"
30+
# show "0123"
3131
tm.write([63, 6, 91, 79])
3232
3333
# show "COOL"
3434
tm.write([0b00111001, 0b00111111, 0b00111111, 0b00111000])
3535
36+
# show "HELP"
37+
tm.show('help')
38+
3639
# display "dEAd", "bEEF"
3740
tm.hex(0xdead)
3841
tm.hex(0xbeef)
3942
4043
# show "12:59"
41-
tm.numbers(12,59)
44+
tm.numbers(12, 59)
4245
4346
# show "-123"
4447
tm.number(-123)
@@ -47,7 +50,9 @@ tm.number(-123)
4750
tm.temperature(24)
4851
```
4952

50-
For more detailed examples, see ![tm1637_test.py](tm1637_test.py)
53+
For more detailed examples, see [tm1637_test.py](tm1637_test.py)
54+
55+
# Seven Segment Font
5156

5257
They are called 7-segment displays as there are 7 LEDs for each digit (segment).
5358
One byte (7 lower bits) for each segment. The 8th bit (MSB) is for the colon and only on the 2nd segment.
@@ -83,8 +88,89 @@ C | 0b00111001 | 0x39 | 57
8388
d | 0b01011110 | 0x5E | 94
8489
E | 0b01111001 | 0x79 | 121
8590
F | 0b01110001 | 0x71 | 113
91+
G | 0b00111101 | 0x3D | 61
92+
H | 0b01110110 | 0x76 | 118
93+
I | 0b00000110 | 0x06 | 6
94+
J | 0b00011110 | 0x1E | 30
95+
K | 0b01110110 | 0x76 | 118
96+
L | 0b00111000 | 0x38 | 56
97+
M | 0b01010101 | 0x55 | 85
98+
n | 0b01010100 | 0x54 | 84
99+
O | 0b00111111 | 0x3F | 63
100+
P | 0b01110011 | 0x73 | 115
101+
q | 0b01100111 | 0x67 | 103
102+
r | 0b01010000 | 0x50 | 80
103+
S | 0b01101101 | 0x6D | 109
104+
t | 0b01111000 | 0x78 | 120
105+
U | 0b00111110 | 0x3E | 62
106+
v | 0b00011100 | 0x1C | 28
107+
W | 0b00101010 | 0x2A | 42
108+
X | 0b01110110 | 0x76 | 118
109+
y | 0b01101110 | 0x6E | 110
110+
Z | 0b01011011 | 0x5B | 91
86111
blank | 0b00000000 | 0x00 | 0
87-
\- | 0b01000000 | 0x40 | 64
112+
\- | 0b01000000 | 0x40 | 64
113+
\* | 0b01100011 | 0x63 | 99
114+
115+
# Methods
116+
117+
Get or set brightness.
118+
```
119+
brightness(val=None)
120+
```
121+
122+
Write one or more segments at a given offset.
123+
```
124+
write(segments, pos=0)
125+
```
126+
127+
Convert a single hex digit (0x00-0x0f) to a segment.
128+
```
129+
encode_digit(digit)
130+
```
131+
132+
Convert a string to a list of segments.
133+
```
134+
encode_string(string)
135+
```
136+
137+
Convert a single character to a segment.
138+
```
139+
encode_char(char)
140+
```
141+
142+
Display a number in hexadecimal format 0000 through FFFF.
143+
```
144+
hex(val)
145+
```
146+
147+
Display a number -999 through 9999, right aligned.
148+
```
149+
number(num)
150+
```
151+
152+
Display 2 independent numbers on either side of the (optional) colon, with leading zeros.
153+
```
154+
numbers(num1, num2, colon=True)
155+
```
156+
157+
Display a temperature -9 through 99 followed by degrees C.
158+
```
159+
temperature(num)
160+
```
161+
162+
Show a string on the display.
163+
Shorthand for write(encode_string()).
164+
Limited to first 4 characters.
165+
```
166+
show(string, colon=False)
167+
```
168+
169+
Display a string on the display, scrolling from the right to left, speed adjustable.
170+
String starts off-screen and scrolls until off-screen at 4 FPS by default.
171+
```
172+
scroll(string, delay=250)
173+
```
88174

89175
## Parts
90176

@@ -103,9 +189,10 @@ G | GND
103189

104190
## Links
105191

106-
* [WeMos D1 Mini](http://www.wemos.cc/Products/d1_mini.html)
192+
* [WeMos D1 Mini](https://wiki.wemos.cc/products:d1:d1_mini)
107193
* [micropython.org](http://micropython.org)
108194
* [TM1637 datasheet](http://www.titanmec.com/index.php/en/project/download/id/302.html)
109195
* [Titan Micro TM1637 product page](http://www.titanmec.com/index.php/en/project/view/id/302.html)
110196
* [Nokia 5110 version](https://github.com/mcauser/MicroPython-ESP8266-Nokia-5110-Quad-7-segment)
197+
* [BBC micro:bit version](https://github.com/mcauser/microbit-tm1637)
111198
* [Adafruit Ampy](https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy)

docs/demo.jpg

-224 KB
Loading

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
setup(
88
name='micropython-tm1637',
99
py_modules=['tm1637'],
10-
version='1.2.0',
10+
version='1.3.0',
1111
description='MicroPython library for TM1637 LED driver.',
1212
long_description='This library lets you operate quad 7-segment LED display modules based on the TM1637 LED driver.',
1313
keywords='tm1637 seven segment led micropython',

tm1637.py

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
from micropython import const
44
from machine import Pin
5-
from time import sleep_us
5+
from time import sleep_us, sleep_ms
66

77
TM1637_CMD1 = const(64) # 0x40 data command
88
TM1637_CMD2 = const(192) # 0xC0 address command
99
TM1637_CMD3 = const(128) # 0x80 display control command
1010
TM1637_DSP_ON = const(8) # 0x08 display on
1111
TM1637_DELAY = const(10) # 10us delay between clk/dio pulses
1212

13-
# 0-9, a-f, blank, dash
14-
_SEGMENTS = [63,6,91,79,102,109,125,7,127,111,119,124,57,94,121,113,0,64]
13+
# 0-9, a-z, blank, dash, star
14+
_SEGMENTS = bytearray(b'\x3F\x06\x5B\x4F\x66\x6D\x7D\x07\x7F\x6F\x77\x7C\x39\x5E\x79\x71\x3D\x76\x06\x1E\x76\x38\x55\x54\x3F\x73\x67\x50\x6D\x78\x3E\x1C\x2A\x76\x6E\x5B\x00\x40\x63')
1515

1616
class TM1637(object):
1717
"""Library for quad 7-segment LED modules based on the TM1637 LED driver."""
@@ -106,30 +106,27 @@ def encode_string(self, string):
106106
"""Convert an up to 4 character length string containing 0-9, a-f,
107107
space, dash to an array of segments, matching the length of the
108108
source string."""
109-
segments = bytearray(4)
110-
for i in range(0, min(4, len(string))):
109+
segments = bytearray(len(string))
110+
for i in range(len(string)):
111111
segments[i] = self.encode_char(string[i])
112112
return segments
113113

114114
def encode_char(self, char):
115-
"""Convert a character 0-9, a-f, space or dash to a segment."""
115+
"""Convert a character 0-9, a-z, space or dash to a segment."""
116116
o = ord(char)
117-
# space
118117
if o == 32:
119-
return _SEGMENTS[16]
120-
# dash
118+
return _SEGMENTS[36] # space
119+
if o == 42:
120+
return _SEGMENTS[38] # star/degrees
121121
if o == 45:
122-
return _SEGMENTS[17]
123-
# uppercase A-F
124-
if o >= 65 and o <= 70:
125-
return _SEGMENTS[o-55]
126-
# lowercase a-f
127-
if o >= 97 and o <= 102:
128-
return _SEGMENTS[o-87]
129-
# 0-9
122+
return _SEGMENTS[37] # dash
123+
if o >= 65 and o <= 90:
124+
return _SEGMENTS[o-55] # uppercase A-Z
125+
if o >= 97 and o <= 122:
126+
return _SEGMENTS[o-87] # lowercase a-z
130127
if o >= 48 and o <= 57:
131-
return _SEGMENTS[o-48]
132-
raise ValueError("Character out of range")
128+
return _SEGMENTS[o-48] # 0-9
129+
raise ValueError("Character out of range: {:d} '{:s}'".format(o, chr(o)))
133130

134131
def hex(self, val):
135132
"""Display a hex value 0x0000 through 0xffff, right aligned."""
@@ -149,17 +146,30 @@ def numbers(self, num1, num2, colon=True):
149146
num1 = max(-9, min(num1, 99))
150147
num2 = max(-9, min(num2, 99))
151148
segments = self.encode_string('{0:0>2d}{1:0>2d}'.format(num1, num2))
152-
# colon on
153149
if colon:
154-
segments[1] |= 0x80
150+
segments[1] |= 0x80 # colon on
155151
self.write(segments)
156152

157153
def temperature(self, num):
158154
if num < -9:
159-
self.write([0x38, 0x3F]) # LO
155+
self.show('lo') # low
160156
elif num > 99:
161-
self.write([0x76, 0x06]) # HI
157+
self.show('hi') # high
162158
else:
163159
string = '{0: >2d}'.format(num)
164160
self.write(self.encode_string(string))
165-
self.write([0x63, 0x39], 2) # degrees C
161+
self.write([_SEGMENTS[38], _SEGMENTS[12]], 2) # degrees C
162+
163+
def show(self, string, colon=False):
164+
segments = self.encode_string(string)
165+
if len(segments) > 1 and colon:
166+
segments[1] |= 128
167+
self.write(segments[:4])
168+
169+
def scroll(self, string, delay=250):
170+
segments = string if isinstance(string, list) else self.encode_string(string)
171+
data = [0] * 8
172+
data[4:0] = list(segments)
173+
for i in range(len(segments) + 5):
174+
self.write(data[0+i:4+i])
175+
sleep_ms(delay)

tm1637_test.py

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,85 @@
1212

1313
# all LEDS on "88:88"
1414
tm.write([127, 255, 127, 127])
15+
tm.write(bytearray([127, 255, 127, 127]))
16+
tm.write(b'\x7F\xFF\x7F\x7F')
17+
tm.show('8888', True)
18+
tm.numbers(88, 88, True)
1519

1620
# all LEDS off
1721
tm.write([0, 0, 0, 0])
22+
tm.show(' ')
23+
24+
# write to the 2nd and 3rd segments only
25+
tm.write([119, 124], 1) # _Ab_
26+
tm.write([124], 2) # __b_
27+
tm.write([119], 1) # _A__
1828

1929
# display "0123"
2030
tm.write([63, 6, 91, 79])
2131
tm.write(bytearray([63, 6, 91, 79]))
32+
tm.write(b'\x3F\x06\x5B\x4F')
33+
tm.show('1234')
34+
tm.number(1234)
35+
tm.numbers(12, 34, False)
2236

2337
# display "4567"
2438
tm.write([102, 109, 125, 7])
39+
tm.write([102], 0) # 4___
40+
tm.write([109], 1) # _5__
41+
tm.write([125], 2) # __6_
42+
tm.write([7], 3) # ___7
2543

26-
# set middle two segments to "12", "4127"
27-
tm.write([6, 91], 1)
44+
# set middle two segments to "12", ie "4127"
45+
tm.write([6, 91], 1) # _12_
2846

29-
# set last segment to "9", "4129"
30-
tm.write([111], 3)
47+
# set last segment to "9", ie "4129"
48+
tm.write([111], 3) # ___9
3149

3250
# walk through all possible LED combinations
51+
from time import sleep_ms
3352
for i in range(128):
34-
tm.write([i, i | 0x80, i, i])
53+
tm.number(i)
54+
tm.write([i])
55+
sleep_ms(100)
3556

3657
# show "AbCd"
3758
tm.write([119, 124, 57, 94])
59+
tm.show('abcd')
3860

3961
# show "COOL"
4062
tm.write([0b00111001, 0b00111111, 0b00111111, 0b00111000])
63+
tm.write([0x39, 0x3F, 0x3F, 0x38])
64+
tm.write(b'\x39\x3F\x3F\x38')
65+
tm.write([57, 63, 63, 56])
66+
tm.show('cool')
67+
tm.show('COOL')
68+
69+
# display "dEAd", "bEEF"
70+
tm.hex(0xdead)
71+
tm.hex(0xbeef)
72+
tm.show('dead')
73+
tm.show('Beef')
74+
75+
# show "12:59"
76+
tm.numbers(12, 59)
77+
tm.show('1259', True)
78+
79+
# show "-123"
80+
tm.number(-123)
81+
tm.show('-123')
82+
83+
# Show Help
84+
tm.show('Help')
85+
tm.write(tm.encode_string('Help'))
86+
tm.write([tm.encode_char('H'), tm.encode_char('e'), tm.encode_char('l'), tm.encode_char('p')])
87+
88+
# Scroll Hello World from right to left
89+
tm.scroll('Hello World') # 4 fps
90+
tm.scroll('Hello World', 1000) # 1 fps
91+
92+
# Scroll all available characters
93+
tm.scroll(list(tm1637._SEGMENTS))
4194

4295
# all LEDs dim
4396
tm.brightness(0)
@@ -110,7 +163,7 @@
110163
tm.hex(0xcafe)
111164
tm.hex(0xbabe)
112165

113-
# show " FF" (hex right aligned)
166+
# show "00FF" (hex right aligned)
114167
tm.hex(0xff)
115168

116169
# show " 1" (numbers right aligned)
@@ -138,16 +191,20 @@
138191
tm.number(-1234)
139192

140193
# show "01:02"
141-
tm.numbers(1,2)
194+
tm.numbers(1, 2)
195+
196+
# show "0102"
197+
tm.numbers(1, 2, False)
142198

143199
# show "-5:11"
144-
tm.numbers(-5,11)
200+
tm.numbers(-5, 11)
145201

146202
# show "12:59"
147-
tm.numbers(12,59)
203+
tm.numbers(12, 59)
148204

149205
# show temperature '24*C'
150206
tm.temperature(24)
207+
tm.show('24*C')
151208

152209
# show temperature works for range -9 to +99
153210
tm.temperature(-10) # LO*C

0 commit comments

Comments
 (0)