GPIO mit Python-Programmen nutzen

GPIO mit Python-Programmen nutzen

Vor einiger Zeit wurde hier Verwendung der GPIO-Anschlüsse mit C-Programmen besprochen. Diesmal wird Python verwendet.


Inhalt:


Infos und Sicherheitshinweise

Mit Hilfe der GPIO-Anschlüsse (General Perpose Input and Output) des RaspberryPis lassen sich elektronische Ausgänge digital schalten bzw. Schalter/Zustände über Eingänge digital abfragen. Es lassen sich damit sogar über verschiedene spezielle Schnittstellenprotokolle andere elektronische Komponenten ansteuern.

ACHTUNG: Beim Beschalten dieser GPIO-Pins ist extreme Vorsicht geboten! Die Ein- und Ausgänge sind auf exakt 3,3 V ausgelegt. Jeder einzelne Pin sollte maximal mit 16 mA, sicherer wären maximal 8 mA, betrieben werden, wobei in Summe für alle GPIO-Pins eine Gesamtstromstärke von 50 mA nicht überschritten werden darf. Zusätzliche ist eine Spannung von 5 V für externe Komponenten verfügbar, deren höchste Stromstärke vom verwendeten Netzteil begrenzt ist, wobei die Stromstärke zum Betrieb des RaspberryPis selbst ebenfalls berücksichtig werden muss. Keinesfalls dürfen an Pins, die als Eingang verwendet werden, 5V anlegt werden. Eventuell muss mit Hilfe einer Spannungsteilerschaltung die Spannung reduziert werden.

Vor der Aktivierung einer Schaltung bitte alle Anschlüsse noch einmal kontrollieren, insbesondere auf richtige Polung, Kurzschlüsse, Überspannungen und zu starke Belastung der GPIOs achten!

Ein kleiner Fehler kann das ganze Board zerstören!

 

Python und die GPIOs

Mit Raspbian, der Standard-Linux-Distribution für den Raspberry Pi, werden zwei Bibliotheken bereitgestellt, sodass auf die GPIOs mit Python zugegriffen werden kann.

Für Einsteiger eignet sich die Bibliothek gpiozero am besten, da hier schnell elektronische Komponenten in Python-Programmen verwendet werden können.

from gpiozero import Button, LED

Die umfangreichere und professionellere Bibliothek zeigt sich in der Programmierung zwar aufwändiger, aber für größere Projekte flexibler.

import RPi.GPIO as GPIO

Wir werden letztere in den folgenden Aufgaben verwenden.

Auch wenn in vielen Anleitungen mit Python2 gearbeitet wird, wird hier von Python 3 ausgegangen.

Nummerierung der GPIO-Pins

Die Bezeichnungen für die GPIO-Pins sorgt häufig für Verwirrung, da es, je nach Internetseite oder Buch drei verschiedene Versionen dafür gibt. Im Folgenden beziehe ich mich auch die GPIO-Nummerierung wie folgt:

Diese Abbildung stammt von der Seite www.computerhilfe.de, wo man diese auch als PDF herunterladen kann. In der passenden Größe ausgedruckt und ausgeschnitten empfiehlt es sich diesen Hilfszettel auf die GPIO-Pins zu stecken, so findet man auch immer die richtigen Anschlüsse.

Die richtige Nummer ist dann nicht jene, die die Pins durchnummeriert, sondern jene, die mit z.B. GPIO 23 beschriftet sind.

Bevor in Python der erste GPIO-Befehl abgesetzt wird, muss die Zeile

GPIO.setmode(GPIO.BCM)

angeführt werden, welche diese Art der Nummerierung festlegt.

 

Schalten einer LED

Im ersten Versuch soll eine LED nur kurz aufleuchten:

#!/usr/bin/python3
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)   #Art der Pin-Nummerierung

GPIO.setup(7, GPIO.OUT)   #Pin7 als Output einstellen

GPIO.output (7, GPIO.HIGH)   #Pin7 auf HIGH stellen, d.h. Spannung von 3.3V einschalten

time.sleep(5)   #Pause von 5 Sekungen

