Raspberry Pi – Poskramiamy diody na płytce ;)

Po zrobieniu do mojej malinki przycisku, którym mogę sobie ją wyłączyć, lub zrestartować stwierdziłem, że czegoś mi jednak brakuje. Nie wiedziałem kiedy system na komputerku będzie już gotowy do użytkowania i w ciemno próbowałem się łączyć przez PUTTY, które często nie mogło połączyć się z rapberry (no bo jak, skoro się jeszcze nie uruchomiło), co przy częstych restartach stało się trochę denerwujące. Pomyślałem sobie, że fajnie by zasygnalizować gotowość systemu do pracy np. diodą. Nie chcąc dokładać kolejnego kolejnego elementu na złącza GPIO postanowiłem sprawdzić, czy da się przejąć kontrolę nad diodami znajdującymi się na płytce (ACT oraz PWR) i o tym właśnie będzie dzisiejszy artykuł :)

Wszystkie czynności wykonuję na Raspberry Pi 2 Model B. Nazwy jak i dostępność poszczególnych LEDów mogą się różnić, także jeżeli ktoś posiada inny model to prosiłbym o feedback w komentarzu :)

Sprawdzamy jakimi diodami możemy sterować

Aby sprawdzić które diody możemy kontrolować należy wylistować zawartość katalogu /sys/class/leds.

Najlepiej wszystkie czynności wykonywać jako root w tym przypadku (nie poprzez polecenie sudo przed właściwą komendą), w tym celu najpierw wpisujemy do konsoli:

sudo su

Po wpisaniu hasła, będziemy zalogowani jako root. Aby opuścić ten tryb należy wpisać w konsolę

exit

Ok, skoro jesteśmy już rootem to możemy sprawdzić te ledy:

ls /sys/class/leds

U mnie wynikiem tego polecenia jest

root@raspberrypi:/home/krupson# ls /sys/class/leds
led0  led1

Zatem mogę sterować dwiema diodami:

  • led0 – zielona dioda, podpisana na płytce ACT
  • led1 – czerwona dioda, podpisana PWR

Zmiana „wyzwalacza”

Najpierw sprawdźmy jaką aktualnie funkcję pełni dioda zielona, wpisujemy w tym celu w konsoli

cat /sys/class/leds/led0/trigger

W odpowiedzi powinniśmy dostać listę dostępnych „wyzwalaczy”, oraz ten aktualnie używany objęty w kwadratowy nawais.

none kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock timer oneshot heartbeat backlight gpio cpu0 cpu1 cpu2 cpu3 default-on input panic [mmc0]

Oznacza to, że na daną diodę możemy ustawić dowolny z wylistowanych triggerów. My wybierzemy none, gdyż chcemy sami kontrolować stan diody.

echo none > /sys/class/leds/led0/trigger

Teraz możemy sami zdecydować, czy dioda ma być włączona czy też nie wpisując 0 lub 1 do pliku /sys/class/leds/led0/brightness (tak naprawdę 0-255, ale kontrolowanie jasności nie działa, więc już wpisanie tam wartości 1 zaświeci diodę z pełną jasnością).

# Wlaczamy diode
echo 1 > /sys/class/leds/led0/brightness

# Wylaczamy diode
echo 0 > /sys/class/leds/led0/brightness

Analogicznie możemy postąpić z diodą led1. Warto pobawić się triggerami, może znajdziemy coś co da nam więcej informacji o malince niż tylko świecąca non stop dioda zasilania.

Ciekawym modułem jest heartbeat. Nie spełnia on żadnej praktycznej funkcji, ale fajnie wygląda (<suchar>możemy wręcz tchnąć trochę życia w raspberry</suchar>).

Przeróbmy powerbtn.sh

Skoro już wiemy jak sterować diodami możemy przerobić nasz skrypt powerbtn.sh lub stworzyć nowy serwis, którego jedynym zadaniem będzie informowanie o gotowości malinki do pracy. Ja postanowiłęm przerobić to co już mam.

Watiant 1

Pierwszym moim pomysłem było zamiganie diodami na przemian kilka razy, a następnie powró do ich domyślnych funkcji. Aby to zrobić należy dopisać na początku pliku linijkę

import os

, a następnie zaraz pod zmiennymi SHUTDOWN_PIN oraz LONG_PRESS_TIME_IN_SECONDS wpisać

os.system("echo none >/sys/class/leds/led0/trigger")
os.system("echo none >/sys/class/leds/led1/trigger")
for x in range(5):
        os.system("echo 1 >/sys/class/leds/led0/brightness")
        os.system("echo 0 >/sys/class/leds/led1/brightness")
        time.sleep(0.2)
        os.system("echo 0 >/sys/class/leds/led0/brightness")
        os.system("echo 1 >/sys/class/leds/led1/brightness")
        time.sleep(0.2)
os.system("echo mmc0 >/sys/class/leds/led0/trigger")
os.system("echo input >/sys/class/leds/led1/trigger")

Wariant 2

Później wpadłm na ciekawszy pomysł. Można przecież zamienić diody czerwoną oraz zieloną funkcjami. Daje nam to przynajmniej dwie korzyści jednocześnie:

  • Kiedy system jest gotowy do użytku zielona dioda świeci się ciągle na zielono, a czerwona sygnalizuje operacje IO z kartą pamięci. Jeżeli wyłączymy malinkę dioda czerwona wróci do swojej pierwotnej funkcji, czyli będzie świecić ciągle dopóki nie odłączymy zasilania.
  • Nie sposób przeoczyć tego, że nasza malina już się uruchomiła (w przeciwieństwie do wariantu 1).

Przypisanie domyślnej funkcji (input) diody czerwonej do diody zielonej nie poskutkowało tak jakbym chciał (dioda nie świeci), dlatego postanowiłem nie przypisywać jej żadnej funkcji i ręcznie wpisać jej jasność = 1.

W tym celu tak jak w poprzednim kroku importujemy bibliotekę ok

import os

i pod zmiennymi dopisujemy takie oto linijki:

os.system("echo none >/sys/class/leds/led0/trigger")
os.system("echo 1 >/sys/class/leds/led0/brightness")
os.system("echo mmc0 >/sys/class/leds/led1/trigger")

Teraz możemy zapisać skrypt i uruchomić ponownie malinkę :) Od teraz wystarczy na nią spojrzeć i już wiadomo, czy jest włączona.

PS. Gdybyście chcieli sprawdzić jak napisane są te wszystkie moduły do kernela sterujące diodą to ich kod źródłowy można znaleźć tutaj: https://github.com/raspberrypi/linux/tree/rpi-4.9.y/drivers/leds/trigger

Zapaleńcy niskopoziomowego programowania mogą w ten sposób napisać własny moduł, który wysteruje diodę według ich uznania.