RPi stromlos schalten
Verfasst: 7. Mär 2022 20:26
Hallo,
da ich hier schon oft Hilfe gefunden habe, möchte ich auch mal etwas helfen. Vielleicht kann es ja jemand gebrauchen.
Für ein Projekt benötige ich einen Raspberry Zero, der per Tastendruck ein- und ausgeschaltet werden soll. Beim Ausschalten soll er dabei zunächst heruntergefahren werden, bevor der Strom abgeschaltet wird. Dazu gibt es Schaltungen oder auch Hats z.B. von Pimoroni. Zum einen benutze ich schon aber schon ein Hat, zum anderen benötige ich fast alle restlichen GPIOs.
Langer Rede kurzer Sinn: Meine Schaltung kommt mit einem GPIO aus, benötigt lediglich zwei Kleinrelais - und eine über Openhab (o.ä.) schaltbare Steckdose. In der Steckdose (bei mir eine mit Tasmota) steckt das Steckernetzteil des RPi, dessen Zuleitung aufgetrennt wurde, um an die Stromversorgung zu gelangen.
Funktionsweise:
Nach Betätigung des Tasters T1 fließt der Strom kurzzeitig über Relais R2, welches den Kontakt K2 schließt. Dies bleibt jedoch ohne Wirkung, da der RPi gerade erst hoch fährt. Den Strom dazu erhält er zunächst über die Diode D1, später über den Selbsthaltekontakt K1 des Relais R1, welches ebenfalls über den Tastendruck gestartet wurde.
Bei erneutem Tastendruck schließt wieder R2 mit K2. Diesmal führt das Setzen des GPIO-Eingangs zum Auslösen zweier Ereignisse. Zum einen wird der RPi herunter gefahren. Vorher jedoch setzt er eine Variable in Openhab, deren zugehörige Regel 10 Sekunden später die Schaltsteckdose ausschaltet (RPI wird stromlos und Relais R1 fällt ab) und kurz danach wieder einschaltet.
Das C-Scriptwird mit übersetzt und beim muss beim Einschalten automatisch gestartet werden.
Wie man sieht, wird bei mir der GPIO 3 benutzt und bei einem langen Tastendruck wird ein Reboot durchgeführt, anstatt das Ausschalten zu veranlassen. Meine Openhabvariable heisst "iRadio" und die zugehörige Regel lautet:
Klappt bei mir bestens ...
da ich hier schon oft Hilfe gefunden habe, möchte ich auch mal etwas helfen. Vielleicht kann es ja jemand gebrauchen.
Für ein Projekt benötige ich einen Raspberry Zero, der per Tastendruck ein- und ausgeschaltet werden soll. Beim Ausschalten soll er dabei zunächst heruntergefahren werden, bevor der Strom abgeschaltet wird. Dazu gibt es Schaltungen oder auch Hats z.B. von Pimoroni. Zum einen benutze ich schon aber schon ein Hat, zum anderen benötige ich fast alle restlichen GPIOs.
Langer Rede kurzer Sinn: Meine Schaltung kommt mit einem GPIO aus, benötigt lediglich zwei Kleinrelais - und eine über Openhab (o.ä.) schaltbare Steckdose. In der Steckdose (bei mir eine mit Tasmota) steckt das Steckernetzteil des RPi, dessen Zuleitung aufgetrennt wurde, um an die Stromversorgung zu gelangen.
Funktionsweise:
Nach Betätigung des Tasters T1 fließt der Strom kurzzeitig über Relais R2, welches den Kontakt K2 schließt. Dies bleibt jedoch ohne Wirkung, da der RPi gerade erst hoch fährt. Den Strom dazu erhält er zunächst über die Diode D1, später über den Selbsthaltekontakt K1 des Relais R1, welches ebenfalls über den Tastendruck gestartet wurde.
Bei erneutem Tastendruck schließt wieder R2 mit K2. Diesmal führt das Setzen des GPIO-Eingangs zum Auslösen zweier Ereignisse. Zum einen wird der RPi herunter gefahren. Vorher jedoch setzt er eine Variable in Openhab, deren zugehörige Regel 10 Sekunden später die Schaltsteckdose ausschaltet (RPI wird stromlos und Relais R1 fällt ab) und kurz danach wieder einschaltet.
Das C-Script
Code: Alles auswählen
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#define DEBUG
// benutzer GPIO
#define PIN_PRG_POWER RPI_V2_GPIO_P1_05 //GPIO 03
int pbdown = 0;
struct timeval tbegin, tend;
int main(int argc, char **argv)
{
if (!bcm2835_init()) return 1;
// Pin als Eingang setzen , mit Pull-Up
bcm2835_gpio_fsel(PIN_PRG_POWER, BCM2835_GPIO_FSEL_INPT); bcm2835_gpio_set_pud(PIN_PRG_POWER,BCM2835_GPIO_PUD_UP);
// Endlosschleife
while (1)
{
// Zustand am GPIO einlesen
uint8_t val_prg_power = bcm2835_gpio_lev(PIN_PRG_POWER);
// Länge des Tastendruck messen
if ((val_prg_power == 0) && (pbdown == 0)) {
pbdown = 1; // Taste gedrückt ...
gettimeofday(&tbegin, 0);
}
if ((val_prg_power == 1) && (pbdown == 1)) {
pbdown = 0; // ... und wieder losgelassen
gettimeofday(&tend, 0);
long seconds = tend.tv_sec - tbegin.tv_sec;
long microseconds = tend.tv_usec - tbegin.tv_usec;
double elapsed = seconds + microseconds*1e-6;
if (elapsed > 2.0) { // bei langem Tastendruck wird lediglich ein Reboot durchgeführt
system("sudo reboot");
} else {
system("curl -s 'http://192.168.2.222:8080/basicui/CMD?iRadio=OFF'");
system("sudo poweroff");
}
}
delay(50);
}
return 0;
}
Code: Alles auswählen
sudo gcc rpi.c -o gpiod -lbcm2835
Wie man sieht, wird bei mir der GPIO 3 benutzt und bei einem langen Tastendruck wird ein Reboot durchgeführt, anstatt das Ausschalten zu veranlassen. Meine Openhabvariable heisst "iRadio" und die zugehörige Regel lautet:
Code: Alles auswählen
rule "iRadio ausschalten"
when
Item iRadio received command OFF
then
Thread::sleep(10000)
Steckdose_2.sendCommand(OFF)
Thread::sleep(2000)
Steckdose_2.sendCommand(ON)
iRadio.postUpdate(ON);
end