W większość projektów, które realizował autor tego poradnika w oparciu o Raspberry Pi wykorzystywał on piny GPIO jako wejścia i wyjścia cyfrowe. Wyprowadzonych na płytce RPi jest 17 takich pinów. Co zrobić jak potrzebujemy więcej? Najprostszym sposobem zwiększenia liczy wejść i wyjść cyfrowych, jest wykorzystanie jakiegoś ekspandera portów I/O. Tego rodzaju urządzenie pozwala zwiększyć liczbę dostępnych w układzie portów cyfrowych.
Przykładem takiego ekspandera może być układ MSP23017. Jest to ekspander, komunikujący się z urządzeniem z pomocą portu I²C. Interfejs ten, to szeregowy interfejs komunikacyjny, pozwalający na podłączenie do jednej szyny danych większej liczby urządzeń. Ekspander konwertuje dane z/do I²C do/z równoległego wyjścia cyfrowego. Do podłączenia ekspandera wystarczy kilka pinów GPIO, a z pomocą interfejsu I²C obsłużyć można wiele urządzeń i sensorów.
Część sprzętowa
MCP23017 to 16 bitowy ekspander portu z interfejsem I²C. Wybrany został ten układ, z uwagi na to że oferuje aż 16 wyjść/wejść cyfrowych. Do jego sterowania wykorzystano wyprowadzony z Raspberry Pi port I²C wyprowadzony na pinach 3 i 5 listwy GPIO. To łącznie daje 31 pinów GPIO (15 + 16) w systemie z tylko jednym ekspanderem. Możliwe jest wykorzystanie większej ilości ekspanderów, co pozwala ogromnie zwiększyć ilość dostępnych portów GPIO. Dodanie kolejnego układu MCP23017 do systemu zwiększy liczbę dostępnych pinów GPIO z 31 do 47 (15 + 16 + 16). I to wszystko przy bardzo niewielkich kosztach (w Polsce układ jest dostępny w wielu sklepach w cenie od 4 zł do 6 zł - przyp. red.).
Ogromną zaletą tych układów jest to, że są tanie i wymagają bardzo niewielkiej ilości dodatkowych dyskretnych do działania.
W naszym przykładzie z pomocą tego ekspandera podłączyć do RPi chcemy 3 diody LED i przełącznik - wszystko przez interfejs I²C. Wykorzystano oporniki 330 Ω do ograniczenia prądu płynącego przez diody LED. Można wykorzystać inny rezystor, takie autor akurat miał pod ręką. Poniżej widoczny jest rozkład wyprowadzeń układu MCP23017 oraz schemat podłączenia go do płytki Raspberry Pi.
Opornik przy przełączniku włączony jest pomiędzy wejście układu a masę. Jego rezystancja wynosi 10 kΩ. Zapewnia to stan niski na wejściu z przełącznikiem, będący tam do czasu jego naciśnięcia. Przyciśnięcie przycisku powoduje, że na wejściu obecne jest 3,3 V czyli stan wysoki. Rezystor zapobiega powstaniu zwarcia pomiędzy masą a zasilaniem i ogranicza płynący prąd.
Pin 9 (VDD) podłączony jest do zasilania 3,3 V,
Pin 10 (VSS) podłączony jest do masy,
Pin 12 (SCL) podłączony jest di 5 pinu RPi,
Pin 13 (SDA) podłączony jest di 5 pinu RPi,
Pin 18 (Reset) powinien być w stanie wysokim w czasie normalnego działania układu, należy podłączyć do 3,3 V,
Piny 15, 16 oraz 17 (A0-A2) determinują jaki jest adres układu. Używamy w systemie tylko jednego układu, więc wystarczy ustawić zero (wszystkie piny do masy).
Tak wygląda złożony układ na płytce prototypowej:
Część systemowa
Aby wykorzystywać interfejs I²C na płytce Raspberry Pi należy włączyć w Raspbianie kilka rzeczy, które domyślnie są wyłączone. Konfiguracja realizowana jest w kilku prostych krokach. Opisane poniżej tyczą się nowszej wersji Raspbiana, więc posiadacze starszej instalacji muszą albo zmienić system na nowy, albo prześledzić zmiany.
Krok pierwszy - załączenie I²C poprzez raspi-config
Z linii komend wpisz:
sudo raspi-configUruchomi to narzędzie do konfiguracji układu raspi-config, wygląda ono następująco:
Teraz postępuj zgodnie z poniższym opisem:
Wybierz “8 Advanced Options”
Wybierz “A7 I2C”
Wybierz “Yes”
Komunikat zapyta czy na pewno włączyć interfejs I²C.
Wybierz “Yes”
Wybierz “Ok”
Komunikat zapyta czy domyślnie ładować moduł.
Wybierz “Yes”
Komunikat oznajmi, że moduł ładowany będzie domyślnie.
Wybierz “Ok”
Wybierz “Finish”, aby powrócić do linii komend.
Gdy uruchomisz ponownie system, moduły I²C będą załadowane
Krok drugi - manualna edycja pliku modułów
Następnie musimy dokonań ręcznej edycji pliku modułów. Korzystamy w tym celu z komendy:
sudo nano /etc/modulesI w pliku dodajemy dwie następujące linijki:
i2c-bcm2708
i2c-devNaciskami CTRL-X, następnie Y, następnie RETURN aby zapisać plik i wyjść.
Krok trzeci - instalacja plików programów interfejsu
Aby pomóc sobie w debuggowaniu działania interfejsu I²C i aby móc korzystać z niego pod Pythonem. Instalujemy “python-smbus” i “i2c-tools”:
sudo apt-get update
sudo apt-get install -y python-smbus i2c-toolsKrok czwarty – Shutdown
Wyłącz Raspberry Pi:
sudo haltOdczekaj dziesięć sekund, odłącz zasilanie i możesz podłączać ukłądy do interfejsu I²C.
Sprawdzanie czy moduł I²C jest załączony (opcjonalne)
Gdy uruchomiesz lub zrestartujesz RPi, aby sprawdzić czy moduł interfejsu pracuje wystarczy wpisać komendę:
lsmod | grep i2c_W wyniku zobaczymy wszystkie moduły zaczynające się od "i2c_". JEśli widzimy wśród nich “i2c_bcm2708″ to oznacza że moduł załadował się poprawnie.
Testowanie sprzętu
Gdy udało się już z powodzeniem załączyć działanie modułów I²C i podłączyć układy, trzeba sprawdzić ich działanie. Po upewnieniu się, że zasilanie podłączone jest w odpowiedni sposób i nie ma żadnych zwarć, możemy uruchomić system. Jeśli mamy RPi Rev 2 lub późniejsze, do testów korzystamy z komendy:
sudo i2cdetect -y 1Jeśli dysponujemy układem Rev 1 to wykorzystamy komendę:
sudo i2cdetect -y 0Jaka jest różnica? Pomiędzy Rev 1 a Rev 2 zamianie uległy sygnały idące do pinów 3 i 5 na GPIO. Zmienia to numer urządzenia, jaki nadaje się I²C, stąd też zmiana z 0 na 1.
Autor wykorzystywał RPi Rev 1. Na wyjściu powyższej komendy uzyskał:
pi@raspberrypi ~ $ sudo i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --Pokazuje to, że do systemu podłączony jest tylko jeden układ, którego adres do 0x20 (32dec). Taka konfiguracja wynika z ustawienia pinów adresowych układu. Jeśli na na przykład A0 podalibyśmy stan wysoki, to adres wynosił by 0x21 (33dec). Od tego jak ustawione zostaną piny konfigurujące adres układu - A0, A1 i A2 - zależy pod jakim adresem występować będzie układ. Zadbać jedynie trzeba, aby adres był unikalny.
Test z linii komnd
Aby przeprowadzić szybki test działania układu pod GPA0 podłączamy LEDa. Skonfigurujmy Port A w następujący sposób: GPA0..6 jako wyjścia i GPA7 jako wejście. (10000000bin lub 0x80hex).
sudo i2cset -y 1 0x20 0x00 0x80 Następnie ustawmy GPA0 w stan wysoki, co zapali LEDa:
sudo i2cset -y 1 0x20 0x14 0x01Aby wyłączyć LEDa wystaczy:
sudo i2cset -y 1 0x20 0x14 0x00Pamiętajmy o zmianie 1 na 0, jeśli korzystamy z RPi Rev 1.
Zatem konfigurację i testowane układu mamy za sobą, teraz spróbujmy kontrolować wyjścia GPIO z ekspandera z pomocą Pythona! Poniżej znajduje się opis jak wykorzystywać go jako wyjścia i wejścia cyfrowe w prostym skrypcie Pythona.
W poniższym przykładzie skupimy się na wykorzystaniu pierwszych trzech pinów portu A układu MCP23017 jako wyjść. Opróc portu A układ posiada jeszcze port B (GPB0..7), który kontrolować można w analogiczny sposób.
W tego rodzaju skryptach niezwykle pomocna jest umiejętność szybkiej konwersji pomiędzy liczbami dziesiętnymi, binarnymi i szesnastkowymi. Można też skorzystać z kalkulatora, który wbudowany jest w system operacyjny lub z jakiegoś narzędzia on-line.
Skrypt Pythona dla wyjść
Poniżej znajduje się bardzo prosty, przykładowy skrypt, który wykorzystuje pierwsze trzy piny portu A do liczenia od 1 do 8, co widoczne jest na diodach:
Kod: Python
Skrypt pobrać można ze strony komendą:
wget https://bitbucket.org/MattHawkinsUK/rpispy-misc/raw/master/mcp23017/mcp23017_outputs.pyUruchomić skrypt można poprzez:
sudo python mcp23017_outputs.pyPowyższy skrypt realizuje następujące kroki:
Importuje biblioteki smbus i time,
Tworzy obiekt typu smbus “bus”,
Konfiguruje pewne stałe,
Ustawia wszystkie piny GPA jako wyjścia,
Ustawia wszystkie piny GPA jako zero,
Odlicza od 1 do 8, ustawiając aktualną wartość na GPA, czekając 1 sekundę pomiędzy każdym krokiem,
Zeruje wszystkie piny GPA.
Powinno to być widoczne na diodach LED w postaci sekwencji:
000, 001, 010, 011, 100, 101, 110, 111
Niezwykle istotną rzeczą, na którą trzeba zwrócić uwagę, jest to, że rejestry trzeba konfigurować po 8 bitów naraz. Zatem, aby skonfigurować GPA jako wyjścia wpisujemy 00000000 do IODIR, aby skonfigurować jako wyjścia wpisujemy 11111111 (255dec, 0xFFhex). Aby nastawiać GPA0..3 jako wyjścia i GPA4..7 do IODIR wpiszemy 11110000 (240dec, 0xF0hex) etc.
Podobnie rzecz ma się z zapisem danych na wyjścia. Jeśli mamy GPA jako wyjścia i chcemy do GPA1 zapisać stan wysoki, a do innych niski musimy wysłać 00000010 na rejestr OLATA. Analigicznie, aby ustawić w stan wysoki jedynie GPA2 i GPA8 do tego rejestru zapiszemy 10000100
It’s the same story for setting the pins of outputs. If you’ve set the GPA pins as outputs and you want to set GPA1 high and all the other pins low you need to send 00000010 to the OLATA register. If you want to set GPA2 and GPA7 high you would send 10000100.
Skrypt Pythona dla wejść
Poniżej przedstawiono przykładowy skrypt, pozwalający na odczyt w pętli stanu przełącznika i wypisywanie informacji, gdy przycisk zostanie naciśnięty.
Kod: Python
Skrypt pobrać można ze strony komendą:
wget https://bitbucket.org/MattHawkinsUK/rpispy-misc/raw/master/mcp23017/mcp23017_inputs.pyUruchomić skrypt można poprzez:
sudo python mcp23017_inputs.pyPowyższy skrypt realizuje następujące kroki:
Importuje biblioteki smbus i time,
Tworzy obiekt typu smbus “bus”,
Konfiguruje pewne stałe,
Ustawia wszystkie siedem pierwszych pinów GPA jako wyjścia,
Ustawia ostatni pin GPA jako wejście
Odczytuje w pętli stan ósmego bitu GPA
Generuje komunikat na ekranie “Switch was pressed!”, gdy naciśnięty zostanie przycisk.
W tym przykładzie wykorzystano jedynie jeden przycisk. Wykorzystując wszystkie osiem bitów rejestrów GPA i GPB podłączyć można aż 16 GPIO do wykorzystania jako wyjścia lub wejścia. Oznacza to 16 LEDów albo przycisków albo cokolwiek chcemy! Wystarczy tylko w odpowiedni sposób skonfigurować rejestry IODIRA i IODIRB.
Źródła:
http://www.raspberrypi-spy.co.uk/2013/07/how-...der-with-the-raspberry-pi-part-1/#prettyPhoto
http://www.raspberrypi-spy.co.uk/2013/07/how-...c-port-expander-with-the-raspberry-pi-part-2/
http://www.raspberrypi-spy.co.uk/2013/07/how-...c-port-expander-with-the-raspberry-pi-part-3/
http://www.raspberrypi-spy.co.uk/2014/11/enabling-the-i2c-interface-on-the-raspberry-pi/
Fajne? Ranking DIY
