Powerbutton nachrüsten

PowerButton_214Der Powerbutton vereinfacht das Herunterfahren, bzw. Neustarten des ODROID-C1+ (Partnerlink) erheblich. Leider besitzt der Einplatinen Computer keinen von Haus aus also Rüsten wir ihn nach! Der Vorteil ist, wenn man ihn öfters herunterfährt, eine Vereinfachung und Zeitersparnis, da man sich nicht erst über SSH einloggen muss. Das Programm welches das Herunterfahren durchführt ist in C geschrieben und verwendet die wiringPi Bibliothek. Ursprünglich wurde die Bibliothek für den Raspberry Pi geschrieben. Sie wurde für den Odroid C1 angepasst und kann so wie für den Raspberry Pi verwendet werden. Um zu sehen was gerade geschieht(Herunterfahren bzw. Neustart) wird eine LED nachgerüstet. Für den Anschluss des Tasters(Powerbutton) und der LED werden die GPIOs des Odroid C1 verwendet.




 


Kurzzusammenfassung

  • Powerbutton und LED nachrüsten
  • wiringPi installieren
  • C-Programm schreiben
  • Programm automatisch starten




Benötigte Teile:

Bauteil Firma Bestellnummer Stück Preis
LED rot, 3mm, 2mA Reichelt LED 3MM 2MA RT 1 0,08€
Widerstand 1KOhm Reichelt METALL 1,00K 1 0,08€
Taster Reichelt T 113A RT 1 0,45€
Buchsenleiste 1×20 Polig Reichelt BL 1X20G8 2,54 2 0,26€

 




 


Powerbutton und LED nachrüsten

Als Powerbutton habe ich einen Taster (S1) verwendet der auf Knopfdruck den Kontakt schließt und damit High-Pegel auf den Eingang legt. Ist er geöffnet sorgt der im Odroid zugeschaltete Pulldownwiderstand dafür das am Eingang Low-Pegel anliegt. Als Spannungsversorgung für den Schalter habe ich den Pin 1 (3,3V) von der 40poligen Steckerleiste genommen. Der Eingangist Pin 11, dies entspricht GPIO 0 in der wiringPi Bibliothek. Die LED (P1) ist mit dem Widerstand (R1) von 1 KOhm an Pin 12(Ausgang) angeschlossen. Pin 14(GND) ist die Masseverbindung für die LED (P1). Wird dem Ausgang im Programm High-Pegel zugeordnet leuchtet sie, bei Low_pegel ist sie aus. Beim Anschluss der LED ist auf die richtige Polung zu achten, gegebenenfalls einfach ausprobieren! Der Schalplan ist unten zu sehen, darunter die Pinbelegung des Odroid C1 und die Zuordnung in der wiringPi Bibliothek.

Schaltplan Powerbutton und LED

Pinbelegung Odroid C1

Zum Anschluss des Tasters und der LED an die 40polige Stiftleiste habe ich 1x4Polige Buchsenleisten genommen. Diese hatte ich verfügbar. Besser ist es die oben vorgestellten 1x20Poligen Buchsenleisten zu verwenden. An diese habe ich die LED und den Taster gelötet, die Lötstellen mit Schrumpfschlauch überzogen. Dies ist auf dem unteren Bild gut zu erkennen. Viel Erfahrung braucht man nicht, wichtig ist das man nur die Anschlüsse verbindet die man nutzen möchte und das das Lötzinn gut verläuft.




 


WiringPi installieren

Nun installieren wir erstmal die vom C-Programm verwendete Bibliothek wiringPi. Dazu laden wir die benötigte Datei mit folgendem Befehl herunter:

git clone https://github.com/hardkernel/wiringPi

Dann wechseln wir in den Ordner der durch den Befehl automatisch angelegt wurde:

cd wiringPi

und kompilieren anschließend die benötigten Dateien:

./build

Damit ist hier schon alles gemacht!




 


C-Programm erstellen:

Ich habe ein Programm in C geschrieben welches den Taster im 100ms Takt abfragt. Wird der Taster kurz gedrückt (100ms bis 2900ms), dann wird der Odroid heruntergefahren, wird er länger gedrückt, startet der neu. Dies wird durch die LED angezeigt:

  • kurzes Blinken: Odroid fährt herunter
  • leuchtet dauerhaft: Odroid startet neu

Nun zum Programm! Ich habe bei mir einen Ordner angelegt in dem ich alle selbst geschriebenen Programme speichere. Dies macht man mit folgendem Befehl:

mkdir c_programme

Dann wechselt man in den Ordner:

cd c_programme

Zum Anlegen des Programms erstellen wir eine neue Datei mit nano, ich habe sie powerbutton.c genannt:

nano powerbutton.c

Hier folgendes reinkopieren:

