Latest posts

Python GPIO Befehle im Überblick – Raspberry Pi

GPIO sind die 40 steuerbaren Pins, die du auf deinem Raspberry Pi findest. Diese GPIO kann man individuell als Eingang und Ausgang steuern. Es gibt verschiedene Möglichkeiten, dies zu tun. Wir bedienen uns der Bibliothek von Python RPi GPIO.

In diesem Tutorial geben wir dir einen strukturierten Überblick über die Befehle der RPi GPIO Bibliothek und beschreiben dir, für was und wie du sie einsetzen kannst.

Bist du mit den Grundlagen vertraut, kannst du direkt zur Befehlsübersicht springen.


GPIO Pinbelegung

GPIOs können, als Ausgang beschaltet, eine Spannung von 3,3 V DC ausgeben. Betreibst du sie als Eingang, so erkennen sie Spannung größer 2V als Hochsignal und Spannung bis 0,8 V als Nullpegel.

Eine permanente Spannung von entweder 3,3 oder 5 V bieten die Pins 1, 2, 4 und 17.

Die Masse (den Minus-Pol) kann man jeweils über einen der GND (Ground) Pins abführen.

Da der maximale Strom der GPIOs auf wenige mA begrenzt ist (ca. 16 mA pro Pin und max. ca. 50 mA), nutzt man den Ausgang oft nur als Steuersignal für Transistoren oder Relais und betreibt seine Bauteile mit einer externen Stromquelle.

Für unsere Versuchszwecke reicht der Strom aus.

gpio-pin-belegung-raspberry-pi-3-4-5-b-+-zero-w-h

Abb.: GPIO-Pinbelegung für alle gängigen Raspberry Pi


Empfohlenes Equipment

Damit du die GPIO-Befehle entsprechend testen kannst, hier eine Liste von vorgeschlagenen / erforderlichen Bauteilen:

  • Betriebsbereiten Raspberry Pi
  • Breadboard – Steckplatte
  • Jumperkabel
  • Wenn Raspberry Pi Zero: Sockel-Pins
  • Diverse Bauelemente (PIR Bewegungssensor, Taster, Widerstände, LEDs, Ultraschallsensor)

Wir werden nur einen Taster, Widerstände und eine LED als Bauelemente benötigen, um die Tests durchzuführen.


Installation, Import und wichtige Befehle für RPi GPIOs

Beginner-Info: Python Skript-Datei anlegen

Zu Beginn, leg dir eine Python-Skriptdatei in einem Ordner auf dem Raspberry Pi an, in der du arbeiten und deinen Code schreiben möchtest.

Starten kannst du es anschließend, indem du im LXTerminal zum Ordner des Skripts navigierst und es mit dem Python-Befehl ausführst (Root-Ordner ist home/pi).

Beispiel


$ cd ordner/deinunterordner $ python3 rpi-gpios.py

GPIO deklarieren: To-Do’s im Skript!

Die Python Bibliothek RPi GPIO gliedert sich in drei Hauptteile auf: Deklaration als Eingang, als Ausgang und als Pulsweitenmodulation.

Auf jedem aktuellen Raspberry Pi Modell sollte das GPIO Modul bereits vorinstalliert sein. Wenn nicht, kannst du das mit folgendem Befehl nachholen:


$ pip install RPi.GPIO

1. Importieren

Die Bibliothek wird in Python mit folgendem Befehl importiert:


import RPi.GPIO as GPIO

2. Setmode festlegen – GPIO oder Board-Nummer

Zusätzlich zum Import ist noch festzulegen, nach welcher Methode ihr die GPIO PINs eures RPi ansprecht.

  • GPIO.setmode(GPIO.BOARD)
    GPIO Nummerierung nach Pin-Nummerierung auf dem Board
  • GPIO.setmode(GPIO.BCM)
    GPIO Nummerierung nach GPIO-Nummerierung. Siehe Pinbeschriftung oben.

3. Wichtig zum Schluss! – GPIO.cleanup

Am Ende eines jeden Programms müssen alle vorhandenen GPIO Instanzen gelöscht werden, da es sonst beim Neustart des Programms zu einem Deklarationsfehler kommen kann:


GPIO.cleanup()

Wir haben jetzt alle Basics, die wir brauchen, um mit der GPIO Python Bibliothek zu arbeiten.


GPIO Eingangssignale

Ein GPIO Pin deklariert man wie folgt als Eingang:


GPIO.setup(channel, GPIO.IN)

Channel steht hierbei für den GPIO bzw. die Board-Nummer, je nachdem wie du den Parameter GPIO.setmode() gesetzt hast.

Ein GPIO-Eingang ist mit einem Steuersignal zu versehen. Dieses bezieht man beispielsweise von einem Sensor (siehe Anleitung PIR Bewegungssensor) oder von einem Schalter mit Pull-Up bzw. Pull-Down Widerstand.

