Einstieg in Python, Teil 15
SPI-Bus mit Python nutzen
Unter Python stehen verschiedene Bussysteme bereit, die sich in Geschwindigkeit, Komplexität und Einsatzgebiet unterscheiden. Besonders bei Anwendungen, die schnelle Datenübertragungen oder die Ansteuerung mehrerer Geräte erfordern, spielt eine effiziente Kommunikation eine entscheidende Rolle. Ein häufig eingesetztes Bussystem für solche Zwecke ist der SPI-Bus (Serial Peripheral Interface), der eine schnelle, synchrone Datenübertragung zwischen einem „Master“ bzw. Controller und angeschlossenen Peripheriegeräten ermöglicht. Generell ist der SPI-Bus eines der leistungsfähigsten Bussysteme auf dem Raspberry Pi. Er eignet sich besonders zur Anbindung von Displays, LED-Matrizen, Speichern oder Sensoren, die hohe Datenraten benötigen. Durch die Nutzung separater Leitungen für Datenrichtung und Takt bietet SPI eine stabile und schnelle Kommunikation. In Kombination mit der Programmiersprache Python lässt sich der SPI-Bus auf dem Raspberry Pi einfach konfigurieren und effizient nutzen, wodurch er ideal für Lernprojekte, schnelle Prototypen sowie Embedded- und IoT-Anwendungen ist.
OLED Display am Raspberry Pi
Der SPI-Bus arbeitet synchron über wenige Leitungen und ermöglicht so einen direkten Austausch von Daten zwischen dem Raspberry Pi und angeschlossenen Modulen. Mit Python lässt sich SPI leicht einrichten und nutzen.
Vorteile des SPI-Busses sind
- Hohe Geschwindigkeit:
SPI ist deutlich schneller als I²C, weil die Kommunikation synchron über einen Takt erfolgt und keine Adressierung notwendig ist. - Vollduplex-Kommunikation:
Daten können gleichzeitig in beide Richtungen fließen – also vom Raspberry Pi zum Gerät und zurück. - Einfache Ansteuerung mehrerer Geräte:
Jedes SPI-Gerät hat eine eigene Chip-Select-Leitung, was die Steuerung mehrerer Module erleichtert. - Stabilität bei längeren Kabeln:
SPI arbeitet zuverlässig auch bei höheren Datenraten oder längeren Leitungen, wenn die Hardware korrekt angeschlossen ist. - Flexible Datenbreite:
SPI überträgt Bytes mit beliebigen Bitmustern. Das ist ideal für Displays, LED-Matrizen oder Sensoren.
Bild 1 zeigt, wie zwei SPI-Geräte über vier Leitungen miteinander verbunden werden. Die Kommunikation erfolgt synchron, wobei das steuernde Gerät („Master“ oder Controller) den Takt vorgibt. Über die Leitung SCK (Serial Clock) werden regelmäßige Taktimpulse erzeugt, durch die die Übertragung der einzelnen Bits zeitlich gesteuert wird.