//WiringPi-Api einbinden
#include <wiringPi.h>
//Standard-Input-Output-Funktionen einbinden
#include <stdio.h>
//C Standard-Bibliothek einbinden
#include <stdlib.h>

//Abfrageintervall des Tasters = 100ms
#define POLLINTERVALL 100
//Zeit ab der ein Neustart durchgeführt werden soll = 3000ms
#define DELAYREBOOT 3000/POLLINTERVALL
//Zeit die die LED leuchtet wenn der Odroid heruntergefahren wird = 100ms
#define TIMESHUTDOWNLED 300

int main()
{
   int timerReboot = 0;
   // Starte die WiringPi-Api
   if (wiringPiSetup() == -1)
   return 1;

   //Konfiguration der Ein- und Ausgänge
   pinMode(0, INPUT);
   pinMode(1, OUTPUT);
   pullUpDnControl(0, PUD_DOWN);
   digitalWrite(1, 0);

   // Dauerschleife
   while(1)
   {
      //Wert vom Taster einlesen
      int shutdownbutton = digitalRead(0);

      //Wenn Taster nicht geschlossen dann:
      if(shutdownbutton==0 && timerReboot>0 && timerReboot<DELAYREBOOT)
      {
         //LED kurz aufleuchten lassen
         digitalWrite(1, 1);
         delay(TIMESHUTDOWNLED);
         digitalWrite(1, 0);
         //Odroid herunterfahren
         system("shutdown -P now");
      }

      //wenn Taster geschlossen dann:
      if(shutdownbutton==1)
      {
         timerReboot++;
         if(timerReboot>=DELAYREBOOT)
         {
            //LED einschalten
            digitalWrite(1, 1);
            //Odroid herunterfahren
            system("shutdown -r now");
         }
      }
      delay(POLLINTERVALL);
   }
}

Jetzt mit “alt+x” nano beenden und die Datei abspeichern, anschließend wird die gerade erstellte Datei mit folgendem Befehl kompiliert:

gcc powerbutton.c -o powerbutton -lwiringPi



 


Programm automatisch im Hintergrund starten

Das eben erstellte Programm ist lauffähig und man kann es mit folgendem Befehl starten:

sudo ./powerbutton

drückt man nun den Taster reagiert der Odroid entsprechend. Beenden des Programms durch drücken von “alt+c” falls Rechner noch nicht am Herunterfahren ist 😉 Damit man das Programm nicht immer von Hand starten muss wollen wir es beim Systemstart ausführen und im Hintergrund laufen lassen. Dies macht man beim Archlinux mit dem Init-Sytem systemd, die Schritte die dafür notwendig sind zeige ich hier.

Als erstes in den Ordner wechseln in dem man als Benutzer eigene Services hinterlegen kann:

cd /etc/systemd/system/

Jetzt eine Textdatei mit dem Editor nano erstellen:

sudo nano powerbutton.service

Dort folgendes eintragen:

[Unit]
Description=LEDs blinken lassen

[Service]
ExecStart=/home/arch/c_programme/powerbutton

[Install]
WantedBy=multi-user.target

Anschließend nano beenden und die Datei abspeichern.

Damit die Datei beim Systemstart ausgeführt wird und darüber das Shutdownprogramm startet, muss folgender Befehl ausgeführt werden:

sudo systemctl enable powerbutton

Anschließend starten wir das Programm von Hand, dies wird beim nächsten mal automatisch durchgeführt:

sudo systemctl start powerbutton

Nun ist der Powerbutton betriebsbereit und man kann ihn gleich mal ausprobieren! Hier geht es jetzt weiter zum Anschluss und zur Einrichtung einer externen Festplatte um mehr Speicherplatz für Mediendateien zu haben!




 

