MicroPython Driver for TM1637 & 4-Digit LED Display

TM1637 Driver Code for micro:bit

Download as zip file

'''
TM1637 7-Segment LED 4-Digit
MicroPython driver for micro:bit

AUTHOR: fredscave.com
DATE:   Dec, 2024
VERSION 1.00
'''

from microbit import *
from micropython import const

CMD_DATA = const(0b01000000)
CMD_ON = const(0b10001000)
CMD_OFF = const(0b10000000)
ADDR_DISPLAY = const(0xC0)

PATTERN = {'0':0x3F, '1':0x06, '2':0x5B, '3':0x4F, '4':0x66,
           '5':0x6D, '6':0x7D, '7':0x07, '8':0x7F, '9':0x6F,
           ' ':0x00, '-':0x40}

class TM1637():
    def __init__(self, CLK=pin8, DIO=pin9, Bright=7):
        self.CLK = CLK
        self.DIO = DIO
        self.SetBrightness(Bright)
        self.Digits = bytearray([0, 0, 0, 0])

    def _Start(self):
        self.DIO.write_digital(0)
        self.CLK.write_digital(0)

    def _Stop(self):
        self.DIO.write_digital(0)
        self.CLK.write_digital(1)
        self.DIO.write_digital(1)

    def _Write_Byte(self, digit):
        for i in range(8):
            self.DIO.write_digital((digit >> i) & 1)
            self.CLK.write_digital(1)
            self.CLK.write_digital(0)
        self.CLK.write_digital(0)
        self.CLK.write_digital(1)
        self.CLK.write_digital(0)

    def _Write_Bytes(self):
        self._Send_Data_CMD()
        self._Start()
        self._Write_Byte(ADDR_DISPLAY)
        for digit in self.Digits:
            self._Write_Byte(digit)
        self._Stop()
        self._Display_Control()

    def _Send_Data_CMD(self):
        self._Start()
        self._Write_Byte(CMD_DATA)
        self._Stop()

    def _Display_Control(self):
        self._Start()
        self._Write_Byte(CMD_ON | self.Bright)
        self._Stop()

    def SetBrightness(self, Bright):
        self.Bright = Bright
        if Bright not in range(8):
            self.Bright = 7
        self._Send_Data_CMD()
        self._Display_Control()

    def GetBrightness(self):
        return self.Bright

    def Test(self):
        self.Digits = [0b11111111] * 4
        self._Write_Bytes()

    def Off(self):
        self._Send_Data_CMD()
        self._Start()
        self._Write_Byte(CMD_OFF)
        self._Stop()

    def WriteNumber(self, Number, Bright=None):
        if isinstance(Number, int):
            self._Integer(Number)
        if isinstance(Number, float):
            self._Float(Number)
        if Bright != None:
            self.SetBrightness(Bright)
        self._Write_Bytes()

    def WriteTime(self, Num1, Num2):
        data_list = ['-'] * 4
        isint1 = isinstance(Num1, int)
        isint2 = isinstance(Num2, int)
        if isint1 and isint2:
            inrange1 = Num1 in range(0, 100)
            inrange2 = Num2 in range(0, 100)
            if inrange1 and inrange2:
                if Num1 < 10:
                   data_list[0] = ' '
                   data_list[1] = str(Num1)
                else:
                    data_list[0] = str(Num1)[0]
                    data_list[1] = str(Num1)[1]
                if Num2 < 10:
                    data_list[2] = '0'
                    data_list[3] = str(Num2)
                else:
                    data_list[2] = str(Num2)[0]
                    data_list[3] = str(Num2)[1]
        self.Digits = self._Parse(data_list)
        self.Digits[1] |= 0b10000000
        self._Write_Bytes()

    def _Float(self, Number):
        if Number > 9999:
            self.Digits = self._Parse(['9', '9', '9', '9'])
            return
        elif abs(Number) > 999:
            self.Digits = self._Parse(['-', '9', '9', '9'])
            return
        elif self._Float_Too_Small(Number):
            self.Digits = self._Parse(['-', '-', '-', '-'])
            return
        else:
            dp = str(Number).find('.')
            data = round(Number, 4-dp)
            if dp == 4:
                data = int(data)
        dp -= 1
        data_list = list(str(data).replace('.', ''))
        spaces = 4 - len(data_list)
        dp += spaces
        data_list = ([' '] * spaces) + data_list
        self.Digits = self._Parse(data_list)
        self.Digits[dp] = self.Digits[dp] | 0b10000000

    def _Float_Too_Small(self, Number):
        if (Number < 0) and (int(round(Number, 2) * 100) == 0):
            return True
        elif (Number > 0) and (int(round(Number, 3) * 1000) == 0):
            return True
        else:
            return False

    def _Integer(self, Number):
        if Number > 9999:
            self.Digits = self._Parse(['9', '9', '9', '9'])
        elif Number < -999:
            self.Digits = self._Parse(['-', '9', '9', '9'])
        else:
            data_string = str(Number)
            data_list = [' ', ' ', ' ', ' ']
            start = 4-len(data_string)
            for x in range(start, 4):
                data_list[x] = data_string[x-start]
            self.Digits = self._Parse(data_list)

    def _Parse(self, data_list):
        digits = bytearray(4)
        for x in range(4):
            digits[x] = PATTERN.get(data_list[x], 0x00)
        return digits