Menu Zamknij

Systemowa obsługa wejść i wyjść Raspberry Pi

Cel

Nauka obsługi wejść i wyjść cyfrowych za pomocą wirtualnego systemu plików Raspbiana.

Wymagania

  • Raspberry Pi,
  • odbiornik umożliwiający obserwację stanu wyjścia, na przykład LED z odpowiednio dobranym rezystorem.

Cyfrowe wejścia i wyjścia RPi

Tabela 1 Złącze GPIO Rasperry Pi

Zagadnienia przedstawione w rozdziale Podstawy Raspberry Pi, choć niezbędne do podstawowej obsługi RPi, można przećwiczyć na komputerze z zainstalowanym dowolnym Linuxem. Siłą Raspberry Pi jest posiadanie złącza 2 × 20 GPIO (General-Purpose Input/Output – wejścia i wyjścia ogólnego przeznaczenia) zaznaczonego na rysunku 1 w rozdziale Podstawy Raspberry Pi czerwoną ramką. Numeracja GPIO nie jest zgodna z ich fizycznym położeniem, dlatego należy bardzo uważać na podłączenie, tym bardziej, że na pinach mamy wyprowadzone napięcia 5 V, a RPi pracuje w logice 0–3V3. Numerację i znaczenie poszczególnych pinów zawiera tabela 1. Orientacja względem brzegu płytki jest oznaczona czerwoną kreską.

Raspberry Pi nie posiada analogowych wejść. Potrzeba skorzystania z przetworników analogowo-cyfrowych wymusza konieczność montażu takich urządzeń poza RPi. W pierwszej kolejności należy poszukiwać czujników współpracujących od razu z sygnałami cyfrowymi. Projektując nowe układy, na początku najlepiej wykorzystywać te piny GPIO, które nie współdzielą innych funkcji. Każde z dwudziestu ośmiu GPIO może być wejściem lub wyjściem cyfrowym.

Dostęp do GPIO

Używanie wejść z poziomu powłoki bash jest dosyć proste. Powszechną koncepcją w Linuxie jest dostęp do urządzeń poprzez wirtualny system plików. W przypadku GPIO w RPi polega to na tym, że każdemu zadeklarowanemu (wyeksportowanemu do przestrzeni użytkownika) pinowi odpowiada skojarzony z nim, umiejscowiony gdzieś w strukturze katalogów, plik, przy czym nie jest to fizycznie istniejący plik tylko wirtualny. Jeżeli chcemy, by pin był wyjściem, to do pliku będziemy zapisywać dane, jeżeli pin ma być wejściem, to z pliku będziemy czytać. Ponieważ są to wejścia i wyjścia cyfrowe, to i zawartości plików będą albo 0, albo 1.

Takie rozwiązanie daje szansę na proste wykorzystanie GPIO naszego RPi w „dziwnych” językach programowania, dla których nie ma stosowanych bibliotek wspierających, ale jest możliwość zapisu i odczytu do plików. Podobnie jest z prezentowanymi tu skryptami bash. Nie jest to najlepsza metoda programowania Raspberry Pi, bo nie ma odpowiednich modułów zapewniających obsługę standardowych protokołów komunikacyjnych typowych wyświetlaczy, czujników, serwomechanizmów itp. Samo działanie typu włącz/wyłącz może nie być wystarczające. Ponadto, jeżeli nie zamierzamy pisać skryptów w bashu, chociaż podstawy na pewno mogą się przydać, to wyniesiona nauka, przez jego specyficzną składnię, będzie mało uniwersalna.

Do obsługi GPIO będą nam potrzebne uprawnienia administracyjne, najlepiej na stałe, aby uniknąć ciągłego pisania sudo.

# sudo su

