Kurs Raspberry Pi – #12 – podstawy GPIO, skrypty

Kurs Raspberry Pi – #12 – podstawy GPIO, skrypty

Za nami ćwiczenia z kamerą podłączaną do RPi. Czas na najciekawszy temat z punktu widzenia wszystkich elektroników.

Porty GPIO pozwalają na sterowanie praktycznie dowolnymi urządzeniami. Zacznijmy od prostych poleceń sterujących wyjściami Raspberry Pi.

Dawniej wszystkie książki o programowaniu rozpoczynały się przykładem z wypisywaniem komunikatu Hello world! W przypadku urządzeń elektronicznych takim odpowiednikiem będzie zapewne włączenie diody świecącej podłączonej do Raspberry Pi. Pora przejść więc do praktyki!

Uniwersalne porty wejścia-wyjścia Raspberry Pi

Podłączając cokolwiek do GPIO należy zawsze pamiętać o tym, że Raspberry Pi przystosowane jest do pracy z napięciem 3,3V. Jeśli do pinów dostarczymy wyższe napięcie to łatwo uszkodzimy malinkę.

W części poświęconej komunikacji przez UART już o tym pisaliśmy, ale nie zaszkodzi powtórzyć: piny numer 2 i 4 na Raspberry Pi podłączone są do 5V. Omyłkowe zwarcie ich z innymi pinami doprowadzi więc do uszkodzenia płytki. Aby uchronić się przed tym ryzykiem można założyć zworkę na powyższe dwa wyprowadzenia. Dzięki temu nie będziemy mieć do nich fizycznego dostępu:

Raspberry Pi z założoną zworką zabezpieczającą.

Pierwszy układ podłączony do Raspberry Pi - LED

Wiemy już czego unikać (zbyt wysokiego napięcia), pora więc przejść do pierwszego układu. Wszystkie połączenia najlepiej wykonywać przy odłączonym zasilaniu. Raspberry Pi jest skomplikowaną płytką, co sprawia, że łatwo ją uszkodzić.

Zestaw elementów do kursu

Gwarancja pomocy na forum Błyskawiczna wysyłka

Elementy niezbędne do wykonania wszystkich ćwiczeń z kursu podstaw Rasberry Pi dostępne są w formie gotowych zestawów!

Kup w Botland.com.pl

Diodę świecącą (LED) możemy podłączyć właściwie do dowolnego wyprowadzenia. W tym przykładzie podłączymy ją do pinu numer 40 (oznaczonego jako GPIO21). Pin ten znajduje się w narożniku złącza, a jego bliskim "sąsiadem" jest pin numer 39 (masa, GND).

Schemat podłączenia diody do Raspberry Pi.

Mówiąc najprościej: anodę diody (dłuższa nóżka) łączymy przez rezystor (1,2kΩ) do pinu numer 40. Natomiast katodę diody (krótsza nóżka) łączymy z masą, czyli pinem numer 39. Więcej informacji o diodach i rezystorach można znaleźć w kursie elektroniki.

W praktyce układ może wyglądać następująco:

Po zmontowaniu układu sprawdzamy dla pewności raz jeszcze czy nic nie pomyliliśmy i uruchamiamy malinkę. Logujemy się do terminala w wybrany przez nas sposób i wpisujemy polecenie:

Katalog /sys jest jednym z wielu wirtualnych katalogów w naszym systemie. Nie znajdziemy go na karcie SD. System tylko "udaje" że taki katalog istnieje, w rzeczywistości wszystkie odwołania do plików w tym katalogu są obsługiwane przez jądro systemu. Katalog /sys pozwala na dostęp do informacji o sterownikach systemu Linux.

Jak widać w tym katalogu jest już kilka plików:

Pliki znajdujące się w katalogu ls /sys/class/gpio/.

Domyślnie dostęp do pinów nie jest możliwy, musimy więc go uruchomić. Wykorzystamy w tym celu plik o nazwie export. Zapis do tego pliku spowoduje, że jądro udostępni nam odpowiednie wyprowadzenie procesora. Chcemy mieć dostęp do pinu GPIO21, więc zapisujemy liczbę 21 do pliku /sys/class/gpio/export.

Wydajemy polecenie:

Teraz możemy ponownie sprawdzić zawartość katalogu /sys/class/gpio - znajdziemy w nim nowy podkatalog o nazwie gpio21. Jego zawartość pozwoli na sterowanie zachowaniem wybranego pinu.

Nowy plik znajdujący się w katalogu ls /sys/class/gpio/.

Domyślnie wyeksportowany pin jest ustawiony jako wejście (in). Chcemy sterować diodą, potrzebujemy więc wyjścia (out). Musimy zmienić kierunek działania pinu. W tym celu po prostu zapisujemy out do pliku /sys/class/gpio/gpio21/direction

Aby włączyć diodę wydajemy polecenie:

W celu wyłączenia diody wystarczy ustawić wartość wyjścia na 0:

Gdy skończymy eksperymenty możemy posprzątać, czyli wyłączyć dostęp do pinu GPIO21. Na początku go wyeksportowaliśmy, więc teraz należy cofnąć tę operację:

