Einführung zu GPIO Pins

In diesem Blog Post erfährst Du alles rund um die GPIO Pins des Raspberry Pi. Dieser Post ist besonders für Neulinge im Elektronikbereich gedacht.

Vorab noch eine Warnung

Der Raspberry Pi kann bei falscher Verwendung der Pins irreparabel beschädigt werden. Versichere dich also immer, dass dein Stromkreis korrekt ist und dass Du genügend Widerstände verwendest.

Was sind GPIO Pins

Die GPIO Pins sind die 40 kleinen Metallstifte an der Oberseite des Raspberry Pi. Die Abkürzung GPIO steht für General Purpose Input Output, also Allzweck Eingabe und Ausgabe. Das heißt die GPIO Pins können als Schnittstelle für nahezu jedes Elektronische Gerät verwendet werden.

Aufgrund der großen Anzahl an Möglichkeiten die Pins (falsch) zu verwenden, kann der Einstieg etwas verwirrend sein. Deshalb liefert dieser Blog Post einige Beispiele dafür, wie man die Pins mit Bash, C und Python ansteuert. Ein wenig Erfahrung im programmieren ist also von Vorteil.

Obwohl die 40 Pins identisch aussehen, haben sie unterschiedliche Funktionen. 26 Pins können für GPIO genutzt werden und haben teilweise zusätzliche Funktionen. Weitere 4 Pins dienen als Stromquelle (POWER, zwei mal 3V3 und zwei mal 5V) und 8 als Negativpol (auch Masse oder GROUND). Die zwei verbliebenen Pins sind die I2C Schnittstelle für ID EEPROM.

Pinout

Die untenstehende Graphik zeigt noch einmal die wichtigsten Informationen, unter anderem die Belegung auch Pinout genannt. Das Pinout ist für die meisten Raspberry Pi Modelle identisch, aber es gibt auch Unterschiede. Schau Dir am besten immer das exakte Pinout deines Models an, bevor Du ein Gerät anschließt. Dafür musst du auf deinem Raspberry Pi nur ein Terminal öffnen (Strg+Alt+t) und das Kommando

pinout

ausführen. 

Raspberry Pi Pinout

 

Vielleich ist Dir aufgefallen, dass die GPIO Nummern willkürlich erscheinen und nicht mit der Pin Nummerierung übereinstimmen. Um Verwirrungen zu vermeiden bezeichne ich die Nummerierung von 1 bis 40 als BOARD Nummer und die Nummer von 1 bis 26 als BCM oder GPIO Nummer.

BOARD Pin 1 ist also der 3V3 POWER Anschluss und GPIO Pin 2 ist der Pin daneben mit der BOARD Nummer 3.

Wie schließe ich ein Gerät an die Pins an

Es gibt verschiedene Alternativen um ein Gerät an die GPIO Pins anzuschließen. Manche Geräte verfügen über einen GPIO Header, so dass das Gerät direkt auf die GPIO Pins gesteckt werden kann. Im Allgemeinen ist das aber nicht der Fall, weshalb man Jumper Wires oder GPIO extension Kabel verwendet.

Wenn Du nicht lesen möchtest, schau Dir unser Video zu den GPIO Pins an.

In den Folgenden Beispiel wird eine LED mithilfe von Jumper Kabeln an den Raspberry Pi angeschlossen.

Der Aufbau

Das Female to Male Jumper Wires verbindet den GPIO Pin mit einem  Header oder ein Breadboard. Anschließend muss der Pin programmiert werden um das Gerät zu betreiben. Das Gerät kann beispielsweise ein ein Button, eine LED, ein Sensor, ein Motor oder ein Display sein. Wichtig ist nur dass das Gerät mit 5 Volt oder weniger betrieben werden kann und dass es mit den Schnittstellen I2C, SPI oder UART kompatibel ist.

Für den Aufbau benötigen wir folgendes Equipment.

  • Raspberry Pi mit Raspberry Pi OS
  • Zwei Male to Female Jumper Wires
  • Ein Male to Male Jumper Wire
  • 10 kilo Ohm Widerstand
  • LED
  • Solderless Breadboard

Verbinde den GPIO Pin 13 (BOARD Nummer 33) mit dem + Streifen und den GROUND Pin daneben (BOARD Nummer 34) mit dem - Streifen des Breadboards. Stecke anschließend ein Ende des 10 kilo Ohm Widerstands (egal welches) in den + Streifen und das andere Ende in einen der Querstreifen. Bei der LED ist die Orientierung entscheidend. Die Anode ist der längere der zwei Arme und oftmals abgeknickt, die Kathode ist der kürzere Arm. Die Anode muss immer in Richtung + also in Richtung Stromquelle zeigen und die Kathode in Richtung - also in Richtung GROUND. Stecke also den längeren Arm in den selben Querstreifen wie den Widerstand, sodass der kürzere Arm im benachbarten Querstreifen steckt. Verbinde zuletzt mithilfe des Male to Male Jumper Kabels den Querstreifen der Kathode (kürzerer Arm der LED) mit dem - Streifen.

Die folgende Graphik zeigt den Aufbau, vergewissere Dich noch einmal, dass alles korrekt ist und dass die Komponenten bis zum Anschlag im Breaboard stecken, da sonst Wackelkontakte auftreten.

Aufbau des Schaltkreises

Die folgenden drei Codebeispiele in Bash, Python und C sind gehen von diesem Aufbau aus. Wenn Du andere Pins verwendest musst Du den Code entsprechend abändern.

Bash

Die GPIO Pins per Bash anzusteuern ist sehr einfach. In Linux werden die GPIO Pins durch die Files im /sys/class/gpio Ordner kontrolliert. Um einen GPIO Pin zu nutzen muss er zuerst exportiert werden. Als Beispiel verwende ich GPIO Pin 13. Im Folgenden sind die Kommandos bold und kursiv.

Öffne ein Terminal und liste den Inhalt des gpio Ordners auf.

cd /sys/class/gpio
ls

der Ordner enthält die Files export und unexport sowie Unterordner für jeden exportierten GPIO Pin

Wir exportieren den Pin indem wir die GPIO Nummer in das /sys/class/gpio/export File schreiben. Führe dafür dieses Kommando im Terminal aus.

echo 13 > /sys/class/gpio/export
ls

Nun wurde ein Ordner mit der entsprechenden Pinnummer angelegt gpio13. In diesem Ordner befinden sich weitere Ordner und Dateien. Wichtig für uns sind vorerst aber nur das direction und das value File.

Das direction File speichert den Modus des Pins:

in -> Pin ist im Read oder Input Modus

out -> Pin ist im Write oder Output Modus

Das value File speichert den Spannungszustand des Pins:

0 -> Pin ist im LOW Modus -> Es liegt keine Spannung an dem Pin an

1 -> Pin ist im HIGH Modus -> Es liegt Spannung an dem Pin an

Die folgenden Befehle setzen den Modus auf out und den Value auf 1.

echo out > /sys/class/gpio/gpio13/direction

echo 1 > /sys/class/gpio/gpio13/value

Die LED leuchtet jetzt. Es ist wichtig die Werte des Pins nach der Nutzung wieder zurückzusetzen. Die folgenden Befehle sollten nach jeder Nutzung ausgeführt werden.

echo 0 > /sys/class/gpio/gpio13/value

echo in > /sys/class/gpio/gpio13/direction

echo 13 > /sys/class/gpio/unexport

Python Programm

Nun abstrahieren und automatisieren wir diese Bash befehle in Python.

Das folgende Python Skript stellt eine einfach GPIO_Pin Klasse bereit. Dies vereinfacht die Handhabung extrem. Das os Modul ermöglicht es uns, die gleichen Bash Kommandos aus Python heraus auszuführen. durch die __del__ Methode müssen wir die Pins außerdem nicht mehr manuell zurücksetzen und unexportieren.

import os
from time import sleep

class GPIO_Pin:
    def __init__(self, num, mode):
        if 0 <= num or num <= 40:
            self.num = num
        else:
            print('Invalid Pin Number -> Enter a number from 0 - 40')
        if mode == 'out' or mode == 'write':
            self.mode = 'out'
        elif mode == 'in' or mode == 'read':
            self.mode = 'in'
        else:
            print('Invalid Pin Mode -> Enter "out" or "write" for output, "in" or "read" for input')
        if self.num and self.mode:
            os.system(f'echo {str(self.num)} > /sys/class/gpio/export')
            sleep(0.05)
            os.system(f'echo {self.mode} > /sys/class/gpio/gpio{str(self.num)}/direction')

    def reset(self):
        os.system(f'echo 0 > /sys/class/gpio/gpio{str(self.num)}/value')
        os.system(f'echo in > /sys/class/gpio/gpio{str(self.num)}/direction')

    def write(self, value):
        if value == 0 or value == 'LOW':
            os.system(f'echo 0 > /sys/class/gpio/gpio{str(self.num)}/value')
        elif value == 1 or value == 'HIGH':
            os.system(f'echo 1 > /sys/class/gpio/gpio{str(self.num)}/value')
        else:
            print('Invalid value -> Enter 1 or "HIGH" for HIGH, 0 or "LOW" for LOW')

    def __del__(self):
        self.reset()
        os.system(f'echo {str(self.num)} > /sys/class/gpio/unexport')

    def set_mode(self, mode):
        self.mode = mode
        os.system(f'echo {str(self.mode)} > /sys/class/gpio/gpio{str(self.num)}/direction')

