Skip to content

Instantly share code, notes, and snippets.

@bradmartin333
Created May 14, 2026 16:04
Show Gist options
  • Select an option

  • Save bradmartin333/d7588e39345da6c838b0a98e5414c3a6 to your computer and use it in GitHub Desktop.

Select an option

Save bradmartin333/d7588e39345da6c838b0a98e5414c3a6 to your computer and use it in GitHub Desktop.
RP2040 TM1637 60FPS timecode
import board
import digitalio
import time
import touchio
from adafruit_debouncer import Button
# Update these pins to match your wiring.
TM1637_CLK_PIN = board.GP3
TM1637_DIO_PIN = board.GP4
DISPLAY_VSS_PIN = board.GP5
TOUCH_THRESHOLD_OFFSET = 1000
TOUCH_PIN_CANDIDATES = ("GP12", "A1", "A2", "TOUCH1", "TOUCH2")
FPS = 60
FRAME_PERIOD = 1.0 / FPS
class TM1637:
SEGMENTS = {
" ": 0x00,
"-": 0x40,
"0": 0x3F,
"1": 0x06,
"2": 0x5B,
"3": 0x4F,
"4": 0x66,
"5": 0x6D,
"6": 0x7D,
"7": 0x07,
"8": 0x7F,
"9": 0x6F,
}
def __init__(self, clk_pin, dio_pin, brightness=7):
self._clk = digitalio.DigitalInOut(clk_pin)
self._dio = digitalio.DigitalInOut(dio_pin)
self._clk.direction = digitalio.Direction.OUTPUT
self._dio.direction = digitalio.Direction.OUTPUT
self._clk.value = True
self._dio.value = True
self.set_brightness(brightness)
def set_brightness(self, brightness):
if brightness < 0:
brightness = 0
if brightness > 7:
brightness = 7
self._brightness = brightness
def _delay(self):
time.sleep(0.000005)
def _start(self):
self._dio.value = True
self._clk.value = True
self._delay()
self._dio.value = False
def _stop(self):
self._clk.value = False
self._delay()
self._dio.value = False
self._delay()
self._clk.value = True
self._delay()
self._dio.value = True
def _write_byte(self, value):
for _ in range(8):
self._clk.value = False
self._dio.value = bool(value & 0x01)
self._delay()
self._clk.value = True
self._delay()
value >>= 1
# ACK cycle
self._clk.value = False
self._dio.value = True
self._delay()
self._clk.value = True
self._delay()
self._clk.value = False
def write_raw(self, data):
self._start()
self._write_byte(0x40)
self._stop()
self._start()
self._write_byte(0xC0)
for b in data:
self._write_byte(b)
self._stop()
self._start()
self._write_byte(0x88 | self._brightness)
self._stop()
def show_number(self, number):
number %= 10000
text = "{:04d}".format(number)
self.write_raw([self.SEGMENTS[ch] for ch in text])
def try_touch_button():
last_error = "No supported touch pins found on this board"
for pin_name in TOUCH_PIN_CANDIDATES:
pin = getattr(board, pin_name, None)
if pin is None:
continue
try:
touch = touchio.TouchIn(pin)
touch.threshold = touch.raw_value + TOUCH_THRESHOLD_OFFSET
return Button(touch, value_when_pressed=True), pin_name, None
except Exception as exc:
last_error = "%s: %s" % (pin_name, exc)
return None, None, last_error
def setup_display_vss():
vss = digitalio.DigitalInOut(DISPLAY_VSS_PIN)
vss.direction = digitalio.Direction.OUTPUT
vss.value = True
return vss
def main():
display_vss = setup_display_vss()
brightness = 7
display = TM1637(TM1637_CLK_PIN, TM1637_DIO_PIN, brightness=brightness)
touch_button, touch_pin_name, touch_error = try_touch_button()
print("Display VSS pin %s driven HIGH" % DISPLAY_VSS_PIN)
if touch_button is None:
print("Touch input unavailable: %s" % touch_error)
else:
print("Touch input active on %s" % touch_pin_name)
counter = 0
next_frame = time.monotonic()
display.show_number(counter)
while True:
now = time.monotonic()
if touch_button is not None:
touch_button.update()
if touch_button.rose:
brightness = (brightness + 1) % 8
display.set_brightness(brightness)
display.show_number(counter)
print("Brightness:", brightness)
continue
if now >= next_frame:
frames_elapsed = int((now - next_frame) / FRAME_PERIOD) + 1
counter += frames_elapsed
next_frame += frames_elapsed * FRAME_PERIOD
display.show_number(counter)
else:
time.sleep(0.001)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment