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.

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

- 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.


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.

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.

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.

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.


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

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.