GPIO.output (7, GPIO.LOW)   #Pin 7 auf LOW, d.h. Spannung ausschalten

GPIO.cleanup()   #Alle GPIO Einstellungen zurücksetzen

Mögliche Erweiterungen:

  • Blinkende LED mit Hilfe einer for-Schleife
  • Weitere LEDs abwechseln oder gleichzeitig blinkend
  • Ampelschaltung, d.h. rote, gelbe und grüne LED in richtiger Reihenfolge leuchtend
  • Ampelschaltung mit zusätzlicher roter und grüner LED als Fußgängerampel

 

Buttons verwenden

Mit Hilfe von einfachen Push-Buttons können an einem Pin-Eingang die digitalen Wert 0 oder 1 erzeugt werden.

Button mit PullUp-Widerstand

Mit der folgenden Schaltung wird durch Drücken des Buttons der Pin mit GND (= 0V) verbunden, was dem digitalen Wert 0 entspricht. Ist der Button nicht gedrückt, sorgt ein sogenannter PullUp-Widerstand dafür, dass der Pin mit 3.3 V verbunden ist, was dem digitalen Wert 1 entspricht.

Mit Hilfe de folgenden einfachen Programmes wird in einer Endlosschleife alle 100 ms der Eingang abgefragt, und der digitale Wert 1 oder 0 ausgegeben.

#!/usr/bin/python3
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)   #Art der Pin-Nummerierung

GPIO.setup(24, GPIO.IN)   #Pin24 als digitalen Eingang festlegen

while True:   # Endlosschleife, mit Strg-C beenden
        input = GPIO.input(24)   # Eingang einlesen
        print("Zustand: " + str(input))   #Ausgabe auf Bildschirm
        time.sleep (0.1)   # kurze Pause

Bessere wäre es, die obige While-Schleife in eine try-expept-Strukur zu klammern, um beim Abbrechen mit Strg-C die GPIO-Pins zurückzusetzen:

#!/usr/bin/python3
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)   #Art der Pin-Nummerierung

GPIO.setup(24, GPIO.IN)   #Pin24 als digitalen Eingang festlegen

try:
        while True:   # Endlosschleife, mit Strg-C beenden
                input = GPIO.input(24)   # Eingang einlesen
                print("Zustand: " + str(input))   #Ausgabe auf Bildschirm
                time.sleep (0.1)   # kurze Pause
except KeyboardInterrupt:
        GPIO.cleanup()

Mögliche Erweiterungen:

  • Ein- und Ausschalten einer LED
  • Umschalten zwischen mehreren LED
  • Ampelschaltung um Fußgänger-Button erweitern

Button mit PullDown-Widerstand

Im Gegensatz zur obigen Schaltung wird hier durch Drücken des Buttons der GPIO-Eingang auf 3.3 V geschaltet, was digital dem Wert 1 entspricht. Im nicht gedrückten Zustand wird der GPIO-Pin über den Pull-Down-Widerstand mit 0V (GND) verbunden, was logisch den Wert 0 ergibt.

Obiges Programm zur regelmäßigen Abfrage eines GPIO-Eingang funktioniert auch mit dieser Schaltung und sollte den entsprechenden Wert wie beschrieben ausgeben.

Die digitalen Werte 0 und 1

Die GPIO-Pins sind digitale Ein- bzw. Ausgänge. In Programmen werden als GPIO.IN gesetzte Pins nur die Werte 0 oder 1 liefern, wobei dies gleichwertig zu den boolschen Werte False oder True ist, bzw. zu den GPIO-Konstanten GPIO.LOW bzw. GPIO.HIGH. Pins, die als GPIO.OUT deklariert wurden, müssen mit diesen Werten gesetzt werden.

Für als Ausgänge festgelegt Pins bedeutet die Ausgabe des logischen Wertes 1 eine Spannung von 3,3 V und die Ausgabe des logischen Wertes 0 eine Spannung von 0 V gegenüber GND. Ein angeschlossener Verbraucher sollte eine Stromstärke von von 16 mA an einem Pin nicht überschreiten, wobei die Summe aller entnommenen Ströme an allen Pins max. 50 mA ausmachen darf.

Für Eingänge ist der Raspi relativ tolerant, was die angelegte Spannung betrifft. Spannungen über rund 2 V werden als HIGH interpretiert, Spannungen unter 1 V als LOW (wobei die Angaben dazu sehr variieren).

logische Werte digitaler
Ausgang
digitaler
Eingang
HIGH 1 True 3,3 V > 2 V
LOW 0 False 0 V < 1 V

 

Der Ultraschallsensor HC-SR04

Ein günstiger und einfach zu programmierender Ultraschallsensor, der sich zur Abstandsmessung eignet, ist der HC-SR04.

Der Sensor hat vier Anschlüsse. Als Stromversorgung müssen am Pin mit der Bezeichnung VCC 5V und GND angeschlossen sein. Wird am Anschluss Trig von HIGH auf LOW umgeschaltet („fallende Flanke“) und bleibt dieser Zustand für mind. 10 µs auf LOW, so wird ein Ultraschall-Signal mit 40 kHz ausgesandt. Gleichzeitig wird vom Sensor der Anschluss Echo auf HIGH gesetzt, solange, bis ein reflektiertes Ultraschallsignal vom Sensor detektiert wird. Dann wird der Anschluss Echo wieder LOW, sodass die Dauer des HIGH-Pegels am Anschluss Echo der Laufzeit des Ultraschallsignals entspricht. Die gemessene Zeit kann mit Hilfe der Schallgeschwindigkeit (343 m/s bei 20°C) in den zu messenden Abstand umgerechnet werden.

Der Sensor ist auf eine Spannung von 5 V ausgelegt, was für die Stromversorgung durch den Raspi kein Problem darstellt. Allerdings muss der HIGH-Level des Echo-Ausganges für den Raspberry-Eingang durch einen Spannungsteiler zweier Widerstandsbauteile auf unter 3,3 V gesenkt werden.

Im folgenden Programm wird ein kurzer Impuls an den Trigger-Anschluss des HC-SR04 gelegt und dann die Laufzeit für den Hin- und Rückweg des US-Signals gemessen, woraus sich dann der Abstand zum reflektieren Objekt ermitteln lässt. Die Messung und anschließende Ausgabe des Messwertes auf eine Nachkommastelle gerundet erfolgt im Sekundentakt.

#!/usr/bin/python3
# Datei ultraschall.py
import time
import RPi.GPIO as GPIO

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
trig = 23 # GPIO-Pin-Nummer fürs Auslösen der Messung
echo = 24 # GPIO-Pin zur Messung der Laufzeit des Ultraschall-Signals

GPIO.setup(echo, GPIO.IN)
GPIO.setup(trig, GPIO.OUT)


while True :
        GPIO.output(trig, GPIO.HIGH)
        time.sleep (0.00001) # 10 Mikrosekunden
        GPIO.output(trig, False) # Umschalten auf LOW = fallende Flanke

        while GPIO.input(echo) == 0: # Warten bis Start des US-Signals
                pass
        start = time.time() # Start der Zeitmessung beim Aussenden des US-Signals

        while GPIO.input(echo) == 1: # Warten bis Rückkehr des US-Signals
                pass
        ende = time.time() # Ende der Zeitmessung bei Rückkehr des US-Signals

        entfernung = ((ende - start) * 34300) / 2 # Berechnung desAbstandes aus der Laufzeit des US-Signals
        print("Entfernung:", round(entfernung,1) , "cm")
        time.sleep (1)

Zwar finden sich häufig Beschreibungen, die dem Ultraschall-Sensor eine Genauigkeit von 3 mm bescheinigen, aber nach meinen Erfahrungen liegt die Genauigkeit im Zentimeterbereich.

Mögliche Erweiterungen:

  • Einschalten einer LED bei Annäherung unter 30 cm bzw. Ausschalten bei Entfernung.
  • 3 LEDs, die die Entfernung anzeigen: > 50 cm grün, <= 50 und > 25 cm gelb, <=25 cm rot

Dieser Beitrag wurde unter Raspberry Pi veröffentlicht. Setze ein Lesezeichen auf den Permalink.