diff --git a/README.md b/README.md index f59c22b..b976cca 100644 --- a/README.md +++ b/README.md @@ -27,18 +27,21 @@ tm.write([127, 255, 127, 127]) # all LEDS off tm.write([0, 0, 0, 0]) -# display "0123" +# show "0123" tm.write([63, 6, 91, 79]) # show "COOL" tm.write([0b00111001, 0b00111111, 0b00111111, 0b00111000]) +# show "HELP" +tm.show('help') + # display "dEAd", "bEEF" tm.hex(0xdead) tm.hex(0xbeef) # show "12:59" -tm.numbers(12,59) +tm.numbers(12, 59) # show "-123" tm.number(-123) @@ -47,7 +50,9 @@ tm.number(-123) tm.temperature(24) ``` -For more detailed examples, see ![tm1637_test.py](tm1637_test.py) +For more detailed examples, see [tm1637_test.py](tm1637_test.py) + +# Seven Segment Font They are called 7-segment displays as there are 7 LEDs for each digit (segment). 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 d | 0b01011110 | 0x5E | 94 E | 0b01111001 | 0x79 | 121 F | 0b01110001 | 0x71 | 113 +G | 0b00111101 | 0x3D | 61 +H | 0b01110110 | 0x76 | 118 +I | 0b00000110 | 0x06 | 6 +J | 0b00011110 | 0x1E | 30 +K | 0b01110110 | 0x76 | 118 +L | 0b00111000 | 0x38 | 56 +M | 0b01010101 | 0x55 | 85 +n | 0b01010100 | 0x54 | 84 +O | 0b00111111 | 0x3F | 63 +P | 0b01110011 | 0x73 | 115 +q | 0b01100111 | 0x67 | 103 +r | 0b01010000 | 0x50 | 80 +S | 0b01101101 | 0x6D | 109 +t | 0b01111000 | 0x78 | 120 +U | 0b00111110 | 0x3E | 62 +v | 0b00011100 | 0x1C | 28 +W | 0b00101010 | 0x2A | 42 +X | 0b01110110 | 0x76 | 118 +y | 0b01101110 | 0x6E | 110 +Z | 0b01011011 | 0x5B | 91 blank | 0b00000000 | 0x00 | 0 -\- | 0b01000000 | 0x40 | 64 +\- | 0b01000000 | 0x40 | 64 +\* | 0b01100011 | 0x63 | 99 + +# Methods + +Get or set brightness. +``` +brightness(val=None) +``` + +Write one or more segments at a given offset. +``` +write(segments, pos=0) +``` + +Convert a single hex digit (0x00-0x0f) to a segment. +``` +encode_digit(digit) +``` + +Convert a string to a list of segments. +``` +encode_string(string) +``` + +Convert a single character to a segment. +``` +encode_char(char) +``` + +Display a number in hexadecimal format 0000 through FFFF. +``` +hex(val) +``` + +Display a number -999 through 9999, right aligned. +``` +number(num) +``` + +Display 2 independent numbers on either side of the (optional) colon, with leading zeros. +``` +numbers(num1, num2, colon=True) +``` + +Display a temperature -9 through 99 followed by degrees C. +``` +temperature(num) +``` + +Show a string on the display. +Shorthand for write(encode_string()). +Limited to first 4 characters. +``` +show(string, colon=False) +``` + +Display a string on the display, scrolling from the right to left, speed adjustable. +String starts off-screen and scrolls until off-screen at 4 FPS by default. +``` +scroll(string, delay=250) +``` ## Parts @@ -103,9 +189,10 @@ G | GND ## Links -* [WeMos D1 Mini](http://www.wemos.cc/Products/d1_mini.html) +* [WeMos D1 Mini](https://wiki.wemos.cc/products:d1:d1_mini) * [micropython.org](http://micropython.org) * [TM1637 datasheet](http://www.titanmec.com/index.php/en/project/download/id/302.html) * [Titan Micro TM1637 product page](http://www.titanmec.com/index.php/en/project/view/id/302.html) * [Nokia 5110 version](https://github.com/mcauser/MicroPython-ESP8266-Nokia-5110-Quad-7-segment) +* [BBC micro:bit version](https://github.com/mcauser/microbit-tm1637) * [Adafruit Ampy](https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy) diff --git a/docs/demo.jpg b/docs/demo.jpg index da3d8c8..9537a4b 100644 Binary files a/docs/demo.jpg and b/docs/demo.jpg differ diff --git a/setup.py b/setup.py index f0c60b2..68e87e8 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='micropython-tm1637', py_modules=['tm1637'], - version='1.2.0', + version='1.3.0', description='MicroPython library for TM1637 LED driver.', long_description='This library lets you operate quad 7-segment LED display modules based on the TM1637 LED driver.', keywords='tm1637 seven segment led micropython', diff --git a/tm1637.py b/tm1637.py index 4b56064..785e661 100644 --- a/tm1637.py +++ b/tm1637.py @@ -2,7 +2,7 @@ from micropython import const from machine import Pin -from time import sleep_us +from time import sleep_us, sleep_ms TM1637_CMD1 = const(64) # 0x40 data command TM1637_CMD2 = const(192) # 0xC0 address command @@ -10,8 +10,8 @@ TM1637_DSP_ON = const(8) # 0x08 display on TM1637_DELAY = const(10) # 10us delay between clk/dio pulses -# 0-9, a-f, blank, dash -_SEGMENTS = [63,6,91,79,102,109,125,7,127,111,119,124,57,94,121,113,0,64] +# 0-9, a-z, blank, dash, star +_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') class TM1637(object): """Library for quad 7-segment LED modules based on the TM1637 LED driver.""" @@ -106,30 +106,27 @@ def encode_string(self, string): """Convert an up to 4 character length string containing 0-9, a-f, space, dash to an array of segments, matching the length of the source string.""" - segments = bytearray(4) - for i in range(0, min(4, len(string))): + segments = bytearray(len(string)) + for i in range(len(string)): segments[i] = self.encode_char(string[i]) return segments def encode_char(self, char): - """Convert a character 0-9, a-f, space or dash to a segment.""" + """Convert a character 0-9, a-z, space or dash to a segment.""" o = ord(char) - # space if o == 32: - return _SEGMENTS[16] - # dash + return _SEGMENTS[36] # space + if o == 42: + return _SEGMENTS[38] # star/degrees if o == 45: - return _SEGMENTS[17] - # uppercase A-F - if o >= 65 and o <= 70: - return _SEGMENTS[o-55] - # lowercase a-f - if o >= 97 and o <= 102: - return _SEGMENTS[o-87] - # 0-9 + return _SEGMENTS[37] # dash + if o >= 65 and o <= 90: + return _SEGMENTS[o-55] # uppercase A-Z + if o >= 97 and o <= 122: + return _SEGMENTS[o-87] # lowercase a-z if o >= 48 and o <= 57: - return _SEGMENTS[o-48] - raise ValueError("Character out of range") + return _SEGMENTS[o-48] # 0-9 + raise ValueError("Character out of range: {:d} '{:s}'".format(o, chr(o))) def hex(self, val): """Display a hex value 0x0000 through 0xffff, right aligned.""" @@ -149,17 +146,30 @@ def numbers(self, num1, num2, colon=True): num1 = max(-9, min(num1, 99)) num2 = max(-9, min(num2, 99)) segments = self.encode_string('{0:0>2d}{1:0>2d}'.format(num1, num2)) - # colon on if colon: - segments[1] |= 0x80 + segments[1] |= 0x80 # colon on self.write(segments) def temperature(self, num): if num < -9: - self.write([0x38, 0x3F]) # LO + self.show('lo') # low elif num > 99: - self.write([0x76, 0x06]) # HI + self.show('hi') # high else: string = '{0: >2d}'.format(num) self.write(self.encode_string(string)) - self.write([0x63, 0x39], 2) # degrees C + self.write([_SEGMENTS[38], _SEGMENTS[12]], 2) # degrees C + + def show(self, string, colon=False): + segments = self.encode_string(string) + if len(segments) > 1 and colon: + segments[1] |= 128 + self.write(segments[:4]) + + def scroll(self, string, delay=250): + segments = string if isinstance(string, list) else self.encode_string(string) + data = [0] * 8 + data[4:0] = list(segments) + for i in range(len(segments) + 5): + self.write(data[0+i:4+i]) + sleep_ms(delay) diff --git a/tm1637_test.py b/tm1637_test.py index 3964b39..248f02b 100644 --- a/tm1637_test.py +++ b/tm1637_test.py @@ -12,32 +12,85 @@ # all LEDS on "88:88" tm.write([127, 255, 127, 127]) +tm.write(bytearray([127, 255, 127, 127])) +tm.write(b'\x7F\xFF\x7F\x7F') +tm.show('8888', True) +tm.numbers(88, 88, True) # all LEDS off tm.write([0, 0, 0, 0]) +tm.show(' ') + +# write to the 2nd and 3rd segments only +tm.write([119, 124], 1) # _Ab_ +tm.write([124], 2) # __b_ +tm.write([119], 1) # _A__ # display "0123" tm.write([63, 6, 91, 79]) tm.write(bytearray([63, 6, 91, 79])) +tm.write(b'\x3F\x06\x5B\x4F') +tm.show('1234') +tm.number(1234) +tm.numbers(12, 34, False) # display "4567" tm.write([102, 109, 125, 7]) +tm.write([102], 0) # 4___ +tm.write([109], 1) # _5__ +tm.write([125], 2) # __6_ +tm.write([7], 3) # ___7 -# set middle two segments to "12", "4127" -tm.write([6, 91], 1) +# set middle two segments to "12", ie "4127" +tm.write([6, 91], 1) # _12_ -# set last segment to "9", "4129" -tm.write([111], 3) +# set last segment to "9", ie "4129" +tm.write([111], 3) # ___9 # walk through all possible LED combinations +from time import sleep_ms for i in range(128): - tm.write([i, i | 0x80, i, i]) + tm.number(i) + tm.write([i]) + sleep_ms(100) # show "AbCd" tm.write([119, 124, 57, 94]) +tm.show('abcd') # show "COOL" tm.write([0b00111001, 0b00111111, 0b00111111, 0b00111000]) +tm.write([0x39, 0x3F, 0x3F, 0x38]) +tm.write(b'\x39\x3F\x3F\x38') +tm.write([57, 63, 63, 56]) +tm.show('cool') +tm.show('COOL') + +# display "dEAd", "bEEF" +tm.hex(0xdead) +tm.hex(0xbeef) +tm.show('dead') +tm.show('Beef') + +# show "12:59" +tm.numbers(12, 59) +tm.show('1259', True) + +# show "-123" +tm.number(-123) +tm.show('-123') + +# Show Help +tm.show('Help') +tm.write(tm.encode_string('Help')) +tm.write([tm.encode_char('H'), tm.encode_char('e'), tm.encode_char('l'), tm.encode_char('p')]) + +# Scroll Hello World from right to left +tm.scroll('Hello World') # 4 fps +tm.scroll('Hello World', 1000) # 1 fps + +# Scroll all available characters +tm.scroll(list(tm1637._SEGMENTS)) # all LEDs dim tm.brightness(0) @@ -110,7 +163,7 @@ tm.hex(0xcafe) tm.hex(0xbabe) -# show " FF" (hex right aligned) +# show "00FF" (hex right aligned) tm.hex(0xff) # show " 1" (numbers right aligned) @@ -138,16 +191,20 @@ tm.number(-1234) # show "01:02" -tm.numbers(1,2) +tm.numbers(1, 2) + +# show "0102" +tm.numbers(1, 2, False) # show "-5:11" -tm.numbers(-5,11) +tm.numbers(-5, 11) # show "12:59" -tm.numbers(12,59) +tm.numbers(12, 59) # show temperature '24*C' tm.temperature(24) +tm.show('24*C') # show temperature works for range -9 to +99 tm.temperature(-10) # LO*C