Jeśli chodzi o samą płytkę Raspberry Pi, wiemy, że jest ona przystosowana do pracy z programowaniem komponentów elektronicznych za pomocą jej pinów GPIO (ang. general-purpose input/output). Są to piny ogólnego przeznaczenia do wejścia/wyjścia, z których część można zobaczyć w dwóch rzędach po 20 pinów. Na poniższym obrazku możemy zobaczyć wyraźniej, które piny odpowiadają czemu.

Każdy z pinów GPIO może zostać przypisany (w oprogramowaniu) jako pin wejściowy lub wyjściowy i użyty do szerokiego zakresu zastosowań, takich jak podłączenie diody LED lub czujnika.

Uwaga: Numeracja pinów GPIO nie jest uporządkowana numerycznie. Piny GPIO 0 i 1 są obecne na płycie (fizyczne piny 27 i 28), ale są zarezerwowane dla zaawansowanego użytku (patrz poniżej).

Napięcia

Na płytce znajdują się dwa piny o napięciu 5V oraz dwa piny o napięciu 3,3V (3,3V), jak również kilka pinów uziemiających (GND: 0V), które nie są konfigurowalne. Pozostałe piny to ogólnego przeznaczenia piny 3,3V, co oznacza, że wyjścia są skonfigurowane na 3,3V, a wejścia tolerują napięcie 3,3V.

Wyjścia

Pin GPIO oznaczony jako pin wyjściowy może być skonfigurowany jako stan wysoki (3,3V) lub niski (0V).

Wejścia

Pin GPIO oznaczony jako pin wejściowy może być odczytywany jako stan wysoki (3,3V) lub niski (0V). Ułatwia to użycie wewnętrznych rezystorów podciągających lub opuszczających. Piny GPIO2 i GPIO3 posiadają wbudowane rezystory podciągające, ale dla innych pinów można to skonfigurować w oprogramowaniu.

Więcej 

Poza prostymi urządzeniami wejściowymi i wyjściowymi, piny GPIO mogą być używane z różnymi funkcjami alternatywnymi, niektóre z nich są dostępne na wszystkich pinach, inne na konkretnych pinach.

· PWM: Piny obsługujące modulację szerokości impulsu, używaną do przesyłania informacji przez kanał komunikacyjny lub do kontrolowania ilości energii wysyłanej do obciążenia.

o PWM oprogramowania dostępne na wszystkich pinach

o PWM sprzętowe dostępne na GPIO12, GPIO13, GPIO18, GPIO19

· SPI: Interfejs szeregowy do podłączania urządzeń peryferyjnych, głównie do przesyłania informacji między układami scalonymi w elektronice.

o SPI0: MOSI (GPIO10); MISO (GPIO9); SCLK (GPIO11); CE0 (GPIO8), CE1 (GPIO7)

o SPI1: MOSI (GPIO20); MISO (GPIO19); SCLK (GPIO21); CE0 (GPIO18); CE1 (GPIO17); CE2 (GPIO16)

· I2C: Interfejs szeregowy do komunikacji między różnymi częściami obwodu, na przykład między kontrolerem a zintegrowanymi układami peryferyjnymi.

o Dane: (GPIO2); Zegar (GPIO3)

o Dane EEPROM: (GPIO0); Zegar EEPROM (GPIO1)

· Szeregowe: Porty do komunikacji UART (Uniwersalny Odbiornik-Nadajnik Asynchroniczny) za pomocą pinu transmisji TX i pinu odbioru RX.

o TX (GPIO14); RX (GPIO15)

Istnieją 2 sposoby numerowania pinów na Raspberry Pi: w trybie GPIO lub w trybie BCM. Jest to ważne podczas programowania. Różnica między tymi notacjami zazwyczaj jest zauważalna podczas kontrolowania pinów GPIO za pomocą Pythona lub innego języka, gdy musimy określić, w jakim trybie będziemy używać pinów GPIO: GPIO.BOARD lub GPIO.BCM.