Wszystkie potrzebne pliki i katalogi znajdziemy w lokalizacji /sys/class/gpio/. Na początku, dopóki nie wyeksportujemy pinu do przestrzeni użytkownika, nie mamy dostępu do żadnego wejścia/wyjścia. W katalogu /sys/class/gpio/ znajdują się dwa ważne pliki export i unexport. Nie da się z nich nic odczytać, ale można do nich zapisać numer pinu, czyniąc go dostępnym dla użytkownika. Żeby nie wypisywać ciągle pełnej ścieżki, zmieńmy katalog.

# cd /sys/class/gpio

Teraz możemy wyeksportować pin poprzez wpisanie do pliku export numeru pinu.

# echo „26” > export

Jeżeli polecenie echo przyjmuje jeden argument bez spacji, to można pominąć cudzysłów. Wyświetlana liczba i tak będzie przesłana jako tekst. W tym przykładzie wybraliśmy pin 26, bo jest łatwy do zlokalizowania i sąsiaduje z masą (GND).

Wyeksportowanego pinu będziemy używać do sterowania diodą LED jako wskaźnikiem jego stanu. Jak podłączyć diodę, można dokładnie przeczytać w uwagach z rozdziału Nauka programowania z Arduino. W przykładzie użyto diody zielonej podłączonej przez szeregowy rezystor k18. Jeżeli umiemy wysterować diodą, to z pewnością nie będzie problemu z włączaniem i wyłączaniem dowolnego odbiornika, warto jednak wrócić i przypomnieć sobie uwagę z rozdziału Zmierzchowy wyłącznik światła zaznaczoną białymi literami na czerwonym tle. Gdybyśmy chcieli używać pinu jako cyfrowego wejścia, powinniśmy zastosować rezystor podciągający zgodnie z uwagami zamieszczonymi w rozdziale Przycisk teleturniejowy.

Po wylistowaniu (ls) bieżącego katalogu można zobaczyć, że pojawił się w nim nowy podkatalog o nazwie gpio26.

# cd gpio26

Po wylistowaniu tego katalogu zobaczymy kilka plików, ale najważniejsze dwa to: direction określające, czy pin jest wejściem in (domyślnie), czy wyjściem out oraz value określające stan pinu 0 lub 1.

Na początek ustalamy, że chcemy, by pin 26 był cyfrowym wyjściem.

# echo out > direction

Teraz jeśli zapiszemy do pliku value wartość 1, sprawimy, że dioda zapali się.

# echo 1 > value

Jeśli wpiszemy do tego pliku 0, wyłączymy diodę.

# echo 0 > value

Po tej próbie, która może być dosyć efektowna, pracując zdalnie, możemy już zakończyć pracę.

# cd ..
# echo 26 unexport

Podobnie odczytamy przycisk, tyle że zamiast pisać do pliku value, należy z niego odczytywać dane.

# echo 26 > export
# echo in > gpio26/direction
# cat gpio26/value
# echo 26 unexport

Być może jest to niewiele, ale jeśli dysponujemy mikrokontrolerem i posiadamy umiejętność ustawienia odpowiedniej wartości cyfrowej wyjścia oraz odczytania wartości na wejściu, to w zasadzie można już zrobić wszystko, chociaż tylko teoretycznie.

Skrypty bash

Ciągłe wpisywanie tych samych komend w celu włączania i wyłączania odbiornika może być męczące. Na szczęście polecenia powłoki można grupować w pliku, podobnie jak opisane w rozdziale Wykresy z gnuplotem skrypty gnuplota. Umieszczone w pliku o zwyczajowym rozszerzeniu *.sh polecenia powłoki wykonywane są po kolei.

Napiszmy skrypt włączający diodę na pinie 26 na dwie sekundy. Na początek zmieńmy katalog, nie zaśmiecając systemowego /sys, najlepiej na domowy root.

# cd ~

Napisanie skryptu najkorzystniej jest przeprowadzić w jakimś edytorze.

# nano led.sh

Skrypt taki może mieć postać jak na listingu 1.

Listing 1

#!/bin/bash
path="/sys/class/gpio"
echo 26 > $path/export
echo out > $path/gpio26/direction
echo 1 > $path/gpio26/value
sleep 2
echo 0 > $path/gpio26/value
echo 26 > $path/unexport

Pierwsza linia skryptu jest informacją o środowisku uruchomieniowym, gdybyśmy ją pominęli, musielibyśmy przed wywołaniem skryptu podać nazwę interpretera. Nową rzeczą jest użycie zmiennej path jako skrótu ścieżki. Odwołujemy się do zmiennych poprzez poprzedzenie ich znakiem $. Zwyczajowo zmienne basha piszemy wielkimi literami, ale zmienna środowiskowa PATH już istnieje.

Zanim jednak będzie można użyć skryptu jak zwykłego programu, trzeba mu nadać atrybut wykonalności poleceniem chmod.

# chmod +x led.sh

Wykonanie polecenia:

# ./led.sh

spowoduje zapalenie się diody na dwie sekundy. Nie można zapomnieć o poprzedzeniu nazwy znakami ./.

Poprawmy nieco nasz skrypt, tak aby przyjmował dodatkowe parametry: jeden określający numer pinu, a drugi czas trwania świecenia (listing 2).

Listing 2

#!/bin/bash
path="/sys/class/gpio"
if [ $# -ne 2 ]
then
  echo "nieprawidłowa liczba argumetów"
  exit
else
  echo 26 > $path/export
  echo out > $path/gpio$1/direction
  echo 1 > $path/gpio26/value
  sleep $2
  echo 0 > $path/gpio$1/value
  echo 26 > $path/unexport
fi

Dostęp do zmiennych w skrypcie podawanych w powłoce po jego wywołaniu jest możliwy przy pomocy konstrukcji $numer, gdzie numer oznacza kolejny parametr. Ilość podanych parametrów dostaniemy przez korzystanie z $#. W wierszu 3 sprawdzamy, czy liczba parametrów jest odpowiednia ( -ne oznacza „nie równy”, czyli „różny”). Jeżeli tak nie jest, to dostajemy stosowny komunikat i kończymy działanie skryptu.

Wywołanie:

# ./led.sh 26 1m &

spowoduje zapalenie diody na jedną minutę. Ampersand na końcu wiersza spowoduje, że program będzie wykonywany w tle, a my dostaniemy możliwość dalszej pracy w konsoli i nie będzie potrzeby czekania na zakończenie działania skryptu.

Możemy ten skrypt wykorzystać do programowego włączania diody. Zainstalujmy najpierw program at, obecny w większości dystrybucji linuksowych, ale niezainstalowany domyślnie na Malinie.

# apt-get install at

Służy on do jednorazowego wykonywania zadań w określonym czasie. Czas względny podaje się za pomocą znaków + i . Warto podkreślić, że RPi nie posiada wbudowanego zegara, ale samo podłączenie do internetu spowoduje automatyczną synchronizację z czasem sieciowym. Za pomocą at możemy włączyć nasz skrypt za minutę na 10 sekund.

# at now + 1 minute
> ./led.sh 26 10
> ^D

Pamiętamy, że ^D oznacza <CTRL>D. Użycie at opisane jest oczywiście w podręczniku man, co może być bardzo ciekawą lekturą. Program at akceptuje bardzo różne formaty zapisu czasu, na przykład:

# at teatime

spowoduje uruchomienie zadania o 16.00. Jeśli podłączymy brzęczyk zamiast diody, otrzymamy powiadomienie dźwiękowe o przerwie na herbatkę.

Utworzenie trwałego, nie jednorazowego, alarmu herbacianego jest możliwe przy wykorzystaniu linuksowego plannera cron. Kto i na jakich zasadach może z niego korzystać, jest sprawą dosyć skomplikowaną, ale wykorzystamy posiadane uprawnienia root. Pliki harmonogramów wszystkich użytkowników znajdują się w katalogu /var/spool/cron/crontab, jednak nie powinniśmy bezpośrednio tworzyć, modyfikować ani usuwać tych plików. Do edycji tabel cron służy polecenie crontab z krótką opcją -e. Poniżej widoczne wywołanie polecenia w RPi i komunikaty po jego zatwierdzeniu.

# crontab -e
no crontab for root – using an empty one

Select an editor.  To change later, run ‘select-editor’.
1.	/bin/ed
2.	/bin/nano        <---- easiest
3.	/usr/bin/vim.tiny

Choose 1-3 [2]:

Widać, że do edycji używać będziemy, tak czy inaczej, któregoś z edytorów tekstowych. Ponieważ w Raspbianie nie mamy zdefiniowanej zmiennej środowiskowej EDITOR określającej domyślny edytor systemowy, przy uruchomieniu crontab zostaniemy poproszeni o wybranie go z listy. Używaliśmy do tej pory nano, więc wybieramy 2, chociaż nie musimy, bo jest to wybór domyślny. Jedynka jest dla prawdziwych geeków.

Po uruchomieniu edytora w liniach komentarza, poprzedzonych #, znajduje się mniej lub bardziej rozbudowany komentarz i przykłady. Umieszczenie poniżej komentarza wiersza:

00 16 * * 6,7 /root/led.sh 26 15

i zapisanie zmian spowoduje uruchomienie alarmu w każdą sobotę i niedzielę o 16.00. Znaczenie poszczególnych wpisów w tabeli cron jest następujące: godziny i minuty są odwrotnie w pierwszych dwóch polach, potem są dni w miesiącu, miesiące i dni w tygodniu, a na końcu polecenie do wykonania. Gwiazdka oznacza „wszystkie”.

Polecenie gpio

Systemowe korzystanie z wejść i wyjść RPi przedstawione powyżej może wydawać się nieco zawiłe. Projektanci Maliny, zdając sobie z tego sprawę, wyposażyli Raspbiana w dodatkowe polecenie powłoki gpio. Pozwala ono nie tylko w prosty sposób na konfigurację pinów i manipulowanie sygnałami, ale co najważniejsze, daje możliwość obsługi bez uprawnień administracyjnych. Zanim rozpoczniemy pracę, należy ustalić tryb działania pinu.

$ gpio -g mode <numer_pinu> <tryb>

Opcja -g jest konieczna dla zachowania standardowej numeracji pinów zgodnej z tabelą 1. Opcja tryb może przyjmować oprócz standardowego in i out, także między innymi: wejść up, down z wewnętrznymi rezystorami podciągającymi, pwm dla wyjść PWM oraz wfi dla przerwań. Sprzętowy PWM, a tylko taki jest dostępny poleceniem gpio, w RPi jest obsługiwany jedynie na pinach 12 i 13. Po określeniu trybu wystarczy określić działanie, podstawowym dla out jest write, a dla in/up/downread. Włączenie i wyłączenie diody na pinie 26 może wyglądać zatem następująco:

$ gpio -g mode 26 out
$ gpio -g write 26 1
$ gpio -g write 26 0

Regulacja jasności, tyle że na pinach 12 lub 13, też nie będzie trudna.

$ gpio -g mode 13 pwm
$ gpio -g pwm 13 511

Powyższe dwa polecenia włączają diodę w połowie maksymalnego natężenia. Wyjścia PWM mają 10-bitową rozdzielczość (0–1023). Zakończenie pracy najlepiej wykonać przez wykonanie:

$ gpio unexport <numer_pinu>

lub:

$ gpio unexportall

Modyfikacje

Wyposażenie w taką wiedzę pozwala na pisanie bardzo złożonych programów. Skrypty basha, pomimo swojej specyficzności, mogą realizować bardzo skomplikowane programy. Do dyspozycji mamy funkcje, pętle i warunki. Można spróbować napisać skrypt migającej diody.

Dla potrzeb plannera cron najlepiej byłoby napisać osobny skrypt eksportujący pin i włączający diodę oraz osobny wyłączający i usuwający GPIO z przestrzeni użytkownika.

Literatura

Powtórzenie zaprezentowanych projektów nie wymaga studiowania dodatkowej literatury. Dopiero wprowadzenie modyfikacji może wiązać się z koniecznością uzupełnienia wiedzy. Najlepszym źródłem informacji w przypadku jakiegoś konkretnego problemu jest internet. Książka pisana swoją wyższość ukazuje dopiero jako podręcznik czy przewodnik.

Informacje bibliograficzne dotyczące źródeł internetowych zamieściłem bezpośrednio w tekście, przy zagadnieniach, których dotyczą.

Do zapisu linków, tylko w tym spisie, wykorzystywana jest metoda skracania adresów (URL shortening). W tym skrypcie wybrano serwis TinyURL. Dostęp do wszystkich internetowych zasobów został przetestowany 27.02.2020.

Bibliografia zawiera tylko materiały pomocnicze do projektów, których dotyczą, a pominięto literaturę o charakterze ogólnoinformatycznym. Dobór materiałów do nauki kodowania, czy obsługi programów narzędziowych, pozostaje po stronie nauczyciela.

Dla Arduino i Raspberry jest po prostu ogrom literatury i różnych zasobów internetowych – także w polskim języku. Jest na rynku bardzo ciekawa książka wspólna dla obu platform, prezentująca rozwiązania problemów równocześnie dla obu modułów:

  • Monk Simon, Zrób to sam. Generowanie ruchu, światła i dźwięku za pomocą Arduino i Raspberry Pi [e-book], tłum. Konrad Matuk, Helion, 2018.

Także Raspberry Pi nie należy do urządzeń, dla których trudno o dokumentację.

Z książkowych przewodników polecam:

  • Richardson Matt, Wallace Shawn, Wprowadzenie do Raspberry Pi [e-book], tłum. Maria Chaniewska, wyd. 2, Helion, 2016.
  • Upton Eben, Halfacree Gareth, Raspberry Pi. Przewodnik użytkownika. Wydanie III [e-book], tłum. Konrad Matuk, Helion, 2015. ale gama dobrych podręczników jest naprawdę szeroka.

Literatura uzupełniająca

W niektórych projektach nie wszystko da się podłączyć za pomocą pasujących do siebie wtyków i złącz. Należy wówczas wykonać takie podłączenia samodzielnie. Wymaga to nieco umiejętności majsterkowania i elektroniki. Bardzo ciekawą książką dla początkujących majsterkowiczów jest:

  • Roberts Dustyn, Wpraw to w ruch. Proste mechanizmy dla wynalazców, majsterkowiczów i artystów [e-book], tłum. Krzysztof Sawka, Helion, 2015.

Znajdziemy w niej oprócz podstaw elektroniki także dużo elementarnej mechaniki i materiałoznawstwa.

Majsterkowanie z użyciem systemów wbudowanych, tam gdzie nie wszystko pasuje do siebie za pomocą dedykowanych styków, wymaga elementarnej wiedzy z elektroniki. Niezmiennie najważniejszą książką na półce elektronika jest:

  • Horowitz Paul, Hill Winfield, Sztuka elektroniki, tłum. Bogusław Kalinowski, Grażyna Kalinowska, t. 1–2, wyd. 12 zmienione, WKŁ, Warszawa 2018.

Jednakże jest to pozycja dla wymagającego czytelnika. Podobnym standardem, ale skierowanym do początkujących jest:

  • Platt Charles, Elektronika. Od praktyki do teorii. Wydanie II [e-book], tłum. Konrad Matuk, Helion, 2016.

Na uwagę zasługuje ponadto, w moim przekonaniu bardzo dobra, książka polskiego autora:

  • Górecki Piotr, Wyprawy w świat elektroniki, t. 1, WKŁ, Warszawa 2006.
  • Górecki Piotr, Wyprawy w świat elektroniki. Wyższy stopień wtajemniczenia, t. 2, WKŁ, Warszawa 2011.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *