In diesem Beitrag hab ich schonmal ganz allgemein über den Raspberry Pi geschrieben, und in diesem Beitrag über ein paar allgemeine Grundlagen zur GPIO-Schnittstelle des Raspberry Pi. Dieses mal soll es nun etwas konkreter werden: Im folgenden Beitrag zeige ich anhand von Python-Beispiel-Scripten, wie man Ausgänge schalten und Eingänge lesen kann.
Inhalt
Vorbereitung
Neuere Raspbian-Images liefern eigentlich alles mit, was man benötigt, um mit der Steuerung der GPIO loslegen zu können. Sollte in Eurem Image doch noch etwas fehlen (leicht an der daraus resultierenden Fehlermeldung beim Testen zu erkennen), setzt Ihr einfach folgenden Befehl ab:
$ sudo apt-get update && sudo apt-get install python-dev && sudo apt-get install python-rpi.gpio
Vorbemerkungen zu Python
Zum Programmieren in Python eignet sich so gut wie jeder normale Texteditor. Etwas leichter wird es, wenn dieser Editor Syntax-Highlighting für Python unterstützt, sodass z.B. Befehle automatisch in einer anderen Farbe dargestellt werden, als Kommentare. Außerdem sollte der Editor das Zeilenumbruch-Zeichen des Zielsystems (hier Linux) unterstützen.
Auf meinem Mac verwende ich die kostenfreie App TextWrangler aus dem Mac App Store, die meine Ansprüche vollständig erfüllt. Für Windows fällt mir da das ebenfalls kostenfreie Notepad++ ein.
In meinen Skripten sehen die ersten zwei Zeilen eigentlich immer so aus:
#!/usr/bin/env python #coding: utf8
Die erste Zeile ist der Shebang. Er hilft dem System, den entsprechenden Code korrekt zu interpretieren und auszuführen. Zeile zwei legt den Zeichensatz fest, in dem die Scripte geschrieben sind. Ich wähle hier UTF-8, um mit Umlauten (ä, ö, ü, ß) arbeiten zu können. Das ist auch nötig, wenn man Umlaute nur in den Kommentaren verwendet.
Grundlegendes zum Umgang mit den GPIO
Das eigentliche Script beginnt mit dem Importieren der Module time und RPi.GPIO. time bringt etliches an Funktionen, die mit Zeit zutun haben, mit (siehe Doku). RPi.GPIO übernimmt für uns das Handling der GPIO (siehe Doku).
import time import RPi.GPIO as GPIO
Auf Zeile 8 legen wir die Zählweise der Pins fest. Ich bevorzuge BOARD, denn damit kann ich die Pins einfach körperlich abzählen (bzw. einen Blick auf die Grafiken in diesem Beitrag werfen) und die Nummern entsprechend verwenden.
# Zählweise der Pins festlegen GPIO.setmode(GPIO.BOARD)
Alternativ zu dieser Zählweise kann man auch BCM verwenden. Hier wird nachfolgend dann nicht mehr die Pin-Nummer, sondern die GPIO-Nummer angegeben.
Ausgang schalten
Nachfolgend der gesamte Code, der unseren Ausgang schalten soll. Ich verwende für dieses Script den 22. Pin (GPIO 25) und konfiguriere diesen auf Zeile 11 als Ausgang.
Im eigentlichen Programmablauf passiert folgendes: Innerhalb einer Schleife wird der Ausgang eingeschaltet, dann wird eine Zeit von 2 Sekunden abgewartet, anschließend der Ausgang wieder ausgeschaltet, wieder 2 Sekunden gewartet und der Schleifenzähler, der auf Zeile 14 auf 3 gesetzt wurde, um einen Zähler verringert. Wenn der Zähler nach dem Durchlauf noch größer 0 ist, beginnt das wieder von vorn.
#!/usr/bin/env python
#coding: utf8
import time
import RPi.GPIO as GPIO
# Zählweise der Pins festlegen
GPIO.setmode(GPIO.BOARD)
# Pin 22 (GPIO 25) als Ausgang festlegen
GPIO.setup(22, GPIO.OUT)
# Ausgang 3 mal ein-/ausschalten
i = 3
while i > 0:
# Ausgang einschalten
GPIO.output(22, GPIO.HIGH)
# zwei Sekunden warten
time.sleep(2)
# Ausgang ausschalten
GPIO.output(22, GPIO.LOW)
# zwei Sekunden warten
time.sleep(2)
# Zähler für die Schleife herunter zählen
i = i - 1
# Ausgänge wieder freigeben
GPIO.cleanup()
Das Script könnt Ihr einfach kopieren und beispielsweise als gpio_ausgang.py abspeichern. Dann nur noch ausführbar machen:
$ chmod +x gpio_ausgang.py
und anschließend starten:
$ sudo ./gpio_ausgang.py
Um die Funktion zu testen könnt Ihr ein beliebiges Bauteil anschließen, das sich in irgendeiner Form einschalten lässt – Vielleicht eine LED. Ich verwende ein 2-Kanal-Relais-Modul, das ich mit 3 Steckbrücken angeschlossen habe.
Die Relais sind jedoch low-aktiv – heißt: wenn man den Ausgang des Raspberry Pi ausschaltet, zieht das Relais an. Schaut man sich das Schaltbild des Relais-Moduls an, wird auch schnell klar, warum das so ist. Das muss uns hier aber nicht weiter interessieren. Es reicht erstmal, wenn wir wissen, dass es so ist. Angeschlossen wird es in meinem Beispiel so:
Die Spannungsversorgung erfolgt mit 5V und GND, Relais 1 auf dem Modul wird über den Anschluss IN1 an den GPIO25 vom Raspberry Pi angeschlossen.
Eingang lesen
Der Code zum lesen eines Einganges sieht vom Grunde her nicht viel anders aus. Dieses mal verwende ich den GPIO24 (Pin 18), der auf Zeile 10 als Eingang konfiguriert wird. Außerdem wird per Software ein Pull-Down-Widerstand hinzugeschaltet. Dieser bewirkt, dass der Eingang stets ein definiertes Signal liefert. Lässt man ihn weg und schließt einen Draht an den Pin 18 an, dessen anderes Ende frei in der Luft hängt, kann es durchaus passieren, dass der Eingang bereits Signale „empfängt“ und somit einen undefinierten Zustand einnimmt.
In einer Dauerschleife wird der Eingang abgefragt. Solange er HIGH ist, erfolgt eine Ausgabe im Terminal. Der Raspberry Pi ist ziemlich schnell und man kann kaum so schnell gucken, wie das Terminal-Fenster vollgeschrieben wird. Um das besser darzustellen hab ich noch einen Schleifenzähler eingebaut (Zeile 13), der bei jeder Terminalausgabe mit ausgegeben wird (Zeile 20) und am Ende eines Durchlaufs hochgezählt wird (Zeile 22).
#!/usr/bin/env python
#coding: utf8
import RPi.GPIO as GPIO
# Zählweise der Pins festlegen
GPIO.setmode(GPIO.BOARD)
# Pin 18 (GPIO 24) als Eingang festlegen
GPIO.setup(18, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
# Schleifenzähler
i = 0
# Endlosschleife
while 1:
# Eingang lesen
if GPIO.input(18) == GPIO.HIGH:
# Wenn Eingang HIGH ist, Ausgabe im Terminal erzeugen
print "Eingang HIGH " + str(i)
# Schleifenzähler erhöhen
i = i + 1
Das Script könnt Ihr einfach kopieren und beispielsweise als gpio_eingang.py abspeichern. Dann nur noch ausführbar machen:
$ chmod +x gpio_eingang.py
und anschließend starten:
$ sudo ./gpio_eingang.py
Das Script läuft solange, bis es mit der Tastenkombination Strg+C abgebrochen wird.
Testen könnt Ihr das, indem Ihr einfach 3,3V am Pin 18 anlegt. Dazu stellt Ihr einfach mit einer Steckbrücke eine Verbindung zu Pin 1 her.
Angeschlossen wird das in meinem Beispiel so:
Flanken eines Eingangs abfragen (Interrupt)
Das zuvor gezeigte Beispiel, einen Eingang dauerhaft in einer Schleife abzufragen, ist natürlich nicht sehr elegant. Daher modifizieren wir den Code dahingehend, dass ein Ereignis ausgelöst wird, wenn der Eingang sich ändert.
Steigende Flanke
Auf den Zeile 26 und 27 wird das Ereignis deklariert. In diesem Fall wird Pin 18 überwacht auf die steigende Flanke (GPIO.RISING) überwacht. Mit callback wird definiert, was dann passieren soll. In diesem Beispiel wird die Funktion doIfHigh aufgerufen. Da es nicht möglich ist, einer callback-Funktion Parameter zu übergeben, schreiben wir den gewünschten GPIO in eine Variable (channel), die wir in der Zielfunktion auslesen und entsprechend darauf reagieren können. bouncetime gibt an, in welchem Zeitintervall der Eingang abgefragt wird und verhindert, dass das Ereignis bei prellenden Schaltern oder meiner Steckbrücke mehrfach ausgelöst wird. Wikipedia hält hierzu einen interessanten Artikel bereit.
Auf Zeile 17 wird die Funktion mit den Befehlen definiert, die bei einer positiven Flanke abgearbeitet werden sollen.
#!/usr/bin/env python
#coding: utf8
import time
import RPi.GPIO as GPIO
# Zählweise der Pins festlegen
GPIO.setmode(GPIO.BOARD)
# Pin 18 (GPIO 24) als Eingang festlegen
GPIO.setup(18, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
# Schleifenzähler
i = 0
# Ereignis-Funktion für Eingang HIGH
def doIfHigh(channel):
# Zugriff auf Variable i ermöglichen
global i
# Wenn Eingang HIGH ist, Ausgabe im Terminal erzeugen
print "Eingang " + str(channel) + " HIGH " + str(i)
# Schleifenzähler erhöhen
i = i + 1
# Ereignis deklarieren
channel = 18
GPIO.add_event_detect(channel, GPIO.RISING, callback = doIfHigh, bouncetime = 200)
# Eigentlicher Programmablauf
while 1:
time.sleep(0.1)
Fallende Flanke
Die fallende Flanke wird mit GPIO.FALLING abgefragt, funktioniert sonst aber genau wie die steigende.
GPIO.add_event_detect(channel, GPIO.FALLING, callback = doIfHigh, bouncetime = 200)
Steigende und fallende Flanke
Um beide Flanken abzufragen verwendet man GPIO.BOTH.
GPIO.add_event_detect(channel, GPIO.BOTH, callback = doIfHigh, bouncetime = 200)
Hierzu passen wir das Beispiel nochmal ein wenig an, damit bei fallender Flanke ein anderer Text ausgegeben wird:
#!/usr/bin/env python
#coding: utf8
import time
import RPi.GPIO as GPIO
# Zählweise der Pins festlegen
GPIO.setmode(GPIO.BOARD)
# Pin 18 (GPIO 24) als Eingang festlegen
GPIO.setup(18, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
# Schleifenzähler
i = 0
# Ereignis-Funktion für Eingang HIGH
def doIfHigh(channel):
# Zugriff auf Variable i ermöglichen
global i
if GPIO.input(channel) == GPIO.HIGH:
# Wenn Eingang HIGH ist, Ausgabe im Terminal erzeugen
print "Eingang " + str(channel) + " HIGH " + str(i)
else:
# Wenn Eingang LOW ist, Ausgabe im Terminal erzeugen
print "Eingang " + str(channel) + " LOW " + str(i)
# Schleifenzähler erhöhen
i = i + 1
# Ereignis deklarieren
channel = 18
GPIO.add_event_detect(channel, GPIO.BOTH, callback = doIfHigh, bouncetime = 200)
# Eigentlicher Programmablauf
while 1:
time.sleep(0.1)
Status eines Ausgangs abfragen
Manchmal ist es nötig, in manchen Situationen vielleicht auch einfacher, den Status eines Ausgangs abzufragen. Dies geschieht vom Grunde her genauso, wie man einen Eingang abfragt nur dass man die Pin-Nummer des Ausgangs angibt. Hierzu ergänzen wir das Script gpio_ausgang.py um eine Zusätzliche Abfrage (Zeile 19-22).
#!/usr/bin/env python
#coding: utf8
import time
import RPi.GPIO as GPIO
# Zählweise der Pins festlegen
GPIO.setmode(GPIO.BOARD)
# Pin 22 (GPIO 25) als Ausgang festlegen
GPIO.setup(22, GPIO.OUT)
# Ausgang 3 mal ein-/ausschalten
i = 3
while i > 0:
# Ausgang einschalten
GPIO.output(22, GPIO.HIGH)
# Abfragen, ob Ausgang high ist
if GPIO.input(22) == GPIO.HIGH:
# Wenn Ausgang HIGH ist, Ausgabe im Terminal erzeugen
print "Ausgang HIGH"
# zwei Sekunden warten
time.sleep(2)
# Ausgang ausschalten
GPIO.output(22, GPIO.LOW)
# zwei Sekunden warten
time.sleep(2)
# Zähler für die Schleife herunter zählen
i = i - 1
# Ausgänge wieder freigeben
GPIO.cleanup()
- macOS: pimp your terminal prompt (ZSH) - 2. Januar 2026
- Proxmox: „Failed to connect to Server“ mit Safari auf MacOS - 28. Januar 2023
- Loxone: Benachrichtigung per Telegram - 15. Januar 2022






Pingback: GPIO Eingänge: Werte wechseln ständig zwischen 0 und 1 – Smarthome
Pingback: Drucker automatisch starten – MyBlog