Opcja GPIO.BOARD oznacza, że odnosimy się do pinów za pomocą ich numeru, czyli numerów widocznych na naszej Raspberry Pi (na przykład P1). Na poniższym obrazku pokazujemy pin 1 i pin 2. Kolejne piny numerujemy od lewej do prawej, przy czym pin poniżej pinu 1 będzie pinem 3. Cały ten rząd to piny nieparzyste, a przeciwległy rząd to piny parzyste.

Opcja GPIO.BCM odnosi się do pinów za pomocą ich numeru "Broadcom SOC channel". Nie są one kolejne jak w trybie BOARD. Na poniższym obrazku pokazane są zarówno piny w trybie BOARD, jak i w trybie BCM różnych wersji Raspberry Pi. Piny BCM mają nazwę rozpoczynającą się od GPIO, a środkowe to piny BOARD. Można by powiedzieć, że numery BCM odnoszą się do układu procesora, a numery BOARD do złącza.

Aby kontrolować GPIO za pomocą Pythona, musisz najpierw zaimportować wcześniej napisaną bibliotekę. Najpopularniejszą i powszechnie stosowaną jest Rpi.GPIO, używana do tworzenia tysięcy projektów od pierwszych dni RPi. Inną interesującą biblioteką jest WiringPi, która sprawia, że piny są bardziej "przenośne" między różnymi kodami, bardziej uniwersalne.

Aby zainstalować najnowszą wersję, należy wprowadzić następujące instrukcje w konsoli:

cd /tmp

wget https://project-downloads.drogon.net/wiringpi-latest.deb

sudo dpkg -i wiringpi-latest.deb

Aby zobaczyć te piny na Raspberry Pi, możemy otworzyć konsolę poleceń i wykonać polecenie: gpio readall. Jak wskazuje nazwa, odczyta wszystko, co dotyczy gpio, i pokaże poniższą informacyjną tabelę, gdzie można zobaczyć każdy pin i jego charakterystyki.

Inną komendą, którą możemy być zainteresowani, jest: pinout. Dzięki temu pokaże nam informacje bardziej wizualnie:

5.1 Programowanie GPIO

Teraz, gdy już wiemy, do czego służą te piny, przejdźmy do wyjaśnienia, jak ich używać i programować urządzenia. Możemy użyć tej samej konsoli poleceń do zmiany konfiguracji pinów, na przykład, aby pin 21 wygenerował wysokie napięcie i zaświecił podłączoną diodę LED.

5.1.1 Korzystanie z konsoli

Można "programować" na różne sposoby, a najprostszym jest po prostu korzystanie z poleceń w konsoli. Przede wszystkim podłączymy diodę LED do RPi. Pamiętaj, że zawsze musi być podłączony rezystor szeregowy, w naszym przypadku użyjemy rezystora 1kΩ i czerwonej diody LED podłączonej do pinu GPIO21 w następujący sposób:

Pin 40 jest podłączony do rezystora, który następnie łączy się z anodą diody LED. Katoda diody LED łączy się z GND, który jest na pinie 39.

ls /sys/class/gpio/

Katalog /sys to jeden z wielu wirtualnych katalogów w naszym systemie. Nie znajdziemy go na karcie SD. System tylko "udaje", że taki katalog istnieje, a faktycznie wszystkie odniesienia do plików w tym katalogu są obsługiwane przez jądro systemu (jądro SO w Linuxie). Katalog /sys umożliwia dostęp do informacji o sterownikach systemu Linux. W tym przypadku skupiamy się na sterownikach klasy GPIO, czyli portach wejścia i wyjścia.

Jak widać, istnieją już pewne pliki w tym katalogu:

Domyślnie dostęp do pinów jest wyłączony, więc musimy go włączyć. Do tego celu użyjemy pliku o nazwie export. Zapisanie wartości w tym pliku spowoduje, że jądro systemu dostarczy nam odpowiednie przyporządkowanie pinów procesora. Chcemy uzyskać dostęp do pinu GPIO21, więc zapisujemy numer 21 w pliku /sys/class/gpio/export, wykonując polecenie:

echo 21 > /sys/class/gpio/export