10 Antworten

  1. Alex sagt:

    Ich versuche es gerade auf einen Odroid C2 zum Laufen zu kriegen, aber im neuesten Ubuntu 18.04.3 LTS mit Kernel 3.16.72-46 (aarch64) geht’s nicht:

    root@odroid:~/src/c_program/new# gcc powerbutton.c -o powerbutton -lwiringPi
    powerbutton.c: In function ‘main’:
    powerbutton.c:40:10: warning: implicit declaration of function ‘system’ [-Wimplicit-function-declaration]
    system(“shutdown -P now”);
    ^~~~~~
    /usr/lib/gcc/aarch64-linux-gnu/7/../../../../lib/libwiringPi.so: undefined reference to `pthread_join’
    /usr/lib/gcc/aarch64-linux-gnu/7/../../../../lib/libwiringPi.so: undefined reference to `pthread_create’
    /usr/lib/gcc/aarch64-linux-gnu/7/../../../../lib/libwiringPi.so: undefined reference to `pthread_cancel’
    collect2: error: ld returned 1 exit status

    Was muss ich da machen?

  2. joeko sagt:

    hmm,
    beim c2 funktioniert das nicht.habe diese Fehlermeldung
    powerbutton.c: In function ‘main’:

    powerbutton.c:40:10: warning: implicit declaration of function ‘system’ [-Wimplicit-function-declaration]

    system(“shutdown -P now”);

    ^
    /tmp/ccANliFW.o: In function `main’:

    powerbutton.c:(.text+0xc): undefined reference to `wiringPiSetup’

    powerbutton.c:(.text+0x28): undefined reference to `pinMode’

    powerbutton.c:(.text+0x34): undefined reference to `pinMode’

    powerbutton.c:(.text+0x40): undefined reference to `pullUpDnControl’

    powerbutton.c:(.text+0x4c): undefined reference to `digitalWrite’

    powerbutton.c:(.text+0x54): undefined reference to `digitalRead’

    powerbutton.c:(.text+0x88): undefined reference to `digitalWrite’

    powerbutton.c:(.text+0x90): undefined reference to `delay’

    powerbutton.c:(.text+0x9c): undefined reference to `digitalWrite’

    powerbutton.c:(.text+0xd8): undefined reference to `digitalWrite’

    powerbutton.c:(.text+0xec): undefined reference to `delay’

    collect2: error: ld returned 1 exit status

    kann mir da jemand tips geben ?

    • Hallo, hast du noch Probleme mit dem Programm?

      Ich habe das gerade mal ausprobiert und bei mir hat es funktioniert. Die Warnung beim Kompilieren bekomme ich auch (powerbutton.c:40:10: warning: implicit declaration of function ‘system’…), mehr Meldungen gab es bei mir nicht.

      Ist die wiringPi richtig installiert? Ich habe es in der Reihenfolge ausgeführt wie es auch auf der Webseite beschrieben ist. Auf dem Odroid C2 habe ich ArchLinux laufen.

      Gruß, Mathias

  3. Pascal S. sagt:

    Hey, echt eine top sache, kann ich das auch irgendwie bei Android umsetzen ?

    LG

    • Sorry, ich habe mit Android noch nichts gemacht, kann daher nichts konkretes zu sagen
      Ich würde aber einfach mal vermuten das es damit auch möglich ist. Wichtig wäre erstmal zu schauen ob man an die Ein-/Ausgänge kommt. Das dann anschließend in ein Programm zu packen ist dann bestimmt möglich.

  4. Tom sagt:

    Hi, echt ein schönes Script, das du da entwickelt hast. Habe versucht, es in meinem C1+ mit Odrobian zum laufen zu bringen. Der Rechner schmeisst mich bei Knopfdruck jedoch nur aus dem System u. fährt den Rechner nicht herunter. Hast du einen Tipp, was ich checken könnte?

    • Könnte ein Problem mit den Rechten sein. Unter welchen Benutzer startest du das Script? Probier doch mal das Script als Root zu starten.

      Hast du den Befehl der ausgeführt werden soll mal ausprobiert ohne das Script zu starten, also einfach in der Konsole?

      • Tom sagt:

        Hi Mathias, wie recht du hast. Als root gestartet u. jetzt in rc.local eingetragen läuft es auch unter Debian fein.
        Könnte man die LED beim Shutdown irgendwie für einige Sekunden blinken lassen (z.B. über den digitalWrite Befehl)?

        • Hey Tom, freut mich das es jetzt bei dir läuft.

          Das Blinken ist kein großes Problem. Einfach folgendes, anstatt dem Code hinter “//LED kurz aufleuchten lassen” mehrfach hintereinander in das Sript hineinkopieren:

          digitalWrite(1,1);        //LED Ein
          delay(TIMESHUTDOWNLED);    //Zeit die die LED an sein soll
          digitalWrite(1,0);        //LED Aus
          delay(TIMESHUTDOWNLED);    //Zeit die die LED aus sein soll
          

          Den Wert für “TIMESHUTDOWNLED” kannst du oben im Code anpassen, oder einfach durch eine Zahl ersetzen. Es ist eine Zeitangabe in ms.

          Als alternative, z.B. wenn du die LED länger blinken lassen möchtest, bietet sich ein “for” Schleife an. Diese wiederholt die Anweisungen die darunter stehen.

          Das müsste dann so aussehen, ohne es getestet zu haben:

          for(int i = 0;i<10;i++){
               digitalWrite(1,1);        //LED Ein
               delay(TIMESHUTDOWNLED);    //Zeit die die LED an sein soll
               digitalWrite(1,0);        //LED Aus
               delay(TIMESHUTDOWNLED);    //Zeit die die LED aus sein soll
          }
          

          Die 10 ist die Anzahl wie oft die LED blinken soll. Diese dann anpassen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert