Raspberry Pi: GPIO Steuerung in der bash

Um die GPIO Pins des Raspberry Pi zu steuern braucht es nicht unbedingt eine Programmiersprache wie Python oder C. Ich zeige dir in diesem Post, wie es auch direkt mit einem bash Script geht.

Ich benutze hier:

  • einen Raspberry Pi 5 mit Raspberry Pi OS (bookworm)
  • einen Raspberry Pi 4 mit Armbian (bullseye)
  • die bekannte Ampelschaltung
  • einen Taster quadratisch, mit vier Pins

Softwaresetup

Um per bash auf die GPIO zuzugreifen, existieren die Kommandos gpioset zum Schalten eines Pins oder gpioget , um den zustand eines Pins auszulesen. Sollten diese auf deinen Raspi noch nicht installiert sein, kannst du dies mit

sudo apt install gpiod -y

nachholen. Dieses Paket ist unter bookworm und bullseye verfügbar. Für älteren Debianversionen weiß ich das nicht. Vielleicht kannst du mir darüber Feedback geben.

Nach der Installation befinden sich verschiedene gpio Kommandos unter /usr/bin
raspithek.de - Olli Graf
gpio-commandsCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Nach der Installation befinden sich verschiedene gpio Kommandos unter /usr/bin

Um die Kommandos nicht immer mit sudo zu starten, solltest du deinen User der gpio Gruppe hinzufügen

sudo usermod -aG gpio "$USER"

Danach ein ab- und wieder anmelden, damit die Modifikation greift.

Hardwareaufbau

Wie oben geschrieben nehme ich mal wieder das Ampel Breakoutboard zu Hilfe, das mit allen Jumperkabel an die inneren Pins angeschlossen wird

Raspberry Pi 4 GPIO Pinout (Bild von pinout.xyz)
  • Masse (schwarz) -> GND links neben Pin 17
  • rote LED -> Pin 17
  • gelbe LED -> Pin 27
  • grüne LED -> Pin 22

Bei der Nummerierung handelt es sich um die Zählweise des Broadcom Chips.

Dieser Aufbau hat den Vorteil, dass alle verwendeten Pins direkt nebeneinander liegen. Allerdings könnte das Anschließen der Jumperkabel etwas pummelig werden.

Ausschnittvergrößerung der eingesteckten Jumperkabel
raspithek.de - Olli Graf
detail-jumpersCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Ausschnittvergrößerung der eingesteckten Jumperkabel
Hardwareaufbau mit Raspberry Pi 5
raspithek.de - Olli Graf
raspi5-ampelCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Hardwareaufbau mit Raspberry Pi 5

gpioinfo

Mit dem Kommando gpioinfo gpiochip0 erhältst du Informationen zu den einzelnen Pins der GPIO Leiste

gpiochip0 ist das Device des Linuxkernels, das die GPIO Leiste verwaltet.

oberer Teil der Ausgabe von gpioinfo
raspithek.de - Olli Graf
gpioinfo-outputCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
oberer Teil der Ausgabe von gpioinfo

LED schalten

Nachdem die Hardware fertig aufgebaut und der Raspi konfiguriert ist, kannst du jetzt die rote LED mit

gpioset gpiochip0 17=1

einschalten. Die rote LED des Ampel-Breakoutboards ist an Pin 17 angeschlossen, gpiochip0 ist das Device des Linuxkernels, das die GPIO Leiste verwaltet. Mit 17=0 schaltest du die rote LED wieder aus. Um gelb oder grün zu schalten benutzt du einfach die oben aufgelisteten Pins.

Mit dem Wissen können wir jetzt ein Script bauen, dass die Ampelphasen automatisch durchschaltet.

#! /usr/bin/bash

pin_rot=17     # z.B. Pin 11 (BCM 17)
pin_gelb=27    # z.B. Pin 13 (BCM 27)
pin_gruen=22   # z.B. Pin 15 (BCM 22)

state_rot=0
state_gelb=0
state_gruen=0

gpiochip="gpiochip0"

function resetPins() {
  echo "Ampel aus"
  gpioset "${gpiochip}" ${pin_rot}=0 ${pin_gelb}=0 ${pin_gruen}=0
}


function setPins() {
  gpioset "${gpiochip}" ${pin_rot}=${state_rot} ${pin_gelb}=${state_gelb} ${pin_gruen}=${state_gruen}
}

function ampel() {
  case ${1} in
    1)
      echo "Ampelphase rot"
      state_rot=1
      state_gelb=0
      state_gruen=0
      setPins
      sleep 5
      ;;
    2)
      echo "Ampelphase rot/gelb"
      state_rot=1
      state_gelb=1
      state_gruen=0
      setPins
      sleep 1
      ;;
    3)
      echo "Ampelphase grün"
      state_rot=0
      state_gelb=0
      state_gruen=1
      setPins
      sleep 3
      ;;
    4)
      echo "Ampelphase gelb"
      state_rot=0
      state_gelb=1
      state_gruen=0
      setPins
      sleep 2
      ;;
  esac
}

for phase in 1 2 3 4 1; do
  ampel "${phase}"
done

resetPins

die for Schleife läuft über eine Liste der Zustände, mittels case werden die für jeden Zustand relevanten Pins gesetzt.

Das Script schaltet einmal die Phasen „rot“,“rot/gelb“, „grün“, „rot“ durch. Mit der resetPins Funktion werden am Scriptende alle LEDs wieder abgeschaltet. Um einen Dauerbetrieb der Ampel zu bewerkstelligen, könntest du die for Schleife in eine while true; do Schleife schachteln.

manuelle Steuerung

Ich möchte in diesem Post auch eine manuelle Steuerung der Ampel implementieren. Dazu setze ich whiptail ein. Ein Programm, mit dessen Hilfe du textbasierte Nutzeroberflächen (TUI) in der Shell erzeugen kannst.

Du solltest mit

which whiptail

prüfen, ob whiptail auf deinem Raspberry Pi installiert ist. Falls nicht, kannst da das mit

sudo apt install whiptail -y

nachholen. Ich habe das Programm unter Raspberry Pi OS, Armbian (auch unter RISC) und DietPi OS bereits installiert vorgefunden. Vermutlich wird es von raspi-config oder anderen Programmen benutzt.

raspithek.de - Olli Graf
which-whiptailCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Die Ausgabe zeigt, whiptail ist in /usr/bin vorhanden.

Mit whiptail lässt sich ohne viel Aufwand eine einfache Oberfläche für die manuelle Steuerung realisieren.

#! /usr/bin/bash

pin_rot=17     # z.B. Pin 11 (BCM 17)
pin_gelb=27    # z.B. Pin 13 (BCM 27)
pin_gruen=22   # z.B. Pin 15 (BCM 22)

state_rot=0
state_gelb=0
state_gruen=0

gpiochip="gpiochip0"

function resetPins() {
  echo "Ampel aus"
  gpioset "${gpiochip}" ${pin_rot}=0 ${pin_gelb}=0 ${pin_gruen}=0
}

function setPins() {
  echo "rot=${state_rot} gelb=${state_gelb} grün=${state_gruen}"
  gpioset "${gpiochip}" ${pin_rot}=${state_rot} ${pin_gelb}=${state_gelb} ${pin_gruen}=${state_gruen}
}

installed=$(command -v whiptail)
if [ -z "${installed}" ]; then
  echo "whiptail muss installiert sein und im PATH liegen!"
  exit 5
fi


while true
do
  AUSWAHL=($(whiptail --title "Ampelsteuerung" --checklist "manuelle Steuerung" 25 75 3 \
  "RED" "Rot " ${state_rot} \
  "YELLOW" "Gelb " ${state_gelb} \
  "GREEN" "Grün " ${state_gruen} 3>&1 1>&2 2>&3))

  RETURNCODE=$?

  if [ ${RETURNCODE} -ne 0 ]; then
    echo "Abgebrochen – Programm wird beendet."
    resetPins
    break
  fi
  echo "AUSWAHL=${AUSWAHL[@]}"

  state_rot=0
  state_gelb=0
  state_gruen=0
  for farbe in "${AUSWAHL[@]}"; do
    farbe_clean=$(echo "$farbe" | tr -d '"')
    echo "aktuelle farbe=${farbe}"

    case ${farbe_clean} in
      "RED")
         echo "setze State rot"
         state_rot=1
         ;;
      "YELLOW")
         echo "setze State gelb"
         state_gelb=1
         ;;
      "GREEN")
         echo "setze State grün"
         state_gruen=1
         ;;
   esac
  done
  setPins
done

Der Kern des Scripts ist der Aufruf

 AUSWAHL=($(whiptail --title "Ampelsteuerung" --checklist "manuelle Steuerung" 25 75 3 \"RED" "Rot " ${state_rot} \
"YELLOW" "Gelb " ${state_gelb} \
"GREEN" "Grün " ${state_gruen} 3>&1 1>&2 2>&3))

Damit werden drei Checkboxen (eine pro LED) erzeugt, die mit der Leertaste selektiert oder deselektiert werden können.

Mit OK werden die LEDs gemäß der Auswahl ein- oder ausgeschaltet. Über Abbrechen wird das Script beendet.

Screenshot des Scripts für die manuelle Steuerung
raspithek.de - Olli Graf
manuell-screenCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Screenshot des Scripts für die manuelle Steuerung

Status einen Pins auslesen

Der Zustand eines Pins lässt sich auch auslesen, dazu existiert das Kommando gpioget. Dazu erweitere ich die Schaltung um den Taster, der die Masseschiene des Breadboards mit GPIO 23 des Raspberry Pi 5 verbinden soll.

gpioget kann nur digitale Werte auslesen. Es eignet sich nicht zum Lesen von I²C Sensoren oder ähnlichem.

Skizzierung der Verschaltung mit Button.
raspithek.de - Olli Graf
gpio-bash_SteckplatineCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Skizzierung der Verschaltung mit Button.
Schaltungsaufbau mit Button
raspithek.de - Olli Graf
raspi5-buttonCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Schaltungsaufbau mit Button

Um mir einen hardwareseitigen Pullup-Widerstand zu ersparen, konfiguriere ich Pin 23 mit Hilfe von pinctrl als Eingabepin mit Pullup-Widerstand

pinctrl set 23 pu

Analog zu gpioset existiert auch ein Kommando zum Lesen des Zustands eines Pins

gpioget gpiochip0 23

Da der Pullup-Widerstand konfiguriert ist und der Taster den Pin beim Drücken auf Masse zieht, gibt gpioget eine 1 aus, wenn der Taster nicht gedrückt ist und eine 0 im gedrückten Zustand.

Auch dazu habe ich ein kleines Script, um den Taster zu testen. Es liest in einer Endlosschleife alle drei Sekunden den Zustand von Pin 23 aus.

#! /usr/bin/bash
# File: button.sh

pin_button=23  # Button an BCM23
gpiochip="gpiochip0"

pinctrl set ${pin_button} pu # Pin 
while true; do
  gpioget ${gpiochip} ${pin_button}
  sleep 3
done
Die Ausgabe von button.sh zeigt eine 0 bei gedrücktem Taster, sonst eine 1
raspithek.de - Olli Graf
button-pressedCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Die Ausgabe von button.sh zeigt eine 0 bei gedrücktem Taster, sonst eine 1

Raspberry Pi 4

Zum Abschluss schließe ich die gesamte Schaltung noch an einen Raspberry Pi 4 an, um einen kurzen Kompatibilitätscheck durchzuführen.Da die GPIO Leiste genauso belegt ist wie beim 5er, erwarte ich keine großen Änderungen. Das gpiod Package ist auch unter DietPiOS verfügbar und kann wie oben installiert werden.

Tatsächlich ist es wie vermutet, nachdem ich die Jumperkabel am Raspi 4 angeschlossen hatte, liefen die Demoprogramme für die Ampel ohne Modifikation problemlos auch auf dem Raspberry Pi 4. Nur das Programm für den Button beschwerte sich, dass das pinctrl Kommando nicht verfügbar ist. Das ist kein Wunder, denn es ist nicht im offiziellen Repository vorhanden.Mit etwas Suche habe ich den Quellcode von pinctrl gefunden und ihn selbst compiliert. Zunächst brauche ich diese Hilfsprogramme:

sudo apt install cmake device-tree-compiler libfdt-dev git -y

Dann habe ich das Repository von pinctrl gecloned

git clone https://github.com/raspberrypi/utils.git
cd utils

Mit drei einfachen Aufrufen konnte ich pinctrl jetzt aus dem Quellcode bauen und installieren.

cmake .
make
sudo make install

Jetzt laufen alle GPIO Demos auch unter DietPi OS auf dem Raspberry Pi 4.

Schreibe einen Kommentar

Insert math as
Block
Inline
Additional settings
Formula color
Text color
#333333
Type math using LaTeX
Preview
\({}\)
Nothing to preview
Insert
Creative Commons License
Except where otherwise noted, the content on this site is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Olli Graf - raspithek.de
WordPress Cookie Hinweis von Real Cookie Banner