├── files ├── main.py └── lib │ └── TM1637.py ├── Readme.md └── License /files/main.py: -------------------------------------------------------------------------------- 1 | import time 2 | import TM1637 3 | import board 4 | 5 | if __name__ == "__main__": 6 | CLK = board.D6 7 | DIO = board.D13 8 | display = TM1637.TM1637(CLK, DIO) 9 | display.hex(0xbeef) 10 | time.sleep(5) 11 | while True: 12 | t = time.localtime() 13 | display.numbers(t.tm_hour,t.tm_min) 14 | time.sleep(60-(t.tm_sec%60)) 15 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | CircuitPython library für the TM1637 7-Segment Display 2 | ====================================================== 3 | 4 | This is a CircuitPython port of the MicroPython TM1637 library from 5 | [https://github.com/mcauser/micropython-tm1637](https://github.com/mcauser/micropython-tm1637). 6 | 7 | 8 | Installation 9 | ------------ 10 | 11 | Copy the file `files/lib/TM1637.py` to your `lib`-folder. 12 | 13 | 14 | Usage 15 | ----- 16 | 17 | There is a simple example in `files/main.py`. The original MicroPython-repository has a number 18 | of examples, links to documentation and some background info in the Readme. 19 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright (c) 2016 Mike Causer (MicroPython original) 3 | Copyright (c) 2019 Bernhard Bablok (CircuitPython port) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /files/lib/TM1637.py: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------------- 2 | # CircuitPython library for TM1637 quad 7-segment LED displays 3 | # 4 | # This core of the code is from a micropython implementation from: 5 | # https://github.com/mcauser/micropython-tm1637 6 | # 7 | # Adapted to CircuitPython with minor modifications by Bernhard Bablok 8 | # 9 | # Website: https://github.com/bablokb/circuitpython-tm1637 10 | # 11 | # ----------------------------------------------------------------------------- 12 | 13 | """ 14 | MIT License 15 | Copyright (c) 2016 Mike Causer 16 | 17 | Permission is hereby granted, free of charge, to any person obtaining a copy 18 | of this software and associated documentation files (the "Software"), to deal 19 | in the Software without restriction, including without limitation the rights 20 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 21 | copies of the Software, and to permit persons to whom the Software is 22 | furnished to do so, subject to the following conditions: 23 | 24 | The above copyright notice and this permission notice shall be included in all 25 | copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 | SOFTWARE. 34 | """ 35 | 36 | import digitalio 37 | import time 38 | 39 | class TM1637(object): 40 | """Library for quad 7-segment LED modules based on the TM1637 LED driver.""" 41 | 42 | _CMD1 = 0x40 # data command 43 | _CMD2 = 0xC0 # address command 44 | _CMD3 = 0x80 # display control command 45 | _DSP_ON = 0x08 # display on 46 | _DELAY = 0.000010 # 10us delay between clk/dio pulses 47 | _MSB = 0x80 # decimal point or colon depending on your display 48 | 49 | # 0-9, a-z, blank, dash, star 50 | _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') 51 | 52 | def __init__(self, clk, dio, brightness=7): 53 | if not 0 <= brightness <= 7: 54 | raise ValueError("Brightness out of range") 55 | self._brightness = brightness 56 | 57 | self._clk = digitalio.DigitalInOut(clk) 58 | self._clk.direction = digitalio.Direction.OUTPUT 59 | self._clk.value = 0 60 | self._dio = digitalio.DigitalInOut(dio) 61 | self._dio.direction = digitalio.Direction.OUTPUT 62 | self._dio.value = 0 63 | time.sleep(TM1637._DELAY) 64 | self._write_data_cmd() 65 | self._write_dsp_ctrl() 66 | 67 | def _start(self): 68 | self._dio.value = 0 69 | time.sleep(TM1637._DELAY) 70 | self._clk.value = 0 71 | time.sleep(TM1637._DELAY) 72 | 73 | def _stop(self): 74 | self._dio.value = 0 75 | time.sleep(TM1637._DELAY) 76 | self._clk.value = 1 77 | time.sleep(TM1637._DELAY) 78 | self._dio.value = 1 79 | 80 | def _write_data_cmd(self): 81 | # automatic address increment, normal mode 82 | self._start() 83 | self._write_byte(TM1637._CMD1) 84 | self._stop() 85 | 86 | def _write_dsp_ctrl(self): 87 | # display on, set brightness 88 | self._start() 89 | self._write_byte(TM1637._CMD3 | TM1637._DSP_ON | self._brightness) 90 | self._stop() 91 | 92 | def _write_byte(self, b): 93 | for i in range(8): 94 | self._dio.value = (b >> i) & 1 95 | time.sleep(TM1637._DELAY) 96 | self._clk.value = 1 97 | time.sleep(TM1637._DELAY) 98 | self._clk.value = 0 99 | time.sleep(TM1637._DELAY) 100 | self._clk.value = 0 101 | time.sleep(TM1637._DELAY) 102 | self._clk.value = 1 103 | time.sleep(TM1637._DELAY) 104 | self._clk.value = 0 105 | time.sleep(TM1637._DELAY) 106 | 107 | def brightness(self, val=None): 108 | """Set the display brightness 0-7.""" 109 | # brightness 0 = 1/16th pulse width 110 | # brightness 7 = 14/16th pulse width 111 | if val is None: 112 | return self._brightness 113 | if not 0 <= val <= 7: 114 | raise ValueError("Brightness out of range") 115 | 116 | self._brightness = val 117 | self._write_data_cmd() 118 | self._write_dsp_ctrl() 119 | 120 | def write(self, segments, pos=0): 121 | """Display up to 6 segments moving right from a given position. 122 | The MSB in the 2nd segment controls the colon between the 2nd 123 | and 3rd segments.""" 124 | if not 0 <= pos <= 5: 125 | raise ValueError("Position out of range") 126 | self._write_data_cmd() 127 | self._start() 128 | 129 | self._write_byte(TM1637._CMD2 | pos) 130 | for seg in segments: 131 | self._write_byte(seg) 132 | self._stop() 133 | self._write_dsp_ctrl() 134 | 135 | def encode_digit(self, digit): 136 | """Convert a character 0-9, a-f to a segment.""" 137 | return TM1637._SEGMENTS[digit & 0x0f] 138 | 139 | def encode_string(self, string): 140 | """Convert an up to 4 character length string containing 0-9, a-z, 141 | space, dash, star to an array of segments, matching the length of the 142 | source string.""" 143 | segments = bytearray(len(string)) 144 | for i in range(len(string)): 145 | segments[i] = self.encode_char(string[i]) 146 | return segments 147 | 148 | def encode_char(self, char): 149 | """Convert a character 0-9, a-z, space, dash or star to a segment.""" 150 | o = ord(char) 151 | if o == 32: 152 | return TM1637._SEGMENTS[36] # space 153 | if o == 42: 154 | return TM1637._SEGMENTS[38] # star/degrees 155 | if o == 45: 156 | return TM1637._SEGMENTS[37] # dash 157 | if o >= 65 and o <= 90: 158 | return TM1637._SEGMENTS[o-55] # uppercase A-Z 159 | if o >= 97 and o <= 122: 160 | return TM1637._SEGMENTS[o-87] # lowercase a-z 161 | if o >= 48 and o <= 57: 162 | return TM1637._SEGMENTS[o-48] # 0-9 163 | raise ValueError("Character out of range: {:d} '{:s}'".format(o, chr(o))) 164 | 165 | def hex(self, val): 166 | """Display a hex value 0x0000 through 0xffff, right aligned.""" 167 | string = '{:04x}'.format(val & 0xffff) 168 | self.write(self.encode_string(string)) 169 | 170 | def number(self, num): 171 | """Display a numeric value -999 through 9999, right aligned.""" 172 | # limit to range -999 to 9999 173 | num = max(-999, min(num, 9999)) 174 | string = '{0: >4d}'.format(num) 175 | self.write(self.encode_string(string)) 176 | 177 | def numbers(self, num1, num2, colon=True): 178 | """Display two numeric values -9 through 99, with leading zeros 179 | and separated by a colon.""" 180 | num1 = max(-9, min(num1, 99)) 181 | num2 = max(-9, min(num2, 99)) 182 | segments = self.encode_string('{0:0>2d}{1:0>2d}'.format(num1, num2)) 183 | if colon: 184 | segments[1] |= 0x80 # colon on 185 | self.write(segments) 186 | 187 | def temperature(self, num): 188 | if num < -9: 189 | self.show('lo') # low 190 | elif num > 99: 191 | self.show('hi') # high 192 | else: 193 | string = '{0: >2d}'.format(num) 194 | self.write(self.encode_string(string)) 195 | self.write([TM1637._SEGMENTS[38], TM1637._SEGMENTS[12]], 2) # degrees C 196 | 197 | def show(self, string, colon=False): 198 | segments = self.encode_string(string) 199 | if len(segments) > 1 and colon: 200 | segments[1] |= 128 201 | self.write(segments[:4]) 202 | 203 | def scroll(self, string, delay=0.25): 204 | segments = string if isinstance(string, list) else self.encode_string(string) 205 | data = [0] * 8 206 | data[4:0] = list(segments) 207 | for i in range(len(segments) + 5): 208 | self.write(data[0+i:4+i]) 209 | time.sleep(delay) 210 | 211 | # --------------------------------------------------------------------------- 212 | 213 | class TM1637Decimal(TM1637): 214 | """Library for quad 7-segment LED modules based on the TM1637 LED driver. 215 | 216 | This class is meant to be used with decimal display modules (modules 217 | that have a decimal point after each 7-segment LED). 218 | """ 219 | 220 | def encode_string(self, string): 221 | """Convert a string to LED segments. 222 | 223 | Convert an up to 4 character length string containing 0-9, a-z, 224 | space, dash, star and '.' to an array of segments, matching the length of 225 | the source string.""" 226 | segments = bytearray(len(string.replace('.',''))) 227 | j = 0 228 | for i in range(len(string)): 229 | if string[i] == '.' and j > 0: 230 | segments[j-1] |= TM1637._MSB 231 | continue 232 | segments[j] = self.encode_char(string[i]) 233 | j += 1 234 | return segments 235 | --------------------------------------------------------------------------------