Einstieg in Python, Teil 12
Sieben-Segment-Anzeigen mit Python ansteuern
Im Zeitalter virtueller Instrumente und grafischer Benutzeroberflächen könnte man meinen, dass klassische Sieben-Segment-Anzeigen längst überholt sind. Doch gerade im Gerätebau haben sie nach wie vor klare Vorteile: Sie sind kompakt, kostengünstig, robust und lassen sich schnell und zuverlässig ablesen. Damit eignen sich Sieben-Segment-Anzeigen besonders gut für Projekte, bei denen es auf eine stromsparende und unkomplizierte Visualisierung ankommt.
In diesem Beitrag wird gezeigt, wie sich solche Anzeigen mit Python ansteuern lassen. Dabei verbindet sich die klassische Welt der Hardware mit der Flexibilität einer modernen Programmiersprache. So entsteht ein praxisnaher Einstieg in die direkte Ansteuerung von Elektronikbausteinen – ein idealer Lernschritt für alle, die ihre Python-Kenntnisse auf die Hardware-Ebene erweitern möchten.
Ansteuerung der vierstelligen Siebensegment-Anzeige mit dem Raspberry Pi
Neben dem Raspberry Pi selbst sind oftmals nur noch wenige zusätzliche Bauelemente erforderlich, um ein vollständiges Gerät aufzubauen. Wird der Controller beispielsweise mit einer Sieben-Segment-LED-Anzeige kombiniert, so entsteht eine sehr universell nutzbare Plattform, auf der sich viele interessante Projekte realisieren lassen.
Ziffern können mit Sieben-Segment-Anzeigen einfach und effizient dargestellt werden. Derartige Anzeigen bestehen häufig aus acht LED-Elementen (sieben Segmente plus Dezimalpunkt), sie werden aber dennoch als Sieben-Segment-Displays bezeichnet. Die LED-Segmente sind in der Form einer Acht („8“) angeordnet. Durch entsprechende Aktivierung bestimmter Elemente können so die Ziffern von 0 bis 9 in gut lesbarer Form dargestellt werden.
Darüber hinaus lassen sich auch noch einige Großbuchstaben anzeigen (z. B. A, C, E, F etc.). Möchte man weitere Buchstaben anzeigen, müsste man Sechzehn-Segmentanzeigen einsetzen. Diese sind aber vergleichsweise wenig verbreitet und daher teuer. Eine andere Möglichkeit, um Buchstaben und einfache Grafiken anzuzeigen, bieten die sogenannten Punktmatrix-Displays. Diese kommen aber ebenfalls verhältnismäßig wenig zum Einsatz.
Vierstellige Sieben-Segment-Anzeigen
Sieben-Segment-Anzeigen werden in den verschiedensten Formen, Farben und Anschlussbelegungen hergestellt. Ein weit verbreiteter Typ ist in Bild 1 dargestellt. Die einzelnen Segmente werden üblicherweise mit den Buchstaben a bis g bezeichnet. Die anderen Anschlüsse sind entweder die gemeinsame Anode (Common Anode: CA) oder die gemeinsame Kathode (Common Cathode, CC) der Segmente, je nach Displaytyp (s. Bild 2).


Zu den Hauptvorteilen von 7-Segment LED-Anzeigen zählt, dass sie auch aus größerer Entfernung noch gut ablesbar sind. Durch die Lichtemission der LEDs sind die Anzeigen selbst bei Dämmerung und Dunkelheit gut erkennbar. Ein vierstelliges Display mit zusätzlichen Dezimalpunkten ist dabei sehr universell einsetzbar.
Zum einen lassen sich mit einer vierstelligen Anzeige gut Stunden und Minuten für eine Uhr oder Minuten und Sekunden für einen Timer darstellen. Andererseits ist auch eine Anzeige mit zwei Vor- und zwei Nachkommastellen realisierbar – so können Spannungen oder Stromstärken gut angezeigt werden. Für eine Temperaturanzeige in Grad Celsius kann man sogar einen einfachen Trick anwenden um ein °-Zeichen darzustellen
Ein übliches 4×7-Segementdisplay enthält 32 LED-Elemente, 4 x 7 = 28 LEDs sind für die Zifferndarstellung erforderlich. Dazu kommen dann noch beispielsweise 4 Dezimalpunkte.
Meist sind jedoch entweder alle Anoden oder alle Kathoden jeweils einer Ziffer zusammengeführt. Darüber hinaus werden und auch alle Anoden bzw. Kathoden der jeweiligen Segmente verbunden. Ein solches Display weist dann nur 12 Pins auf:
- Sieben Pins für die Kathoden der Displaysegmente a, b, c, d, e, f und g
- Ein Pin für die Dezimalpunkte (DP)
- Vier Anoden für die Einer- (E), Zehner- (Z), Hunderter- (H) und Tausender-(T) Stelle
Neben der Einsparung von Pins hat die gemeinsame Herausführung von Anschlüssen noch den Vorteil, dass die betreffenden Anzeigen sehr leicht im sogenannten Zeitmultiplex betrieben werden können.
Anschluss des Displays an den Raspberry Pi
Der Rasberry Pi verfügt über genügend IO-Pins, um eine 4×7-Segmentanzeige direkt anzusteuern. In der folgenden Tabelle sind die erforderlichen Verbindungen angegeben.
| Pin-Display | Funktion | Verbinden am RasPi mit Pin |
| a | a | 18 |
| b | b | 14 |
| c | c | 25 |
| d | d | 09 |
| e | e | 11 |
| f | f | 15 |
| g | g | 24 |
| DP | Dezimalpunkt | 10 |
| Th | Tausenderstelle | 22 |
| H | Hunderterstelle | 07 |
| T | Zehnerstelle | 08 |
| O | Einerstelle | 23 |
Bild 3 zeigt den zugehörigen Aufbau. Um eine möglichst übersichtliche Verdrahtung zu ermöglichen, wurde der Raspberry Pi um 180° gedreht und die Darstellung entsprechend angepasst. Auf diese Weise können die Jumper-Kabel auf kürzesten Wegen mit der Anzeige verbunden werden. Zudem wird die Verdrahtung auf dem Breadboard auf diese Weise besonders einfach.

Die folgenden beiden Fotos zeigen den Aufbau auf dem Breadboard zunächst ohne (Bild 4) und dann mit eingesetztem Displaymodul (Bild 5).


