12.October 2024    
   homeProjekteRaspberry PiRaspbian-Shutdown-Key

 

Hobby 234x60
reichelt elektronik – Elektronik und PC-Technik
Seite zuletzt geändert: 12.04.2013 21:02

Raspberry Pi mit externem Shutdown-Key

Es kommt immer mal vor, dass man für den Raspberry einen simplen Knopf für den Shutdown benötigt, bei welchem nicht gleich einfach der Strom weggenommen wird (wer das schon ab und zu mal absichtlich oder unabsichtlich gemacht hat, weiß, welche Folgen das für die SD-Karte haben kann).

Daher habe ich diese kleine "quick-and-dirty"-Lösung entwickelt.

Benötigt wird die nebenstehende externe Beschaltung aus

  • Pull-Up-Widerstand zur internen Betriebsspannung von 3,3V (am Connector an Pin 1 abgreifbar)
  • Taster nach Masse (z.B. an Pin 6 verfügbar)
  • Verbindung zu einem GPIO-Port, z.B. GPIO8 (Pin 24) über einen Sicherheitswiderstand von 330 Ohm (dieser, um zu verhindern, dass bei einem versehentlichen Schalten des GPIO als Ausgang mit H-Pegel und gleichzeitigem Betätigen des Tasters der GPIO zerstört wird - Danke an Dieter!)

Auf dem System läuft dann die Software (Link zum Paket siehe weiter unten, Sourcen sind mit im Paket enthalten), die für den gewählten GPIO-Port Interrupts aktiviert. Durch die Interrupt-Steuerung ist die Systemlast durch das Progrämmchen zu vernachlässigen. Auch der Speicher hält sich in Grenzen.

Standardmäßig ist die Software so konfiguriert, dass sie als Daemon läuft und den GPIO8 abfragt. Wer einen anderen GPIO nutzen möchte oder muss, kann das dann entweder im Source ändern und dann neu compilieren oder er gibt beim Start des Daemons einen Parameter "-g <gpionumber>" mit, wobei <gpionumber> dann NICHT der physikalische Anschluss des Steckverbinders ist, sondern die interne GPIO-Nummer. Der Standard-Port GPIO8 entspricht dem Pin 24 auf dem Steckverbinder.

Außerdem kann noch mit "-v" ein Debugging aktiviert werden, wobei das derzeit auch nicht viel mehr Informationen ausgibt (eigentlich vor allem die Werte der Parameter, mit denen das Programm dann läuft).

Und dann gibt es noch den Parameter "-D", der verhindert, dass ein fork stattfindet, so dass das Programm dann als normales Konsolenprogramm läuft.

Die Parameter lassen sich für den Einsatz eines als init.d-gestarteten Daemons auch über die Datei /etc/defaults/shutkey konfigurieren.

 

Das Programm reagiert bei einem Wechsel von "H" nach "L" auf dem gewählten GPIO-Port. Was diesen Wechsel auslöst, ist egal, anstelle eines Tasters kann also auch irgendwas anderes einen "L"-Pegel am Port erzeugen und damit einen Shutdown anstoßen.

In dem Moment, in welchem der gewünschte Interrupt auftritt, wird ein "shutdown -P now" gestartet. Wenn man etwas anderes machen will als einen Shutdown, dann muss man nur die eine betreffende Zeile im Source ändern und neu compilieren (dauert nur wenige Sekunden).

 

Der Interrupt-Teil basiert zum größten Teil auf den Ideen von Radek "Mrkva" Pilar (http://dev.mrkva.eu/rpi/). Auf dieser Seite wird auch noch der von Radek entwickelte Kernel-Patch aufgeführt. Dieser ist aber NICHT mehr separat erforderlich, bereits seit dem 30.06.2012 ist der Patch fester Bestandteil des Kernels - und damit auch die Interrupt-Unterstützung bei GPIO-Ereignissen. Für die Nutzung von Interrupts ist es also ausreichend, wenn man einen aktuellen Kernel benutzt.

 

Paket shutkey-0.0.1.tar.bz2

Installation des Pakets:

  1. Herunterladen des Pakets in ein beliebiges temporäres Verzeichnis
  2. Auspacken mit "tar -xjvf shutkey-0.0.1.tar.bz2"
  3. Wechsel in das Auspack-Verzeichnis mit "cd shutkey-0.0.1"
  4. Kopieren der Verzeichnisse direkt in die Zielverzeichnisse mit:
    cp -r etc /
    cp -r usr /
  5. Aktivierung mit "insserv shutkey"
  6. Mit "/etc/init.d/shutkey start" direkt starten und auf das Beste hoffen... ;-)