Die Darstellung zeigen die Versuchsschaltung:

gpio-led-schaltung-r-pi-raspberry-pi-3-4-5-b-zero r-pi-raspberry-pi-3-4-5-b-zero-led-schaltung-schalt-plan

Startet man das Programm, wartet der GPIO auf ein eingehendes Signal größer 2 V und gibt programmseitig eine 1 (True) zurück. Fällt die Spannung unter 0,8V, wird das Signal 0 (False).


GPIO.input(channel)

Dieser Befehl gibt entweder 1 oder 0 zurück, je nachdem ob am GPIO eine Spannung anliegt oder nicht.

Beispiel: Taster-Schaltung mit GPIO als Eingangssignal


import RPi.GPIO as GPIO
import random
import time

switch = 17

GPIO.setmode(GPIO.BCM)
GPIO.setup(switch, GPIO.IN)

randomNothing = ["nothing", "still nothing", "just waiting", "Oh! Was there anything? No, probably just a fly", "I'm bored", "I wanna go home"]

try:
    while True:
        if GPIO.input(switch) is 1:
            print("I saw the sign!")
        else: 
            print(random.choice(randomNothing))
        time.sleep(1)
        
except KeyboardInterrupt:
    print("Bye Bye")
    GPIO.cleanup()

Das obige Programm überwacht den GPIO Pin switch (Pin 17). Wenn der Taster gedrückt wird, gibt es die Meldung „I saw the sign!“ aus. Andernfalls wird eine zufällige Nachricht aus der randomNothing-Liste angezeigt. Mit der Taste ctrl+C kann das Skript beendet werden, und GPIO.cleanup() sorgt dafür, dass alle GPIOs korrekt freigegeben werden.


Event-Erkennung

Die beiden folgenden RPi GPIO Statements sind so designed, dass sie auf ein auftretendes Event warten.

Wait for Edge

wait_for_edge blockt das Programm, solange bis ein Event erkannt wurde:


GPIO.wait_for_edge(channel, GPIO.RISING)

Der optionale timeout Parameter legt eine maximale Zeit in Millisekunden fest, in der auf ein Event gewartet wird, bevor das Skript weiterläuft:


GPIO.wait_for_edge(channel, GPIO.RISING, timeout=5000)

Beispiel: Wait-for-Edge


import RPi.GPIO as GPIO
import time

switch = 17

GPIO.setmode(GPIO.BCM)
GPIO.setup(switch, GPIO.IN)

try:
    while True:
        GPIO.wait_for_edge(switch, GPIO.RISING, timeout=5000)
        print("Something happened or time is up")
        time.sleep(0.5)

except KeyboardInterrupt:
    print("Bye Bye")
    GPIO.cleanup()

Event Detected

Bei event_detected wird das Skript nicht unterbrochen. Es läuft einfach weiter. Man kann es zum Beispiel in Schleifen einsetzen. Der Vorteil an diesem Befehl ist, dass das Event asynchron erkannt wird. Ungeachtet dessen, dass die CPU gerade einen anderen Programmteil ausführt, wird die Erkennung einer Flanke gespeichert.


GPIO.add_event_detect(channel, GPIO.RISING)

Man kann in den Parametern festlegen, auf welche Flanke reagiert werden soll:

  • GPIO.RISING – Steigende Flanke
  • GPIO.FALLING – Fallende Flanke
  • GPIO.BOTH – Beides

Beispiel: Event-Detection


import RPi.GPIO as GPIO
import time

switch = 17

GPIO.setmode(GPIO.BCM)
GPIO.setup(switch, GPIO.IN)
GPIO.add_event_detect(switch, GPIO.RISING)

try:
    while True:
        if GPIO.event_detected(switch):
            print("Rising edge detected! Steigende Flanke erkannt! Front montant détecté.")

        print("Busy")
        time.sleep(3)
        print("Really busy")
        # Hier drücken wir den Schalter. Das Programm merkt sich den Status und wird ausgeführt,
        # sobald das Skript sich wieder an dieser Position befindet
        time.sleep(3)
        print("Still busy")
        time.sleep(3)

except KeyboardInterrupt:
    print("Bye Bye")
    GPIO.cleanup()

Event Detected mit Callback Funktion

Es ist auch möglich, bei der Erkennung eine Callback-Funktion auszuführen. Der Vorteil an dieser Variante ist, dass die Funktion direkt beim Erkennen der Flanke ausgeführt wird.

Beispiel: Event-Detection mit Callback-Funktion


import RPi.GPIO as GPIO
import time

switch = 17

GPIO.setmode(GPIO.BCM)
GPIO.setup(switch, GPIO.IN)

def callback_function(switch):
    print("Falling from high to low. That really hurts!")