Als Vorwiderstände kommen 220-Ohm-Werte mit der Farbringkombination rot-rot-braun-gold zum Einsatz.
Ansteuerung der 4×7 –Segment LED-Anzeige
Für die Ansteuerung einer 4×7-Segmentanzeige kann das folgende Python-Programm verwendet werden:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
# GPIO ports for display pins
# a b c d e f g DP
segments = (18,14,25,9,11,15,24,10)
for segment in segments:
GPIO.setup(segment, GPIO.OUT)
GPIO.output(segment, 1)
# GPIO ports for digits pins
# Th H T O
digits = (22, 7, 8, 23)
for digit in digits:
GPIO.setup(digit, GPIO.OUT)
GPIO.output(digit, 0)
num ={ ' ':(1,1,1,1,1,1,1), '0':(0,0,0,0,0,0,1), '1':(1,0,0,1,1,1,1),
'2':(0,0,1,0,0,1,0), '3':(0,0,0,0,1,1,0), '4':(1,0,0,1,1,0,0),
'5':(0,1,0,0,1,0,0), '6':(0,1,0,0,0,0,0), '7':(0,0,0,1,1,1,1),
'8':(0,0,0,0,0,0,0), '9':(0,0,0,0,1,0,0)
}
try:
while True:
n = 4711
s = str(n)
for digit in range(4):
for loop in range(0,7):
GPIO.output(segments[loop], num[s[digit]][loop])
GPIO.output(digits[digit], 1)
time.sleep(0.001)
GPIO.output(digits[digit], 0)
finally:
GPIO.cleanup()
Zunächst werden hier den einzelnen LED-Segmenten die zugehörigen Ports zugewiesen (siehe auch Tabelle):
# GPIO ports for display pins
# a b c d e f g DP
segments = (18,14,25,9,11,15,24,10)
Dann erfolgt die Zuweisung der Digit-Anoden-Pins:
# GPIO ports for digits pins
# Th H T O
digits = (22, 7, 8, 23)
In der Initialisierungsroutine werden diese aktiven Ports entsprechend als Ausgänge deklariert:
for segment in segments:
GPIO.setup(segment, GPIO.OUT)
GPIO.output(segment, 1)
Mit den Pins für die Anoden wird entsprechend ebenso verfahren.
Dann folgt eine Tabelle, die den einzelnen Ziffern die korrekten Leuchtsegmente zuordnet. Die folgende Tabelle zeigt ein Beispiel für die Ziffer „0“.
| Display-Pin | a | b | c | d | e | f | g |
| Zustand z. B. für „0“ | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
Da ein Common-Anode-Display verwendet wird, muss die Kathode eines Segments auf Null-Potential gelegt werden, wenn es leuchten soll. Daraus ergibt sich die Codierung für die Darstellung der „Null“: Alle Segmente bis auf das g-Segment müssen leuchten, d. h. a bis f liegen auf Null-Potential, g wird auf HIGH geschaltet.
Damit ergibt sich das Binärmuster für die „Null“ zu:
a b c d e f g
0 0 0 0 0 0 1
Entsprechend könne alle restlichen Ziffern codiert werden. Die Tabelle zeig das Ergebnis:
| Ziffer | a | b | c | d | e | f | g |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 |
| 2 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |
| 3 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
| 4 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
| 5 | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
| 6 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 7 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
| 8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 9 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
Daraus ergibt sich die Zuordnungstabelle im Programm:
num ={ '0':(0,0,0,0,0,0,1), '1':(1,0,0,1,1,1,1),
'2':(0,0,1,0,0,1,0), '3':(0,0,0,0,1,1,0),
'4':(1,0,0,1,1,0,0), '5':(0,1,0,0,1,0,0),
'6':(0,1,0,0,0,0,0), '7':(0,0,0,1,1,1,1),
'8':(0,0,0,0,0,0,0), '9':(0,0,0,0,1,0,0)
}
Nun wird eine Beispielzahl festgelegt:
n = 4711
und in einen String umgewandelt:
s = str(n)
Anschließend werden die Digits über eine for-Schleife angesteuert. Innerhalb dieser Schleife sorgt eine zweite Schleife für die Ansteuerung der einzelnen Displaysegmente a bis g entsprechend der oben definierten Tabelle.
Nach dem Starten des Programms sollte somit die Zahl „1234“ im Display erscheinen (siehe Bild 6).
Bei genauer Betrachtung wird man feststellen, dass die Anzeige nicht vollkommen flimmerfrei ist. Dies ergibt sich aus der Tatsache, dass der Raspberry Pi im Gegensatz z. B. zum EPS32 oder Arduino nicht „echtzeitfähig“ ist.

Schnelligkeit und Echtzeit
Die Ansteuerung der Siebensegment-Anzeige zeigt ein wichtiges Problem in der Datenverarbeitung und insbesondere in der Auswertung von Sensorsignalen auf. Obwohl der Raspberry Pi mit einer Taktfrequenz von mindestens 700 MHz arbeitet, ist er mit einer flimmerfreien Zifferndarstellung bereits überfordert. Ein Arduino dagegen arbeitet mit lediglich 16 MHz, dennoch kann er eine Sieben-Segment-Anzeige problemlos flimmerfrei ansteuern.
Die Ursache liegt darin, dass der Arduino kein aufwendiges Betriebssystem steuern muss. In seinem Speicher befindet sich immer genau ein Programm, das im Wesentlichen sequenziell abgearbeitet wird. Das komplexe Linux-System des Raspberry Pi mit dem Kernel, den GNU-Tools, der Grafik-, Maus und Tastatursteuerung und verschiedenen „Dämons“ im Hintergrund wird immer wieder von untergeordneten Aufgaben unterbrochen.
Beim Arduino kann lediglich eine überschaubare Anzahl von Interrupts zu einer temporären Programmunterbrechung führen. Bei sorgfältiger Programmierung kann auch diese Störquelle praktisch vollständig eliminiert werden.
Deshalb kann man beim Arduino eine festgelegte maximale Antwortzeit für eine bestimmte Programmaufgabe angeben. Diese Möglichkeit wird als „Echtzeitfähigkeit“ bezeichnet. Dies ist insbesondere im Bereich von Steuer- und Regelungsaufgaben von größter Bedeutung. In der Fahrzeugsteuerung kommt es beispielsweise darauf an, dass das Steuersystem innerhalb einer Maximalzeit auf ein Ereignis reagiert. Deshalb können hier keine Rechnersysteme mit komplexen Betriebssystemen eingesetzt werden, da in diesem Falle eine feste Reaktionszeit niemals garantiert werden kann, auch wenn der Prozessor selbst mit hoher Geschwindigkeit arbeitet.
Digitaluhr mit vierstelliger Anzeige
In einer ersten praktischen Anwendung soll das Display die aktuelle Uhrzeit anzeigen. Dazu muss das Programm aus dem letzten Abschnitt nur minimal erweitert werden. Mit den beiden Programmzeilen
n = time.ctime()[11:13]+time.ctime()[14:16]
s = str(n).rjust(4)
wird aus der time-Bibliothek die aktuelle Urzeit extrahiert und im Format hh.mm dargestellt. Zusätzlich wird im Programm der mittlere Dezimalpunkt im Sekundentakt aktiviert, um Stunden und Minuten zu trennen. Damit sieht das Programm zur Digitaluhr wie folgt aus:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
import time
# GPIO ports for the 7seg pins
# a b c d e f g d DP
segments = (11,7,15,17,22,8,10,25,18)
for segment in segments:
GPIO.setup(segment, GPIO.OUT)
GPIO.output(segment, 1)
# GPIO ports for the digit 0-3 pins
digits = (25, 24, 23, 14)
for digit in digits:
GPIO.setup(digit, GPIO.OUT)
GPIO.output(digit, 0)
num ={
' ':(1,1,1,1,1,1,1), '0':(0,0,0,0,0,0,1), '1':(1,0,0,1,1,1,1),
'2':(0,0,1,0,0,1,0), '3':(0,0,0,0,1,1,0), '4':(1,0,0,1,1,0,0),
'5':(0,1,0,0,1,0,0), '6':(0,1,0,0,0,0,0), '7':(0,0,0,1,1,1,1),
'8':(0,0,0,0,0,0,0), '9':(0,0,0,0,1,0,0)}
try:
while True:
n = time.ctime()[11:13]+time.ctime()[14:16]
s = str(n).rjust(4)
for digit in range(4):
for loop in range(0,7):
GPIO.output(segments[loop], num[s[digit]][loop])
if (int(time.ctime()[18:19])%2 == 0) and (digit == 1):
GPIO.output(18, 0)
else:
GPIO.output(18, 1)
GPIO.output(digits[digit], 1)
time.sleep(0.001)
GPIO.output(digits[digit], 0)
finally:
GPIO.cleanup()
Hierbei ist zu beachten, dass der Raspberry Pi die Uhrzeit automatisch aus dem Internet bezieht. Besteht keine Verbindung zum Internet, kann die aktuelle Uhrzeit über
sudo date „1224201516“
eingegeben werden. Uhrzeit und Datum werden dabei im Format
MMTThhmmJJ
angegeben (M=Monat, T=Tag, h=Stunde,m=Minute, J=Jahr). Die Einstellung wird anschließend mit der Ausgabe des neuen Datums und Uhrzeit quittiert:
Sa 24. Dez 20:15:00 CET 2016
Allerdings geht diese Einstellung bei jedem Neustart verloren. Abhilfe könnte hier eine Real-Time-Clock schaffen, die als Bausatz passend zum Raspberry Pi erhältlich ist. Bild 7 zeigt die Raspberry Pi-Digitaluhr in Aktion.

