Raspberry Pi Pico
TM1637 4 Digit Display
The TM1637 is an LED driver. There are lots of cheap 4 and 6 digit displays that use it. You can pick these up for a a few pounds if you look around. I have had this one for a while now and finally decided to find out how to use it whilst some of my students were doing a long assessment.
This is how the board looks. It came with some male headers pre-soldered meaning it would stand vertically in a breadboard if you didn't use the male to female jumper cables.
Here is a Fritzing diagram showing how to connect the circuit.
from time import sleep_us from micropython import const _CMD1 = const(64) _CMD2 = const(192) _CMD3 = const(128) _BIT_DELAY = 10 class TM1637: def __init__(self, clk, dio): self.clk = clk self.dio = dio self.data = [0, 0, 0, 0] self.set_brightness(7) def set_brightness(self, b, on=1): if b<0 or b>7: return self.brightness = b + (on * 8) self.start() self.write_byte(_CMD3 + self.brightness) self.stop() def start(self): self.dio.value(0) sleep_us(_BIT_DELAY) self.clk.value(0) sleep_us(_BIT_DELAY) def stop(self): self.dio.value(0) sleep_us(_BIT_DELAY) self.clk.value(1) sleep_us(_BIT_DELAY) self.dio.value(1) def write_byte(self, b): bits = [b >> i & 1 for i in range(8)] for b in bits: self.dio.value(b) sleep_us(_BIT_DELAY) self.clk.value(1) sleep_us(_BIT_DELAY) self.clk.value(0) sleep_us(_BIT_DELAY) self.clk.value(0) sleep_us(_BIT_DELAY) self.clk.value(1) sleep_us(_BIT_DELAY) self.clk.value(0) sleep_us(_BIT_DELAY) def write_digits(self, colon=True): seg_data = [0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F] bitdata = [seg_data[d] for d in self.data] if colon: bitdata[1] |= 128 self.start() self.write_byte(_CMD1) self.stop() self.start() self.write_byte(_CMD2) for digit in bitdata: self.write_byte(digit) self.stop() self.start() self.write_byte(_CMD3 + self.brightness) self.stop() # write a list of 4 binary values def write_raw(self, digits): self.data = digits self.start() self.write_byte(_CMD1) self.stop() self.start() self.write_byte(_CMD2) for digit in digits: self.write_byte(digit) self.stop() self.start() self.write_byte(_CMD3 + self.brightness) self.stop() def display_number(self, num, colon = True): if num < 0 or num > 9999: return sdig = '{:04d}'.format(num) self.data = [int(x) for x in sdig] self.write_digits(colon)
Here is the test code I used,
from machine import Pin from time import sleep from tm1637 import TM1637 clk = Pin(17, Pin.OUT) dio = Pin(16, Pin.OUT) t = TM1637(clk, dio) t.write_raw([127, 255, 127, 127]) for i in range(8): t.set_brightness(7 - i) sleep(1) t.set_brightness(7) sleep(1) # off and on again t.set_brightness(7, False) sleep(1) t.set_brightness(7, True) sleep(1) for i in range(10000): t.display_number(i, False) sleep(0.1)
When I finally got this to work, I was reasonably impressed with it. It can use any pins you like because it has a custom protocol and these displays are really cheap. There is no decimal point on my display and I find the colon to be a little cramped. It's still good enough to get across some numbers or the time when you need it to. I suspect I will find myself using this a lot in the future.