These types of LED displays are quite popular and can be used to add a visual output to a Raspberry Pi automation project. In this post, I will be talking about the KS0445 4-digit LED Display Module from keyestudio. While keyestudio kits are primarily designed to work with Arduino, they are perfectly suitable for Pi applications.

In theory, any LED 4-digit Display using a TM1637 chip can be used with the Python code that will be shown.
The first step is to install the TM1637 Python package containing the class that will simplify controlling the LED display quite a bit. As a side note, I strongly encourage installing VS Code on the Pi, so you can code like a pro.
Open a terminal window in VS Code and type:
pip install raspberrypi-tm1637
Once the installation is complete, you can wire the display as shown below and try the Python code that follows. It illustrates how straightforward it is to use some of the methods of the TM1637 class that come in the package.

# Importing modules and classes
import tm1637
import time
import numpy as np
from datetime import datetime
from gpiozero import CPUTemperature
# Creating 4-digit 7-segment display object
tm = tm1637.TM1637(clk=18, dio=17) # Using GPIO pins 18 and 17
clear = [0, 0, 0, 0] # Defining values used to clear the display
# Displaying a rolling string
tm.write(clear)
time.sleep(1)
s = 'This is pretty cool'
tm.scroll(s, delay=250)
time.sleep(2)
# Displaying CPU temperautre
tm.write(clear)
time.sleep(1)
cpu = CPUTemperature()
tm.temperature(int(np.round(cpu.temperature)))
time.sleep(2)
# Displaying current time
tm.write(clear)
time.sleep(1)
now = datetime.now()
hh = int(datetime.strftime(now,'%H'))
mm = int(datetime.strftime(now,'%M'))
tm.numbers(hh, mm, colon=True)
time.sleep(2)
tm.write(clear)
Raspberry Pi Stopwatch with LED Display
That was pretty much it for the LED display. However, let’s go for an Easter egg, where we implement a stopwatch that can be controlled by keyboard inputs. The main feature here is the use of the Python pynput package, which seamlessly enables non-blocking keyboard inputs. To get started, in a terminal window in VS Code, type:
pip install pynput
To make things more interesting, I created the class StopWatch with the following highlights:
- First and foremost, could the entire code be written using a function (or a few functions) or even as a simple script? Yes, it could. However, using a class makes for code that is much more modular and expandable, and that can easily be integrated into other code.
- At the center of the the StopWatch class is the execution loop method. For conciseness and readability, all other methods (with very descriptive names) are called from within this execution loop.
- The beauty of using a class and therefore its methods is that the latter can be called from different points in the code, as it is the case of the
start_watch()
method, for example. - Finally, as the code is written as a class vs. functions, all the variables can be defined as class attributes. That really reduces complexity with input arguments, if functions were to be used instead.
# Importing modules and classes
import time
import tm1637
import numpy as np
from pynput import keyboard
class StopWatch:
"""
The class to represent a digital stopwatch.
**StopWatch** runs on a Raspberry PI and uses a 4-digit 7-segment display
with a TM1637 control chip.
The following keyboard keys are used:
* ``'s'`` to start/stop the timer.
* ``'r'`` to reset the timer.
* ``'q'`` to quit the application.
"""
def __init__(self):
"""
Class constructor.
"""
# Creating 4-digit 7-segment display object
self.tm = tm1637.TM1637(clk=18, dio=17) # Using GPIO pins 18 and 17
self.tm.show('00 0') # Initializing stopwatch display
# Creating keyboard event listener object
self.myevent = keyboard.Events()
self.myevent.start()
# Defining time control variables (in seconds)
self.treset = 60 # Time at which timer resets
self.ts = 0.02 # Execution loop time step
self.tdisp = 0.1 # Display update period
self.tstart = 0 # Start time
self.tstop = 0 # Stop time
self.tcurr = 0 # Current time
self.tprev = 0 # Previous time
# Defining execution flow control flags
self.run = False # Timer run flag
self.quit = False # Application quit flag
# Running execution loop
self.runExecutionLoop()
def runExecutionLoop(self):
"""
Run the execution loop for the stopwatch.
"""
# Running until quit request is received
while not self.quit:
# Pausing to make CPU life easier
time.sleep(self.ts)
# Updating current time value
self.update_time()
# Handling keyboard events
self.handle_event()
# Checking if automatic reset time was reached
if self.tcurr >= self.treset:
self.stop_watch()
self.reset_watch()
self.start_watch()
# Updating digital display
self.update_display()
# Stroing previous time step
self.tprev = self.tcurr
def handle_event(self):
"""
Handle non-blocking keyboard inputs that control stopwatch.
"""
# Getting keyboard event
event = self.myevent.get(0.0)
if event is not None:
# Checking for timer start/stop
if event.key == keyboard.KeyCode.from_char('s'):
if type(event) == keyboard.Events.Release:
if not self.run:
self.run = True
self.start_watch()
elif self.run:
self.run = False
self.stop_watch()
# Checking for timer reset
elif event.key == keyboard.KeyCode.from_char('r'):
if type(event) == keyboard.Events.Release:
if not self.run:
self.reset_watch()
elif self.run:
print('Stop watch before resetting.')
# Checking for application quit
elif event.key == keyboard.KeyCode.from_char('q'):
self.quit = True
self.tm.write([0, 0, 0, 0])
print('Good bye.')
def start_watch(self):
""" Update start time. """
self.tstart = time.perf_counter()
def stop_watch(self):
""" Update stop time. """
self.tstop = self.tcurr
def reset_watch(self):
""" Reset timer. """
self.tstop = 0
self.tm.show('00 0')
def update_time(self):
""" Update timer value. """
if self.run:
self.tcurr = time.perf_counter() - self.tstart + self.tstop
def update_display(self):
""" Update digital display every 'tdisp' seconds. """
if (np.floor(self.tcurr/self.tdisp) - np.floor(self.tprev/self.tdisp)) == 1:
# Creating timer display string parts (seconds, tenths of a second)
if int(self.tcurr) < 10:
tsec = '0' + str(int(self.tcurr))
else:
tsec = str(int(self.tcurr))
ttenth = str(int(np.round(10*(self.tcurr-int(self.tcurr)))))
# Showing string on digital display
self.tm.show(tsec + ' ' + ttenth)
# Running instance of StopWatch class
if __name__ == "__main__":
StopWatch()
One thought on “7-Segment LED Display with Raspberry Pi”