Sieben-Segment-Anzeige mit Treiber
Die Ansteuerung von Sieben-Segment-Anzeige kann wesentlich vereinfacht werden, wenn Treiber-ICs wie der TM1637 (Bild 8) zum Einsatz kommen. Dieser Baustein reduziert den Verkabelungsaufwand erheblich, da er die komplette Multiplex-Steuerung übernimmt und lediglich zwei Datenleitungen (CLK und DIO) benötigt.
In Kombination mit dem Raspberry Pi lassen sich damit schnell und zuverlässig digitale Anzeigen aufbauen – sei es für Messwerte, Uhrenprojekte oder kleine Embedded-Anwendungen. In diesem Abschnitt wird gezeigt, wie eine Sieben-Segment-Anzeige mit dem TM1637-Treiber am Raspberry Pi angeschlossen und mit Python angesteuert wird.

Für ein Sieben-Segment-Modul mit TM1637-Treiber sind lediglich die folgenden Anschlüsse erforderlich:
- VCC → 3,3 V (oder 5 V, je nach Display-Modul)
- GND → GND
- CLK → GPIO 23
- DIO → GPIO 24
Vor der Verwendung des Moduls ist die erforderliche Bibliothek zuvor auf dem Raspberry Pi zu installieren:
pip install tm1637
Danach kann das folgende Programm gestartet werden (SevenSegClock_TM1637.py). Durch die Verwendung der Bibliothek fällt das Programm sehr kompakt aus, da die Festlegung der LED-Pins etc. bereits in der Bibliothek erfolgt. Man kann sich daher direkt auf die eigentliche Anwendung konzentrieren. Zudem kann die Displayhelligkeit in diesem Fall sehr einfach eingestellt werden, da dafür eine eigene Routine implementiert wurde.
import tm1637
import time
# GPIO-Pins (BCM-Nummern)
CLK = 23 # Clock-Pin
DIO = 24 # Data-Pin
# Display-Objekt anlegen
display = tm1637.TM1637(clk=CLK, dio=DIO)
# Helligkeit einstellen (0=aus, 7=max)
display.brightness(3)
try:
while True:
now = time.strftime("%H%M")
display.show(now)
# Blinkender Doppelpunkt
display.show_doublepoint(True)
time.sleep(1)
display.show_doublepoint(False)
time.sleep(1)
except KeyboardInterrupt:
display.show(" ") # Display leeren
print("\nProgramm beendet")
Das Programm zeigt aktuelle Uhrzeit im Format HH:MM mit einem blinkenden Doppelpunkt an. Die Routine
display = tm1637.TM1637(clk=CLK, dio=DIO)
erstellt ein TM1637-Objekt, das die Kommunikation mit dem 7-Segment-Display über die angegebenen GPIO-Pins (CLK und DIO) steuert. Details: Die tm1637.TM1637-Klasse initialisiert die Verbindung zum Display. Der TM1637-Chip verwendet ein proprietäres Protokoll, das über die beiden Pins (CLK und DIO) kommuniziert. Die Bibliothek kümmert sich um die Low-Level-Details dieser Kommunikation.
Die Funktion
display.brightness(3)
legt die Helligkeit des Displays fest. Der Wert 3 liegt im mittleren Bereich, welcher von 0 (aus) bis 7 (maximale Helligkeit) reicht. Die Helligkeit wird durch Pulsweitenmodulation (PWM) im TM1637-Chip gesteuert.
Die Uhrzeit-Anzeige mit blinkendem Doppelpunkt wird über die Hauptschleife gesteuert. Dort wird die aktuelle Uhrzeit im Format HH.MM (Stunden und Minuten ohne Doppelpunkt) angezeigt, wobei der Doppelpunkt zwischen den Stunden und Minuten abwechselnd ein- und ausgeschaltet wird, um einen blinkenden Effekt zu erzeugen. Die Uhrzeit wird jede Sekunde aktualisiert, indem
time.strftime
die aktuelle Systemzeit abruft. Der blinkende Doppelpunkt (1 Sekunde an, 1 Sekunde aus) simuliert somit eine typische digitale Uhr. Die Try/Except Konstruktion fängt die Unterbrechung des Programms durch den Benutzer ab (z. B. durch Drücken von Strg+C) und sorgt für ein sauberes Programmende. Bild 9 zeigt einen Prototyp-Aufbau der Digitaluhr.