Jak widać w świecie Linuksa wszystko jest plikiem. Katalog /sys zachowuje się jak zwykłe pliki na karcie SD. Do sterowanie podłączonymi urządzeniami możemy wykorzystać standardowe narzędzia z konsoli lub własne programy. Co ciekawe uruchomienie przykładów nie wymagało od nas programowania, to zwykłe operacje na plikach. Oczywiście nie jest to wydajna metoda, jednak w wielu przypadkach będzie ona wystarczająca.

Program gpio i biblioteka WiringPi

Poznaliśmy już metodę bezpośredniej komunikacji z jądrem systemu. To ciekawa opcja, jednak niezbyt efektywna i niekoniecznie wygodna. Na szczęście Raspberry Pi udostępnia kilka całkiem dobrych bibliotek i programów, które pozwalają na wydajniejszy dostęp do pinów. Jedną z nich jest WiringPi.

W tej części kursu nie będziemy pisać programów (tylko proste skrypty), więc wykorzystamy program o nazwie gpio - za jego pomocą można łatwo korzystać z linii GPIO z poziomu konsoli.

Więcej informacji o programie znajdziemy w obszernej dokumentacji:

Fragment dokumentacji programu gpio.

Aktualizacja dla osób z Raspberry Pi 3 model B+

Osoby korzystające z nowego RPi 3B+ powinny zacząć od sprawdzenie wersji zainstalowanego gpio. W tym celu należy wydać polecenie gpio -v. Jeśli numer wersji będzie równy lub większy od 2.46, to wszystko jest dobrze i można iść dalej.

Jeśli zwrócona wersja będzie niższa od 2.46 (najczęściej 2.44) to należy wykonać 3 poniższe polecenia. Za ich pomogą pobierzemy ze strony autora odpowiednią wersję wiringPi i ręcznie ją zaktualizujemy:

Numeracja pinów GPIO na Raspberry Pi

Zanim jednak zaczniemy w pełni korzystać z GPIO musimy przyswoić kilka informacji o numeracji pinów. W przypadku Raspberry Pi panuje "pewien bałagan" i musimy sobie z nim poradzić.  Na płytce znajduje się 40-pinowe złącze. Dostępne piny są numerowane od 1 do 40 (tak samo jak w przypadku każdego innego złącza tego typu). Numer pinu oznacza pozycję sygnału w złączu.

Część pinów ma specjalne znaczenie, np. pin 2 i 4 są podłączone do napięcia 5V, a piny 6, 9, 14, 20, 25, 30, 34 oraz 39 do masy. Z punktu widzenia programisty takie piny nie są ciekawe. Naturalne wydaje się natomiast korzystanie z oznaczeń pinów używanych przez sam procesor.

Opis wyprowadzeń GPIO.

W przypadku mikrokontrolerów piny grupowane są w porty (port A, B itd.) oraz numerowane, mamy więc na przykład pin PA1. W przypadku Raspberry Pi używa się tylko numerów. Mieliśmy już z nimi do czynienia w poprzednim przykładzie. Pisząc GPIO21 chodziło nam o pin 21 procesora.

Nie wszystkie piny procesora są dostępne na złączu Raspberry Pi. Co więcej różne modele różnią się nieco połączeniami. Aby ułatwić życie początkującym, projektanci Raspberry Pi postanowili więc, że wprowadzą jeszcze jedne numery pinów.

W Raspberry Pi mamy więc trzy numery opisujące ten sam pin. Wykonajmy polecenie:

W jego wyniku otrzymamy dokładną rozpiskę wszystkich wyprowadzeń:

Wynik polecenia gpio readall.

W środku widzimy numerację na fizycznym złączu (Physical) - są to piny numerowane od 1 do 40 tak jak je widzimy na płytce. Kolumny BCM (pierwsza po lewej i ostatnia po prawej) opisują numery pinów procesora. Używaliśmy pinu 21 (widzimy go w prawym dolnym rogu). Biblioteka WiringPi używa numeracji zalecanej przez Raspberry Pi, te identyfikatory pinów znajdziemy w kolumnach wPi (więcej można przeczytać na stronie WiringPi).

Kolumna Name definiuje nazwę pliku, warto popatrzeć na kolumny Mode oraz V. Pierwsza określa tryb pinu (domyślnie wejścia, czyli IN) oraz aktualny stan odczytany z wejścia.

Sterowanie buzzera z Raspberry Pi - program gpio

Poprzednio podłączaliśmy diodę świecącą do pinu GPIO21, teraz sprawdźmy działanie buzzera. Podłączmy go do wyprowadzenia GPIO12. Wyprowadzenie modułu opisane jako minus (-) łączymy z masą Raspberry Pi, wyprowadzenie opisane jako plus (+) łączymy z 3,3V. Natomiast środkowy pin modułu łączymy z GPIO12.

Jeśli nie czujesz się pewnie przy podłączaniu takiej elektroniki koniecznie odłącz malinkę od zasilania. Zrób wszystko na spokojnie, sprawdź dwa razy i dopiero wtedy włącz całe urządzenie. Zajmie to trochę więcej czasu, ale może uchronić Raspberry Pi przed spaleniem. 

Schemat podłączenia modułu z buzzerem.

Układ w praktyce może wyglądać następująco:

Tak jak było wspomniane, biblioteka WiringPi używa innej numeracji pinów. Można jednak wymusić używanie takich samych numerów jak w przypadku katalogu /sys. Zostańmy teraz przy tej numeracji. 

Na początek ustawiamy pin numer 12 jako wyjście wydając polecenie:

Teraz możemy wyłączać i włączać buzzer pisząc odpowiednio (po numerze pinu podajemy jego stan, logiczne 1 lub logiczne 0):

Otrzymaliśmy tą samą funkcjonalność co poprzednio, ale nie musieliśmy odwoływać się bezpośrednio do plików, dzięki temu cały "kod" był krótszy.

Sterowanie pinami za pomocą nowej biblioteki.

Oczywiście dla testu możemy spróbować użyć numeracji biblioteki WiringPi. Wracamy do tabelki z pinami (gpio readall) i odnajdujemy nasz pin numer 12. Zgodnie z wewnętrzną numeracją biblioteki będzie miał on numer 26. Możemy więc wydać polecenia:

Działanie układu będzie identyczne.

Skrypty - proste programy w konsoli

Potrafimy już sterować uniwersalnymi wyjściami. Metoda ręcznego wydawania poleceń jest jednak mało wygodna. Na szczęście nie musimy wszystkich poleceń ręcznie wpisywać do terminala.

Skrypt to po prostu plik tekstowy z poleceniami, które normalnie wprowadzamy z klawiatury w oknie terminala. Dzięki umieszczeniu ich w pliku nie musimy wszystkiego wpisywać od nowa  - wystarczy wywołać odpowiedni plik.

Pierwszy skrypt - włączenie diody

Zacznijmy od ekstremalnie prostego przykładu. Niech nasz pierwszy skrypt konfiguruje odpowiedni pin jako wyjście i ustawia na nim stan wysoki (czyli np. włączy diodę). Oczywiście sensowność takiego "programu" jest raczej nikła, przećwiczymy jednak kwestie tworzenia i uruchamiania samego skryptu.

Na początku musimy utworzyć nowy plik z rozszerzeniem sh. Przykładowo może to być led.sh, w tym celu skorzystamy z edytora nano:

W jego treści wpisujemy komendy, które normalnie wpisalibyśmy do konsoli - musimy poprzedzić je tylko jedną linijką: #!/bin/sh. Skrypt włączający diodę podłączoną do pinu 21 wyglądałby więc tak:

Plik zapisujemy (CTRL+X). Następnie musimy naszemu skryptowi nadać odpowiednie uprawnienia, aby był traktowany jak "program". W tym celu korzystamy oczywiście z chmod:

Aby uruchomić skrypt wydajemy polecenie:

Dioda powinna od tej pory świecić!

Dioda włączona.

Skrypt migający diodą na Raspberry Pi

Skrypty mogą być bardziej rozbudowane. Mogą na przykład zawierać w sobie pętle. Pora wykonać "nieśmiertelny przykład" z migającą diodą. Tworzymy nowy plik blink.sh:

W jego treści wklejamy prostą pętlę while (na ten moment nie będziemy skupiać się na składni):

Powyższy kod konfiguruje pin numer 21 jako wyjście. Następnie zmienia jego stan co sekundę. Plik zapisujemy (CTRL+X), nadajemy mu odpowiednie uprawnienia (sudo chmod +x blink.sh). Działanie skryptu można przerwać za pomocą CTRL+C.

Po uruchomieniu programu dioda będzie migała, tak jak na poniższej animacji:

Skrypt migający diodą w praktyce.

Najważniejsze podstawy za nami! Bazując na opisanych tutaj przykładach można stworzyć np. symulację prostych świateł drogowych. Do tego pomysłu wrócimy jeszcze w kolejnym artykule, a w między czasie zachęcamy do samodzielnych eksperymentów!

Podsumowanie

W tej części kursu zajęliśmy się podstawowymi operacjami na wyjściach. Najważniejsze, aby po lekturze tego artykułu znać 3 metody numeracji pinów i samodzielnie tworzyć proste skrypty.

W kolejnym odcinku wykorzystamy piny generujące sygnał PWM, sprawdzimy również jak w praktyce działają wejścia. Na koniec zamienimy nasze Raspberry Pi w prosty aparat cyfrowy. Wciśnięcie przycisku będzie powodowało wykonanie zdjęcia. Połączymy więc umiejętności z wszystkich poprzednich części.

Nawigacja kursu

Autor kursu: Piotr Bugalski,
Testy, ilustracje: Piotr Adamczyk
Redakcja: Damian Szymański

GPIO, kurs, RaspberryPi, skrypt, wiringPi

Komentarze

Komentarze do tego wpisu są dostępne na forum: