Raspberry to wspaniały komputerek, czasami jednak brakuje możliwości łatwego zamknięcia systemu operacyjnego.
Nie zawsze mamy możliwość zalogowania się np. przez ssh i wydania komendy shutdown czy podobnej.
Pozostaje brutalne wyłączenie zasilania.
Pomocnym może być rozwiązanie, które zastosowałem w naszym systemie MiniRCP,
Centralnie umieszczony przycisk służy do przełączania pomiędzy rejestracją wejścia i wyjścia, jeśli jednak przytrzymamy go dłużej, przez 5 sekund (jak na załączonym wyżej filmiku), rozpocznie się procedura zamykania systemu.
Zakończone zostaną ważne dla nas procesy (w tym przypadku proces rejestrujący wejścia, badający trzeźwość pracowników, otwierający drzwi), rozpocznie się zamykanie systemu operacyjnego, a po 10 sekundach wyłączone zostanie podświetlenie wyświetlacza.
Nie zostanie niestety wyłączone zasilanie, wymagałoby to dodatkowego hardware, jednak poprawne zamknięcie systemu operacyjnego to już cenna rzecz.
Program, reset.c skompilować musimy z biblioteką WiringPI, a więc:
cc reset.c -o reset -lwiringPi
Wyświetlacz tym razem został podłączony przez magistralę I2C, inaczej niż opisałem w LCD .
Dzięki niewielkiemu, niedrogiemu modułowi HW-061
zamiast 8 przewodów łączących wyświetlacz z Raspberry, potrzebujemy tylko 4 (w tym zasilanie i masę).
Nasz wyświetlacz staje się też znacznie odporniejszy na zakłócenia.
Jak taki wyświetlacz podłączyć przez magistralę I2C, opiszę w najbliższym czasie, na razie, dla zrozumienia działania oprogramowania, proponuję zerknąć na schemat rejestratora MiniRCP.
No to teraz, jak to działa.
Nie będziemy omawiać procedur sterowania wyświetlaczem przez I2C, to przy innej okazji, skupimy się jedynie na głównej procedurze zamykanie systemu operacyjnego:
Ten pin wyłącznikiem astabilnym łączymy z pinem GND Raspberry:
#define WEWY 25 // connect reset switch to this pin and GNDBędziemy maskować sygnały, więc potrzebna będzie ich maska:
static sigset_t signal_mask; /* signals to block */
void main (argc, argv) int argc; char *argv[]; { .......Inicjujemy wiringPi, pin WEWY programujemy na wejście i wymuszamy na nim jedynkę logiczną aktywując rezystor 'pull-up':
// check wiringPi setup if (wiringPiSetup() == -1) { printf("wiringPi-Error\n"); exit(1); } // set reset pin to input, activate pull-up resistor pinMode (WEWY , INPUT) ; pullUpDnControl(WEWY, PUD_UP);Teraz w nieskończonej pętli co 200 milisekund sprawdzamy stan pinu WEWY. Jeśli naciśniemy wyłącznik, pojawi się na nim zero logiczne.
int state; int count; while (TRUE) { state=digitalRead(WEWY);Sprawdzamy, czy wyłącznik był naciśnięty przez 6 sekund (30 x 200 mS):
if (state == 0) // WEWY pin connected to GND { for(count=30;count>0;count--) //WEWY pin connected to GND for 5 seconds { state=digitalRead(WEWY); if(state == 1) break; Delay_ms(200); }Tu znajdziemy się po 6 sekundach nieprzerwanie naciśniętego wyłącznika:
if (state == 0) {Kończymy pracę procesu (lub kilku procesów), które chcemy poprawnie zakończyć:
system("killall pomiar"); // terminate a process sleep(1);Inicjujemy współpracę z wyświetlaczem po I2C i wyświetlamy komunikat o zamykaniu systemu:
//**** initiate LCD Display fdlcd = wiringPiI2CSetup(I2C_ADDR); lcd_init(); // setup LCD lcdLoc (0, 0) ; // set cursor at line 0, column 0 typeln ("Closing the system") ; // display some info on LCDTeraz maskujemy sygnały, żeby system operacyjny nie zakończył naszego procesu przedwcześnie:
//***** mask signals to avoid premature closure of our process sigemptyset (&signal_mask); sigaddset (&signal_mask, SIGINT); sigaddset (&signal_mask, SIGTERM); sigaddset (&signal_mask, SIGHUP); sigprocmask(SIG_BLOCK, &signal_mask, NULL);Czekamy 900 milisekund (to nie jest potrzebne) i rozpoczynamy zamykanie systemu:
Delay_ms(900); system("shutdown -h now"); // begin shutdown procedurePo 10 sekundach (w praktyce zwykle wystarczy krótszy czas, około 6 sekund) wyłączamy podświetlenie wyświetlacza LCD i kończymy nasz proces. Można wyłączyć zasilanie Raspberry:
//**** wait 10 seconds sleep_time = 10; while (sleep_time > 0) sleep_time = sleep (sleep_time); // *** turn off LCD backlight lcd_backlight = 0x00; typeln (" ") ; exit(0);