Wenn man das Display zusammen mit dem Raspberry Pi in ein passendes Gehäuse einbaut, entsteht eine alltagstaugliche und formschöne Digitaluhr (siehe Bild 10).

Bild 11 zeigt zum Abschluss eine weitere Anwendung der Sieben-Segment-Anzeige. Hier dient sie als Display für einen selbstgebauten Neigungsmesser. Neben dem Display und dem Raspberry Pi ist hierfür nur noch ein Beschleunigungsmessmodul erforderlich. Details dazu folgen in einem späteren Artikel im ELVjournal online.

Ergänzungen, Übungen und Anregungen
Anzeige allgemein:
- Wie könnte man beim direkten Anschluss des Displays an den Raspberry Pi die Helligkeit ändern (Stichwort: PWM)?
- Wie kann man mehrere Digits an den Raspberry Pi anschließen, um z. B. Stunden, Minuten und Sekunden (hh:mm:ss) sowie Tag, Monat und Jahr (TT.MM.JJJJ) anzuzeigen?
Digitaluhr:
- Wie könnte die Uhrzeitanzeige für Sekunden erweitert werden?
- Die Helligkeit könnte dynamisch basierend auf der Umgebungsbeleuchtung angepasst werden (z. B. mit einem Lichtsensor) – wie müsste das Programm dazu aussehen?
- Fehlerbehandlung: Wie kann man zusätzliche try-except-Blöcke hinzufügen, um Verbindungsfehler oder Hardwareprobleme abzufangen?
- Wie könnte man Taster hinzufügen, um zwischen verschiedenen Anzeigemodi (z. B. Zähler, Uhrzeit, Datum) zu wechseln, oder die Uhr zu stellen?
Zusammenfassung und Ausblick
In diesem Artikel wurde die Programmierung von Sieben-Segment-Anzeigen mit Python ausführlich dargestellt. Praktische Anwendungen reichten hierbei von einfachen Zifferndarstellungen bis hin zu kompletten, praxistauglichen Digitaluhren.
Im nächsten Beitrag wird es um weitere alphanumerische Displays gehen. Diese können neben Ziffern und einfachen Zeichen auch komplette Zahlen und sogar Grafiken darstellen. Mit den passenden Python-Bibliotheken wird die Programmierung von LCD-Displays oder modernen OLEDs zum Kinderspiel. Dabei sollen neben den Grundlagen auch wieder praktische Anwendungen wie Messwertausgaben und Funktionsgrafiken zum Einsatz kommen.
Material
- Raspberry Pi mit Netzteil
- Breadboard und Jumper-Kabel
- Sieben-Segment-Anzeigen
- Anzeigemodul mit TM1637-Teiber
- Kleinteile aus dem Set PAD-PRO-EXSB
Über den Autor
Dr. Günter Spanner ist als Autor zu den Themen Elektronik, Sensortechnik und Mikrocontroller einem weiten Fachpublikum bekannt. Schwerpunkt seiner hauptberuflichen Tätigkeit für verschiedene Großkonzerne wie Siemens und ABB ist die Projektleitung im Bereich Entwicklung und Technologie-Management. Der Dozent für Physik und Elektrotechnik hat zudem zahlreiche Fachartikel und Bücher veröffentlicht sowie Kurse und Lernpakete erstellt.