def main():
    pin = GPIO_Pin(13, 'out')
    number_of_blinks = 10
    for i in range(number_of_blinks):
        pin.write('HIGH')
        sleep(0.5)
        pin.write('LOW')
        sleep(0.5)

if __name__ == '__main__':
    main()
Durch das time Modul können wir die LED sogar ohne Problem blinken lassen. Das ganze Skript lässt sich zu einem Python Modul für GPIO Kontrolle erweitern.

C Programm

Auch in C können wir den Inhalt des gpio Ordners leicht bearbeiten. Mithilfe der Standardbibliothek stdlib können wir Dateien öffnen und den Inhalt ändern.
Das folgende C Programm muss vor dem Ausführen noch kompiliert werden. Lege dafür ein File gpio.c an und kopiere das Programm in das File.
Dann öffne ein Terminal und navigiere in den Ordner in dem das gpio.c File liegt. Mit den folgenden Befehlen wird das Programm kompiliert und ausgeführt.
gcc -o gpio gpio.c
./gpio
Hier ist das Programm.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define GPIO_ROOT "/sys/class/gpio"
#define EXPORT "/sys/class/gpio/export"
#define UNEXPORT "/sys/class/gpio/export"

#define LOW 0
#define HIGH 1

int export_pin(int num) {
    FILE* export = fopen(EXPORT, "w");
    if (export == NULL) {
        printf("Failed to open the export file\n");
        exit(-1);
    }
    fprintf(export, "%d", num);
    fclose(export);
    return 0;
}

int unexport_pin(int num) {
    FILE* unexport = fopen(UNEXPORT, "w");
    if (unexport == NULL) {
        printf("Failed to open the unexport file\n");
        exit(-1);
    }
    fprintf(unexport, "%d", num);
    fclose(unexport);
    return 0;
}

int set_direction(char *mode, int num) {
    char direction_file_path[1024];
    snprintf(direction_file_path, sizeof(direction_file_path), "/sys/class/gpio/gpio%d/direction", num);
    FILE* direction = fopen(direction_file_path, "w");
    if (direction == NULL) {
        printf("Failed to open the direction file\n");
        exit(-1);
    }
    fputs(mode, direction);
    fclose(direction);
    return 0;
}

int set_value(int val, int num) {
    char value_file_path[1024];
    snprintf(value_file_path, sizeof(value_file_path), "/sys/class/gpio/gpio%d/value", num);
    FILE* value = fopen(value_file_path, "w");
    if (value == NULL) {
        printf("Failed to open the value file\n");
        exit(-1);
    }
    fprintf(value, "%d", val);
    fclose(value);
    return 0;
}

int main() {

    int rslt;
    int num;
    int num_blinks;

    num = 13;
    num_blinks = 10;

    rslt = export_pin(num);
    rslt = set_direction("out", num);
    for (int i = 0; i < num_blinks; i++) {
        rslt = set_value(HIGH, num);
        sleep(1);
        rslt = set_value(LOW, num);
        sleep(1);
    }

    rslt = set_value(LOW, num);
    rslt = set_direction("in", num);
    rslt = unexport_pin(num);

    return EXIT_SUCCESS;
}

PiCockpit - GPIO App

Die einfachste Variante die GPIO Pins anzusteuern ist mithilfe der GPIO App. Das PiCockpit Webinterface ist kostenlos für bis zu 5 Raspberry Pi. Es bietet zwei große Vorteile: Du musst nicht programmieren können um deine GPIO Pins zu kontrollieren und Du kannst dies von überall aus tun.

Installiere einfach den PiCockpit Client auf deinem Raspberry Pi und verbinde dich mit deinem PiCockpit Account. Danach kannst du die GPIO Pins ganz bequem über das Webinterface kontrollieren.

 

Jetzt weißt du wie Du die GPIO Pins mithilfe von Jumper Wires verwendest. Natürlich gibt es auch externe Python Module und C librarys um die  GPIO Pins zu steuern. Ein guter nächster Schritt wäre eines der Codebeispiele zu erweitern. Zum Beispiel durch Verwendung zusätzlicher LEDs oder eines Buttons.
Viel Spaß beim Experimentieren!
BashCGpioGpio pinsGpio am raspberry piPython

Leave a comment

All comments are moderated before being published