Teraz możemy ponownie sprawdzić zawartość katalogu /sys/class/gpio; znajdziemy nowy podkatalog o nazwie GPIO21. Jego zawartość umożliwi kontrolowanie zachowania wybranego pinu.

Domyślnie, wyeksportowany pin jest ustawiony jako wejście (in). Chcemy kontrolować diodę, więc potrzebujemy wyjścia (out). Musimy zmienić kierunek pinu. Aby to zrobić, wystarczy wpisać "out" w pliku /sys/class/GPIO/gpio21/direction:

echo out > /sys/class/gpio/gpio21/direction

Od teraz możemy kontrolować diodę, wpisując wartości do pliku wartości.

Aby włączyć diodę, wydajemy polecenie:

echo 1 > /sys/class/gpio/gpio21/wartość

W związku z tym, aby go wyłączyć, wpisujemy 0:

echo 0 > /sys/class/gpio/gpio21/wartość

Kiedy skończymy eksperymenty, możemy posprzątać, czyli wyłączyć dostęp do pinu GPIO21. Na początku go wyeksportowaliśmy, więc teraz musimy cofnąć ten krok:

echo 21 > /sys/class/gpio/unexport

Jak widzisz w świecie Linuxa, wszystko jest plikiem. Katalog /sys zachowuje się jak zwykłe pliki na karcie SD. Możemy używać standardowych narzędzi konsolowych lub naszych własnych programów do kontrolowania podłączonych urządzeń. Co ciekawe, uruchamianie tych przykładów nie wymagało od nas programowania, to po prostu normalne operacje na plikach. Oczywiście, nie jest to skuteczna metoda, ale w wielu przypadkach będzie wystarczająca.

Warto wspomnieć, że korzystając z dostępu do katalogu /sys/class/gpio, można również kontrolować piny na innych platformach. Ta funkcjonalność jest zapewniana przez jądro Linuxa i nie zależy od Raspberry Pi.

5.1.2 GPIO i WiringPi

O metodzie komunikacji bezpośredniej z jądrem już się nauczyliśmy. To interesująca opcja, ale nie zawsze skuteczna i wygodna. Na szczęście Raspberry Pi jest wyposażone w kilka dość dobrych bibliotek i programów, które pozwalają na efektywniejszy dostęp do pinów. Jednym z nich jest WiringPi.

W tej części kursu nie będziemy tworzyć programów (tylko proste skrypty), dlatego będziemy korzystać z programu o nazwie gpio - za jego pomocą można łatwo korzystać z pinów GPIO z konsoli.

Więcej informacji o tym programie znajdziesz w obszernej dokumentacji:

man gpio

W sekcji "SYNOPSIS" możemy zobaczyć różne opcje komend.

Aby używać komend z WiringPi, najpierw sprawdzimy zainstalowaną wersję tej biblioteki. Aby to zrobić, uruchom polecenie gpio -v. Jeśli numer wersji wynosi 2.46 lub wyższy, to wszystko w porządku i możesz kontynuować. Jeśli jest niższy, użyj tych poleceń, aby zainstalować nowszą wersję, jak wspomnieliśmy wcześniej:

cd/tmp

wget https://unicorn.drogon.net/wiringpi-2.46-1.deb

sudo dpkg -i wiringpi-2.46-1.deb

Teraz przejdziemy do prostego przykładu włączania diody LED przy użyciu tego samego połączenia co poprzednio, ale tym razem na pinie 12 (tryb BCM), który jest fizycznym pinem 32 na złączu.

Jak wspomniano, biblioteka WiringPi używa innej numeracji pinów. Jednak można wymusić użycie tych samych numerów co w katalogu /sys. Pozostańmy przy tej numeracji teraz.

Aby rozpocząć, ustawiamy pin 12 jako wyjście, wydając polecenie:

tryb gpio -g 12 out

Opcja -g w poleceniu gpio zmusza nas do użycia numeracji pinów procesora.

Teraz możemy wyłączać i włączać diodę LED, wpisując po numerze pinu odpowiednio stan 0 logiczny lub 1 logiczny:

gpio -g napisać 12 0