try:
    # Läuft asynchron, parallel zur Schleife. Führt sofort aus bei fallender Flanke
    GPIO.add_event_detect(switch, GPIO.FALLING, callback=callback_function, bouncetime=200)  # "Bouncing" verhindern
    while True:
        print("Busy")
        time.sleep(3)
        print("Really busy")
        time.sleep(3)
        print("Still busy")
        time.sleep(3)

except KeyboardInterrupt:
    print("Bye Bye")
    GPIO.cleanup()

Event Detection Entfernen

Ist im Laufe des Programms die Event-Erkennung nicht mehr gewünscht, kann man sie mit folgendem Befehl deaktivieren:


GPIO.remove_event_detect(channel)


GPIO Ausgangssignale

GPIO.output(channel, GPIO.HIGH)

Setz deinen GPIO Pin als Ausgang. Der zweite Parameter gibt den initialen Zustand vor. Default ist GPIO.LOW. Statt GPIO.HIGH und GPIO.LOW, kann man auch einfach 1 oder 0 bzw. True oder False benutzen.

Beispiel: LED-Schaltung mit GPIO als Ausgang


import RPi.GPIO as GPIO
import time

led = 23

GPIO.setmode(GPIO.BCM)
GPIO.setup(led, GPIO.OUT)

try:
    while True:
        GPIO.output(led, 1) # 1/0, True/False, GPIO.HIGH/GPIO.LOW accepted
        time.sleep(5) # 5 seconds light on
        GPIO.output(led, False)
        time.sleep(5) # 5 seconds light off

except KeyboardInterrupt:
    print ("Quit")
    GPIO.output(led, GPIO.LOW)
    GPIO.cleanup()

Ebenfalls ist es möglich, den Status des Ausgangs abzufragen, indem man ihn kurzzeitig als Input deklariert:


GPIO.output(12, not GPIO.input(12))

Pulsweitenmodulation (PWM)

Mit Hilfe der Pulsweitenmodulation kannst du unter Zuhilfenahme der Frequenz und einer Einschaltzeit deine Ausgänge dimmen bzw. eine Blinkschaltung realisieren.

Beispiel: Blinkschaltung


import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
led = 23
GPIO.setup(led, GPIO.OUT)

led_pwm = GPIO.PWM(led, 0.1) # 0.1 Hz entspricht einer Periodendauer von 10 Sekunden.

"""
Beispiel:
0.1 Hz bedeutet 0,1 Periode pro Sekunde. Also eine Periodendauer von 10 Sekunden.

80% der Amplitude ist die LED an. 20% der Amplitude ist die LED aus.
Also 8 Sekunden an und 2 Sekunden aus.
"""

try:
    while True:
        led_pwm.start(80) # Prozentuale Einschaltzeit, abhängig von der eingestellten Periodendauer.
                            # Bereich zwischen 0.0 und 100

except KeyboardInterrupt:
    print ("Quit")
    led_pwm.stop()
    GPIO.cleanup()

Beispiel: Dimmen


import RPi.GPIO as GPIO
import time

led = 23

GPIO.setmode(GPIO.BCM)
GPIO.setup(led, GPIO.OUT)

try:
    while True:
        for brightness in range(0, 101, 5):
            GPIO.output(led, True) # LED einschalten
            time.sleep(brightness/100.0) # Helligkeit durch sleep-Dauer beeinflussen
            GPIO.output(led, False)
            time.sleep((100-brightness)/100.0) # Zeit bis zum nächsten Durchlauf

except KeyboardInterrupt:
    print ("Quit")
    GPIO.output(led, GPIO.LOW)
    GPIO.cleanup()

Überblick PWM-Befehle

  • pwm = GPIO.PWM(channel, freq)
    Weise PWM Instanz zu. Frequenz zwischen 0.0 und 100 sinnvoll.
  • pwm.start(t)
    Starte PWM mit Einschaltzeit t in Prozent zwischen 0.0 und 100.
  • pwm.ChangeFrequency(freq)
    Ändere die Frequenz.
  • pwm.ChangeDutyCycle(t)
    Ändere die Einschaltzeit.
  • pwm.stop()
    Stoppe die PWM.


Status eines Pins abfragen

Möchtet ihr, aus welchem Grund auch immer, den Status eines GPIOs abfragen, könnt ihr das tun mit:


GPIO.setmode(GPIO.BOARD)

func = GPIO.gpio_function(pin)

Folgende Ausgaben sind möglich:

  • GPIO.IN
  • GPIO.OUT
  • GPIO.SPI
  • GPIO.I2C
  • GPIO.HARD_PWM
  • GPIO.SERIAL
  • GPIO.UNKNOWN


Schluss

Mit diesen Befehlen seid ihr nun in der Lage, alle erdenklichen Schaltungen aufzubauen. Oder eben halt auch nur so etwas:

Posted in: RPi GPIO Tutorials

Leave a comment