Die Datenübertragung erfolgt parallel in zwei Richtungen. Über die Leitung MOSI (Master Out Slave In) werden Daten vom steuernden Gerät zum angeschlossenen Gerät gesendet. Gleichzeitig können über die Leitung MISO (Master In Slave Out) Daten vom angeschlossenen Gerät zurück übertragen werden. Dadurch wird eine gleichzeitige Übertragung in beide Richtungen ermöglicht.
Zusätzlich wird über die Leitung SS bzw. CS (Slave Select / Chip Select) festgelegt, welches Gerät aktiv ist. Erst wenn diese Leitung aktiviert wird, reagiert das jeweilige Gerät auf die anliegenden Daten.
Im Bild ist zu erkennen, dass bei jedem Taktimpuls ein Bit übertragen wird. Während eines Taktsignals wird jeweils ein Bit gesendet und gleichzeitig ein Bit empfangen. Auf diese Weise wird eine schnelle und effiziente Kommunikation zwischen den Geräten realisiert.
Für den Anschluss eines SPI-Gerätes an den Raspberry Pi werden standardmäßig die folgenden Pins verwendet:
| SPI Chip | Raspberry Pi | Pin |
| VCC | 5 V | (Pin 2 oder 4) |
| GND | GND | |
| DIN | MOSI | (GPIO 10, Pin 19) |
| CS | CE0 | (GPIO 8, Pin 24) |
| CLK | SCLK | (GPIO 11, Pin 23) |
LED-Matrix via SPI am Raspberry Pi
Der MAX7219 ist ein kleiner, aber leistungsstarker LED-Treiber, der die Ansteuerung von 8×8 LED-Matrizen, sieben Segmentanzeigen oder einzelnen LEDs vereinfacht. Er übernimmt das Multiplexing, sodass der Raspberry Pi die LEDs nicht selbst einzeln steuern muss – das spart Leitungen und Rechenaufwand.
Der MAX7219 kommuniziert über den SPI-Bus, wodurch eine schnelle und zuverlässige Datenübertragung zwischen Raspberry Pi und LED-Matrix möglich ist. Über nur fünf Leitungen (VCC, GND, DIN, CLK, optional CS) lassen sich damit problemlos bis zu 64 LEDs direkt ansteuern und so auch Animationen anzeigen oder Text scrollen.
Mit Python lassen sich Zeichen, Muster oder Symbole einfach programmieren. Durch Bibliotheken wie spidev kann der MAX7219 direkt über SPI angesprochen werden, ohne dass zusätzliche Hardware oder komplexe Libraries nötig sind. Der MAX7219 eignet sich daher besonders gut für kreative Hobby-Anwendungen am Raspberry Pi. Der MAX7219 arbeitet mit den folgenden Registern:
| Register | Bedeutung |
| 0x09 | Decode Mode |
| 0x0A | Helligkeit |
| 0x0B | Scan Limit |
| 0x0C | Shutdown |
| 0x0F | Display Test |
| 0x01 – 0x08 | Zeilen (Digit 0–7) |
Standardmäßig ist auf dem Raspberry Pi bereits ein SPI Treiber vorhanden. Andernfalls kann dieser mit
pip3 install spidev
nachinstalliert werden. In Python erfolgt die Initialisierung des SPI Busses dann über
import spidev
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CE0
spi.max_speed_hz = 1000000
spi.mode = 0
Danach können die Register beschrieben werden:
def write(register, data):
spi.xfer2([register, data])
Für den Betrieb einer LED-Matrix sollten die folgenden Register gesetzt werden:
write(0x0C, 0x01) # Shutdown → Normalbetrieb
write(0x0F, 0x00) # Test aus
write(0x0B, 0x07) # 8 Digits
write(0x09, 0x00) # Kein Decode (Pixelmodus)
write(0x0A, 0x08) # Helligkeit (0–15)
Danach kann jede Matrix-Zeile mit einem Byte für die 8 LEDs in einer Display-Zeile binär beschrieben werden z. B. für ein „Herz“-Symbol:
heart = [
"01100110",
"11111111",
"11111111",
"11111111",
"01111110",
"00111100",
"00011000",
"00000000"
]
Das folgende Python-Programm ermöglicht dann die Ansteuerung einer 8×8 Led-Matrix (LED_Matrix_MAX7219_direct):
import spidev, time
# SPI initialisieren
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CE0
spi.max_speed_hz = 1000000
spi.mode = 0
# Funktion zum Schreiben in MAX7219
def write(register, data):
spi.xfer2([register, data])
# Initialisierung MAX7219
def init_max7219():
write(0x0C, 0x01) # Shutdown aus
write(0x0F, 0x00) # Display-Test aus
write(0x0B, 0x07) # Scan-Limit: alle 8 Reihen
write(0x09, 0x00) # Matrixbetrieb
write(0x0A, 0x08) # Helligkeit (0–15)
# Display löschen
def clear():
for i in range(1, 9):
write(i, 0x00)
# Bitmuster (binär)
heart = [
"01100110",
"11111111",
"11111111",
"11111111",
"01111110",
"00111100",
"00011000",
"00000000"
]
# anzeigen
def show_pattern(pattern):
for i, row in enumerate(pattern):
value = int(row, 2) # Binär → Integer
write(i + 1, value)
# Hauptprogramm
try:
init_max7219()
clear()
show_pattern(heart)
except KeyboardInterrupt:
clear()
spi.close()
print("Programm beendet.")
Das Programm erlaubt die direkte Ansteuerung der LED-Matrix über den SPI-Bus. Zu Beginn wird die Bibliothek spidev eingebunden, über die der Zugriff auf die SPI-Schnittstelle des Raspberry Pi ermöglicht wird. Zusätzlich wird das Modul time importiert, um zeitliche Abläufe steuern zu können.
Anschließend wird eine SPI-Verbindung initialisiert. Hierzu wird ein SPI-Objekt erzeugt und mit spi.open(0, 0) der Bus 0 sowie das Gerät CE0 ausgewählt. Die Kommunikationsgeschwindigkeit wird auf 1 MHz festgelegt, und mit spi.mode = 0 wird der SPI-Modus 0 konfiguriert, bei dem Taktpolarität und -phase fest definiert sind.
Zur Vereinfachung der Kommunikation wird eine Funktion write(register, data) definiert. In dieser Funktion werden jeweils zwei Bytes über den SPI-Bus übertragen. Das erste Byte stellt die Registeradresse des MAX7219 dar, während das zweite Byte den zugehörigen Wert enthält. Die Übertragung erfolgt mit spi.xfer2(), wodurch die Daten synchron an das angeschlossene Gerät gesendet werden. Im nächsten Schritt wird der MAX7219 initialisiert. Hierbei werden die oben genannten internen Register des Bausteins gesetzt. Durch das Schreiben in das Shutdown-Register wird der Normalbetrieb aktiviert. Der Display-Testmodus wird deaktiviert, damit die LEDs nicht dauerhaft eingeschaltet sind. Über das Scan-Limit wird festgelegt, dass alle acht Zeilen der Matrix verwendet werden. Der Decode-Modus wird deaktiviert und somit also eine direkte Ansteuerung einzelner LEDs ermöglicht. Schließlich wird die Helligkeit über das Intensitätsregister eingestellt.
Dabei wird mit 0x00 die geringste und mit 0x0F die maximale Helligkeit gewählt.
Anschließend wird eine Funktion zum Löschen des Displays bereitgestellt. Dabei werden alle acht Zeilen nacheinander mit dem Wert Null beschrieben, wodurch sämtliche LEDs ausgeschaltet werden.
Das darzustellende Bild wird als Bitmuster in Form einer Liste von Binärstrings definiert. Jede Zeichenkette repräsentiert dabei eine Zeile der 8×8 LED-Matrix. Innerhalb der Funktion show_pattern werden diese Binärwerte zeilenweise verarbeitet. Jeder Binärstring wird zunächst in eine Ganzzahl umgewandelt und anschließend an das entsprechende Register des MAX7219 übertragen. Auf diese Weise wird das gewünschte Muster auf der LED-Matrix dargestellt.
Im Hauptprogramm wird zunächst die Initialisierung des MAX7219 durchgeführt. Danach wird das Display gelöscht, um einen definierten Ausgangszustand zu gewährleisten. Anschließend wird das zuvor definierte Muster auf der LED-Matrix angezeigt.
In der Funktion show_pattern(pattern) wird ein übergebenes Bitmuster zeilenweise verarbeitet und auf der LED-Matrix ausgegeben. Dazu wird eine Schleife verwendet, in der mit enumerate() sowohl der Index als auch der Inhalt jeder Zeile ermittelt werden. Der Index i entspricht dabei der aktuellen Zeilennummer, während row die zugehörige Binärdarstellung enthält.
Jede Zeile des Musters liegt als Binärstring vor, beispielsweise „01100110“. Dieser String wird mithilfe der Funktion int(row, 2) in eine Ganzzahl umgewandelt. Die Angabe 2 gibt dabei an, dass es sich um eine Binärzahl handelt. Das Ergebnis ist ein Integer-Wert, der direkt über die SPI-Schnittstelle übertragen werden kann.
Anschließend wird mit write(i + 1, value) der berechnete Wert an den MAX7219 gesendet. Dabei entspricht i + 1 der Registeradresse des Bausteins. Die Register 1 bis 8 stehen jeweils für eine Zeile der LED-Matrix. Der Wert bestimmt, welche LEDs in dieser Zeile eingeschaltet werden. Jedes Bit repräsentiert dabei eine einzelne LED: Ein gesetztes Bit (1) schaltet die LED ein, ein nicht gesetztes Bit (0) schaltet sie aus.
Durch das schrittweise Beschreiben aller acht Register wird das vollständige Bild zeilenweise aufgebaut. Da der MAX7219 intern das Multiplexing übernimmt, erscheint das Muster für das menschliche Auge als statisches Bild, obwohl die LEDs tatsächlich schnell nacheinander angesteuert werden.
Abschließend wird die Programmausführung durch eine Ausnahmebehandlung ergänzt. Wird das Programm durch den Benutzer unterbrochen, so wird das Display gelöscht und die SPI-Verbindung ordnungsgemäß geschlossen. Dadurch wird sichergestellt, dass keine undefinierten Zustände auf der Hardware verbleiben.
Bild 2 zeigt die Ausgabe des „Herz“-Icons auf einem 8×8 LED-Matrix-Display.

Ergänzungen, Übungen und Anregungen
- Wie könnte man eine bestimmte LED gezielt einschalten? Lassen sich dabei Koordinaten (x, y) zur Ansteuerung verwenden?
- Stelle verschiedene Smiley-Muster auf der Matrix dar!
- Wie könnte man ein Lauflicht programmieren, bei dem eine LED von links nach rechts wandert?
- Könnte man auch Buchstaben oder Zahlen auf der Matrix darstellen? Lässt sich dabei das Prinzip von Bitmaps nutzen?
- Wäre es möglich, einen Text über die LED-Matrix laufen zu lassen?
- Wie könnte man einfache Animationen auf der Matrix umsetzen? Ist es auch möglich, ein z. B. blinkendes Herz oder bewegte Formen darzustellen?
- Wie könnte man unterschiedliche Helligkeiten einzelner LEDs realisieren?
- Kombiniere mehrere LED-Matrizen zu einer größeren Anzeige (z. B. 8×8 → 32×8 oder mehr)?
Welche Herausforderungen ergeben sich bei der Ansteuerung großer zusammengesetzter Matrizen? - Ist es möglich, Sensordaten auf der LED-Matrix darzustellen? Wie könnte man z. B. die Temperatur eines DS18B20 anzeigen?
Zusammenfassung und Ausblick
In diesem Beitrag wurden die Grundlagen des SPI-Busses erklärt und gezeigt, wie man ihn mit Python praktisch nutzt. Anhand eines konkreten Beispiels – der Ansteuerung einer 8×8-LED-Matrix mit dem MAX7219 – wurde erläutert, wie SPI in Python eingesetzt werden kann. Dazu gehörten die Initialisierung der SPI-Schnittstelle mit der Bibliothek spidev, das Schreiben von Daten in Register sowie die Darstellung einfacher Muster.
Im nächsten Beitrag wird gezeigt, wie man mit Python Daten und Werte ins Internet übertragen kann. Hierzu kommen verschiedene IoT-Anwendungen (Internet of Things) zum Einsatz. In praktischen Anwendungen sollen dabei Messwerte aus Haus, Garten oder Büro in „die Cloud“ gesendet und dort ansprechend dargestellt werden.
Material
- Raspberry Pi mit Netzteil
- Breadboard & Jumper Kabel
- MAX7219-Matrix-Display
Ü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.