gpio -g zapis 12 1

Otrzymaliśmy tę samą funkcjonalność co wcześniej, ale nie musieliśmy odwoływać się bezpośrednio do plików, co skróciło cały "kod".

WiringPi

Oczywiście, na potrzeby testów możemy spróbować użyć numeracji z biblioteki WiringPi. Wróćmy do tabeli z pinami (gpio readall) i poszukajmy pinu numer 12. Według wewnętrznej numeracji biblioteki, będzie miał numer 26.

Następnie możemy wydawać polecenia:

tryb gpio 26 na zewnątrz

gpio napisać 26 0

gpio napisać 26 1

Możemy sprawdzić, że działanie będzie identyczne.

5.2 Skrypty, proste programy

Teraz jesteśmy w stanie kontrolować uniwersalne wyjścia. Jednak metoda ręcznego wysyłania poleceń nie jest zbyt wygodna. Na szczęście nie musimy ręcznie wpisywać wszystkich poleceń w terminalu.

Możemy napisać skrypty, które zostaną wykonane jako "proste programy".

Skrypt to po prostu plik tekstowy zawierający polecenia, które normalnie wprowadzamy z klawiatury w oknie terminala. Dzięki umieszczeniu ich w pliku, nie musimy ponownie wszystkiego przepisywać, wystarczy wywołać odpowiedni plik.

5.2.1. Dioda LED skryptu

Rozpoczniemy od tego samego niezwykle prostego przykładu - włączenie diody LED. Nasz pierwszy skrypt spowoduje ustawienie odpowiedniego pinu jako wyjście i ustawienie go na stan wysoki (czyli włączenie diody LED). Oczywiście, nie ma to zbyt wiele sensu, aby tworzyć "program" do czegoś tak prostego, ale w ten sposób możemy poćwiczyć tworzenie i uruchamianie skryptów.

Najpierw musimy utworzyć nowy plik z rozszerzeniem ".sh". Na przykład może to być led.sh. Do tego użyjemy edytora nano:

nano led.sh

W jego treści wprowadzamy polecenia, które normalnie wpisywalibyśmy w konsoli. Musimy poprzedzić je jedną linią: #!/bin/sh. Wówczas skrypt, który włącza diodę podłączoną do pinu 21, będzie wyglądał tak:

!/bin/sh

tryb gpio -g 21 out

gpio -g zapis 21 1

Zapisz plik (CTRL + X). Następnie musimy nadać naszemu skryptowi odpowiednie uprawnienia, aby mógł być traktowany jako "program". Służy do tego komenda chmod:

sudo chmod +x led.sh

Aby uruchomić skrypt, wydajemy polecenie:

led.sh

Teraz dioda LED zapali się automatycznie. Aby ją wyłączyć, potrzebny będzie inny, oddzielny skrypt, który możesz wypróbować samodzielnie. Teraz spróbujemy kolejnego, bardziej funkcjonalnego przykładu - sprawimy, że dioda będzie migać automatycznie. Tworzymy nowy plik blink.sh:

nano blink.sh

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

#!/bin/sh

gpio -g mode 21 out

while true

do

   gpio -g write 21 1

   sleep 1

   gpio -g write 21 0

   sleep 1

done

Pętla while, jak wskazuje jej tłumaczenie, polega na powtarzaniu czegoś, dopóki zachodzi określony warunek. W tym przypadku, w trybie krótkim, widzimy, że dopóki jest "prawda" (true), wykonaj (do) następujące linie. W rezultacie zawartość między "do" a "done" będzie wykonywana w pętli.

Powyższy kod ustawia pin numer 21 jako wyjście. Następnie zmienia stan co sekundę (sleep 1). Zapisz plik (CTRL + X), nadaj odpowiednie uprawnienia (sudo chmod + x blink.sh). Skrypt można przerwać, naciskając CTRL + C.

Teraz zobaczysz, jak dioda LED miga co sekundę, gdy uruchomisz skrypt.

Korzystając z opisanych tutaj przykładów, masz już wystarczające umiejętności, aby na przykład stworzyć prostą symulację świateł drogowych.