Thomas, 21-11-12 17:12:
Ich hab gelesen, das man die GPIO pins __NICHT__ per Widerstand auf (+) legen muss, sondern die Pins direkt per Schalter auf Masse legen kann ?!
stefan, 21-11-12 17:15:
Zumindest ein paar der GPIOs bieten diese Funktion an, da bin ich mir auch sicher. Ich habe nur nicht zu allen GPIOs diese Information gefunden, so dass ich sicherheitshalber den Widerstand vorgesehen habe. Ich werde mir mal die aktuellen Informationen zum Pi anschauen, vielleicht steht es da genauer drin.
stefan, 21-11-12 17:46:
Ja, es scheint zu gehen, wenn man die internen Pull-Up-Widerstände per Software aktiviert. Die sind standardmäßig aus, so dass sich ein offener Eingang ergibt. Da ich aber in dem kleinen Programm einfach direkt in die /sys/class/gpio schreibe und nicht die Bibliotheken benutze, kann ich die Pull-Up-Widerstände nicht aktivieren (scheint über das Filesystem nicht definiert zu sein). Dann braucht man die Widerstände doch. Nur auf den Pins, die für I2C benutzt werden, sind die 1,8K-Pull-Up immer aktiv.
Dieter, 14-12-12 11:16:
was ist , wenn ein anderes Program den GPIo8 auf Ausgang programmiert und dann ein reset ausgeführt wird?
Wäre ein 330Ohm in reihe zum GPIo8 nicht noch sinnvoll?
stefan, 17-12-12 19:06:
Ja, das hatte ich auch schon überlegt. Normalerweise passiert zwar sowas nicht, aber man weiß nie.
Ich mach ihn einfach mal rein... :-)
Danke!
Michael, 10-01-13 22:10:
Wie groß muss der Sicherheitswiderstand zum GPIO8 sein? Im Kommentar und in der Zeichnung sind 330 Ohm erwähnt. In der Beschreibung ist von 300 Ohm die Rede.
Ist das egal oder sollte es genau einer der beiden Widerstände sein?
stefan, 10-01-13 22:24:
Nein, ist wohl eher ein Tippfehler von mir gewesen. 330 Ohm ist schon richtig. 300 Ohm gehen aber auch. Meist liegt aber ein 330 Ohm im Standardvorrat rum. Es geht wirklich nur darum, den Strom aus dem Raspi in Richtung Masse zu begrenzen, falls man den Port versehentlich auf Ausgang programmiert, mit dem Ausgangspegel "H" versieht und dann den Reset-Taster drückt. Manche Schaltkreise haben dann eine Stromquelle als Ausgang, da kann dann in solch einem Fall nichts passieren, aber der Raspi nicht - das kann zur Zerstörung des Ports oder im Extremfall sogar zur Zerstörung des gesamten GPIO-Teils führen.
Johannes, 18-01-13 19:48:
Danke für die Anleitung und das Programm.
Funktioniert bei mir gut. Ich mußte allerdings in shutkey.c im system()-Aufruf in Zeile 185 die Option -h ergänzen.
System: Linux raspberrypi 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l GNU/Linux
Peter, 29-01-13 14:53:
Vielen Dank auch von mir.
Allerdings eine Frage als Linus Neuling habe ich noch:
Mit "insserv shutkey"nehm ich den Daemon in die Liste der zu startenden auf.
Wie entferne ich shutkey wieder?
stefan, 29-01-13 15:14:
@Peter: mit "insserv -r shutkey" nimmst Du das Startscript aus allen Runlevels wieder raus
Malte, 02-02-13 20:36:
habe auch das problem das der Raspbarry auf shutdown -P nicht reagiert. ich brauch noch nen -h dabei.

den Code im Source hab ich gefunden aber was hat das mit den compilieren auf sich?
stefan, 02-02-13 20:48:
@Malte: Das Script ist so klein und simpel, dass es ausreicht, in dem Verzeichnis, in die shutkey.c liegt, aufzurufen (siehe README):

gcc shutkey.c -o shutkey

Dann noch die neue shutkey ausführbar machen mit

chmod 755 shutkey

und die shutkey in /usr/bin überschreiben
Christian, 04-02-13 07:02:
Vielen Dank, für die genial simple Lösung.
Wenn man übrigens GPIO3 (Pin 5, bei Revision 2) statt GPIO8 nimmt, kann man mit dem Taster den Pi auch wieder starten, wenn er im "Standby" ist.
Sebastian, 08-02-13 17:15:
Hallo, würde gerne auch einen Shutdown Schalter nachbauen, aber ich weiß nicht so recht was für ein Widerstand ich kaufen soll, kann mir bitte mal jemand ein Link zu einem Pull-Up-Widerstand schicken?
MfG
Sebastian, 09-02-13 08:13:
Hallo, würde das ganze auch gerne nachbauen, kann mir bitte mal jemand ein link zu dem passenden Pull-Up-Widerstand schicken?
MfG
stefan, 09-02-13 08:17:
Hallo Sebastian,
hast Du bei Dir evtl. z.B. einen Conrad in der Nähe? Da würdest Du welche bekommen. Online lohnt sich das bei den Preisen eigentlich nicht wirklich. Da würden auch u.a. Conrad und Reichelt zur Verfügung stehen.
Bei Reichelt wären das z.B.:
http://www.reichelt.de/1-4W-5-100-Ohm-910-Ohm/1-4W-330/3/index.html?;ACTION=3;LA=2;ARTICLE=1410;GROUPID=3064;artnr=1%2F4W+330;SID=11URX3m38AAAIAADb7xJMfc12b9e0dd0fed72aa487134dd216e44 (für den 330Ohm) und
http://www.reichelt.de/1-4W-5-10-k-Ohm-91-k-Ohm/1-4W-10K/3/index.html?;ACTION=3;LA=2;ARTICLE=1338;GROUPID=3066;artnr=1%2F4W+10K;SID=11URX3m38AAAIAADb7xJMfc12b9e0dd0fed72aa487134dd216e44 (für den 10kOhm)
Johann, 12-04-13 18:15:
Hallo Stefan,

habe mich auch gerade dran gemacht, die Schaltung nachzubauen.
Leider steht in deiner Anleitung nicht dabei, wie man das Programm installiert.
Eine Schritt-für-Schritt Anleitung wäre echt genial. DANKE

Viele Grüße
Johann
stefan, 12-04-13 18:24:
Hallo Johann,
es muss nur die Archivdatei entpackt werden und die Dateien, die darin enthalten sind, in die vorgegebenen Verzeichnisse kopiert werden. Ich schreibe das aber noch in den eigentlichen Text oben, komme aber grade nicht dazu, aber in Kürze ist es dann drin.
Ciao
Stefan
stefan, 12-04-13 21:04:
erledigt
Ciao
Stefan
Johann, 15-04-13 01:37:
Danke, hat jetzt damit (fast) geklappt.
Jetzt hat die Schaltung funktioniert und das Skript wurde aufgerufen aber hat keinen shutdown bewirkt. Warum geht das mit deiner vorgefertigten Version für raspbian nicht gleich?

Musste noch folgende Änderung in der Datei /usr/src/shutkey/shutkey.c ganz unten machen: "shutdown -P now" -> "shutdown -P -h now".

Dann:
gcc /usr/src/shutkey/shutkey.c -o shutkey
chmod 755 shutkey
cp shutkey /usr/bin/shutkey

Johann
MichaelE, 19-04-13 17:12:
Hallo,
ich bin auch Linux Neuling und scheitere an dem Befehl "insserv shutkey". Auch wenn ich den Befehl mit sudo ausführe, so bekomme ich folgende Meldung " insserv: script shutkey is not an executable regular file, skipped!".

Was mache ich falsch ?

Gruß
Michael
stefan, 19-04-13 21:07:
Hallo,
ist beim Kopieren der /etc/init.d/shutkey was schiefgegangen? Ein "ls -l /etc/init.d/shutkey" sollte eine Größe von 994 Bytes ergeben und einen filemode von 755 (-rwxr-xr-x) ergeben. Ich vermute mal, dass letzteres nicht korrekt ist.
Ciao
Stefan
MichaelE, 19-04-13 22:17:
Hallo Stefan,
habe das nun kontrolliert. Zum einen wie Du richtig vermutet hast, war filemode nicht 755.
Als ich das versucht habe, war als Benutzer PI angemeldet. Nachdem ich mich nun als root angemeldet habe, geht es.
Vielen Dank für die schnelle Antwort. ECHT SPITZE.
Gruß MichaelE
paul, 26-05-13 17:50:
Hallo,
also, das Programm funktioniert bei mir nur, wenn ich vorher in einem Python-Script (das war das Skript, mit dem ich vorher per polling den shutdown ausgelöst hatte) folgendes ausgeführt hatte: (bei mir gpio11)
~~
import RPi.GPIO as GPIO
import time
import os
GPIO.setmode(GPIO.BCM)
GPIO.setup(11, GPIO.IN)
~~
also irgendwie funktioniert zwar die Aktivierung des Interrupts, nicht aber das Set des gpio - zumindest ist das meine Vermutung. Ich stecke nicht sonderlich tief in der Materie. Benötige ich für das Programm noch irgendwelche Bibliotheken?
gruß
paul
Marc, 07-06-13 15:05:
Hallo,
ich bin dabei, das nachzubauen, allerdings nicht durch einen Taster gesteuert.
Da ich den RasPi als Medienserver am Fernseher betreibe und mir dort an der USB Buchse den 'Saft' hole, soll sobald der Fernseher abgeschaltet wird, auch der RasPi runterfahren.
Also: wenn keine Versorgung mehr an der USB Buchse (von aussen) --> Trigger als "Tastendruck". Für geregeltes runterfahren müsste ein hinreichend großer Elko als 'Nachlaufversorgung' rein. Damit der 'Tastendruck' nicht durch den Elko überlagert / verhindert wird, mit einer Diode sperren. Und für den Tastendruck (Schließer) noch einen Inverter (oder kann man das in der Software ändern?)...
Hab ich was vergessen?
Gibt es Erfahrungswerte bzgl. Elko-Kapazität?
Gruß Marc
john, 14-06-13 09:33:
hi danke für das skript, es klappt bei mir jedoch nicht.
denn im syslog steht "unable to write to /sys/class/gpio/export".
skript selbst startet aber
Stefan, 14-06-13 09:36:
Hi John,
existiert die Datei und hast Du Zugriff darauf? Eventuell das Script mit den falschen Rechten gestartet?
Gruß
Stefan
john, 14-06-13 09:45:
habe die dateien entpackt mit chmod 755 alle rechte neu vergeben, danach mit ls -la nochmals geprüft und an die plätze kopiert.
mit gcc das skript neu kompiliert und shutdown -P -h eingefügt. danach in /usr/bin kopiert und die rechte nochmals vergeben.
john, 14-06-13 10:15:
ok habs problem gefunden mir haben für meinen benutzer die schreibrechte dür die gpio verzeichnisse gefehlt , hab jetzt alle dateien auf chmod 666 gestellt nun funktioniert es :)
Thorsten, 06-07-13 15:45:
Hallo,
erst einmal vielen Dank für das Skript!
Ich bin Anfänger, was den Raspberry angeht, würde aber dennoch gerne das Skript zum Laufen bekommen. Leider weiß ich nicht, wie ich nun die Fehler eingrenzen kann ...
Also ich habe geprüft, daß ich die richtige Rev habe und der Pin richtig angeschlossen ist.
Wenn ich den Pin vom Taster durchmesse, habe ich auch einen Spannungsabfall von 3,3 auf 2,9 V beim Drücken.
Im Syslog steht nur fork ok und daß er gestartet ist - sonst nichts ...
Unter sys/class ist gpio8 mit den Unterordnern angelegt
Aber beim Drücken vom Taster passiert nix :-/
Wie kann ich nun weiter vorgehen?
Vielen Dank
Thorsten
Nicolas, 20-09-13 16:43:
Hallo, danke für das Progrämmchen. Bei mir passiert beim Drücken des Tasters auch nichts. Habe das Script /etc/default/shutkey mit OPTS="-g 24" angepasst, unter /sys/class/gpio/gpio24 läßt sich "value" auch immer korrekt als 0 oder 1 auslesen, aber es passiert leider nichts.
Nicolas, 20-09-13 19:57:
Hat sich erledigt, ich brauchte einen Neu-build mit der Option "shutdown -h -P now". Super Sache! So kann man den Pi guten Gewissens als Black Box betreiben.
Dirk, 03-11-13 09:05:
Kann man durch Änderungen am C Code erreichen, dass man den Taster für eine oder zwei Sekunden drücken muss, bevor der Shutdown ausgelöst wird?
Dirk, 03-11-13 09:25:
Kann man erreichen, dass der Taster für min. 1 oder 2 Sekunden gedrückt sein muss, bevor der der Shutdown ausgelöst wird?
Kommentar hinzufügen

* - Pflichtfeld

*



*
Copyright © 2008-2017