środa, 28 grudnia 2016

Raspberry PI i dodatkowe piny GPIO na kilku układach mcp23017 oraz przełącznik na tranzystorze

Jakiś czas temu doszedłem do wniosku że system sterowania automatyką domową który zrobiłem jest zbyt skomplikowany. Mam obecnie raspberry PI + arduino + ethernet shield + dodatkowa płytka do złączy. Arduino razem z ethernet shield czasami sprawia problemy, szczególnie po zanikach energii ma problemy z ponownym uruchomieniem się i wymaga manualnego restartu. Jest to zatem element którego chcę się pozbyć. Wydaje się że samo raspberry PI powinno być zdecydowanie wystarczające. Ogranicza jedynie liczba pin'ów GPIO i wydajność prądowa. Na szczęście da się to obejść i rozpocząłem już projektowanie płytki która po podłączeniu do raspberry dostarczy nam dodatkowe piny oraz możliwość załączania/wyłączania bardziej prądożernych urządzeń. Aby zyskać dodatkowe piny najłatwiej skorzystać z układów mcp23017 które podłączamy do raspberry PI za pomocą magistrali I2C. Każdy taki układ dostarczy nam 16 dodatkowych pin'ów. Układy można ze sobą łączyć, zatem tych pinów można mieć zdecydowanie więcej. Obliczyłem że na moje potrzeby dwa takie układy wystarczą. W sieci znaleźć można mnóstwo przykładów podłączania mcp23017 do raspberry, jednak działających przykładów podpięcia kilku układów jednocześnie już zbyt wiele nie ma. Dodatkowe założenie jest takie, że chcę mieć możliwość włączania/wyłączania urządzeń o większym napięciu niż 5V dostarczane przez raspberry PI. To możemy zrobić za pomocą klucza na tranzystorze N-MOSFET. Poniżej przedstawiam schemat podłączenia do raspberry PI dwóch układów mcp23017 oraz wpięcie do nich dwóch kluczy tranzystorowych. Jeden (podpięty do pierwszego MCP) steruje diodą LED, drugi steruje modułem przekaźnikowym (do którego dalej możemy podłączyć dowolne urządzenie 220V). W moim przykładzie dodatkowe zewnętrzne źródło zasilania to nadal 5V (takiego napięcia potrzebuje zarówno moduł przekaźnikowy jak i dioda LED), ale nic nie stoi na przeszkodzie aby podłączyć do układu napięcie 12V lub 24V (lub wyższe - ograniczenie wynika z możliwości zastosowanego tranzystora) i sterować urządzeniami wymagającymi wyższego napięcia wpinając je do układu analogicznie.


Aby układ zadziałał poprawnie musimy w raspberry PI aktywować obsługę magistrali I2C. 
Opis jak to zrobić znaleźć można na przykład tutaj:


Każdy układ mcp23017 który podłączamy musi mieć oddzielny adres na magistrali I2C.


Za adresowanie odpowiadają piny zaznaczone na rysunku. Adres zawsze zaczyna się od 0x2. Ostatnia cyfra w adresie zależna jest od sposobu w jaki podłączymy piny adresowe. Każdy z nich musi być podłączony albo do masy albo do VCC. Na podanym przykładzie pierwszy układ wszystkie piny podłączone ma do GND, odczytując je binarnie mamy zero, czyli ostatnia cyfra adresu to 0.
Pierwszy układ ma zatem adres 0x20.
Drugi układ środkowy pin podłączony ma do VCC, czyli 010 binarnie daje nam 2 szesnastkowo, zatem adres drugiego układu to 0x22. Podpięcie wszystkich pinów do VCC dałoby nam 111 binarnie, czyli 7 szesnastkowo, adres byłby wtedy 0x27.

Po podpięciu układu możemy sprawdzić jego działanie.
Logujemy się do raspberry Pi (ja korzystam z raspbiana, w którym całe oprogramowanie do I2C jest zainstalowane - w innych dystrybucjach może być konieczność doinstalowania dodatkowych pakietów). 

wykonujemy polecenie

sudo bash

aby nadać sobie uprawnienia roota (dzięki temu przed każdym poleceniem nie będziemy musieli dodawać "sudo")

Następnie wydajemy polecenie:

i2cdetect -y 1

w przypadku raspberry pi 1 będzie to:

i2cdetect -y 0

Po wykonaniu polecenia powinniśmy otrzymać:




Widać że na magistrali mamy dwa urządzenia z adresami 20 i 22

Sterowanie magistralą odbywa się za pomocą polecenia i2cset.

Na początku ustawiamy piny GPA0-7 obydwu układów aby pracowały jako wyjścia.

w tym celu wykonujemy polecenia:


i2cset -y 1 0x20 0x00 0x00

i2cset -y 1 0x22 0x00 0x00


1 - numer szyny i2c

0x20, 0x22 - adresy układów MCP


0x00 - numer rejestru układu MCP, akurat rejestr 0x00 to IODIRA (zgodnie ze specyfikacją układu MCP), który odpowiada za sposób działania pinów GPA0-7. Piny układów w MCP sterowane są niezależnie po 8 - osobno GPA07 i GPB0-7. Aby ustawić tryby działania dla pinów GPB0-7 musielibyśmy wpisać wartości do rejestru IODIRB, którego adres to 0x01

0x00 - wartość wpisywana do odpowiedniego rejestru - ustawiamy w tryb wyjścia 8 pinów. 0 binarne odpowiada wyjściu, 1 binarne odpowiada wejściu. ustawiamy wszystkie piny jako wyjścia, czyli binarnie 00000000, szesnastkowo 0x00.

Po ustawieniu trybów działania pinów, możemy na wyjściach ustawić stan wysoki, co załączy nasz klucz tranzystorowy i uruchomi przekaźnik diodę. Dioda podłączona jest do pinu GPA1 układu o adresie 0x20.

Binarnie zatem chcemy mieć stan 00000010 na wyjściach GPA0-7, daje nam to 0x02 szesnastkowo

Aby ją załączyć wydajemy polecenie:

i2cset -y 1 0x20 0x14 0x02
0x14 - adres rejestru OLATA, który odpowiada za ustawianie wartości na pinach GPA0-7

Aby wyłączyć diodę będzie to polecenie:

i2cset -y 1 0x20 0x14 0x00

Dla przekaźnika będą to odpowiednio polecenia:

i2cset -y 1 0x22 0x14 0x02

i2cset -y 1 0x22 0x14 0x00


W ten sposób możemy zarządzać 32 dodatkowymi wyjściami z Raspberry PI, które mogą załączać zewnętrznie zasilane urządzenia. W razie potrzeby możemy dodawać więcej układów zmieniając jedynie adresację. Daje nam to na prawdę bardzo szerokie możliwości.


Układy MCP23017 można zasilać również napięciem 3,3V.

Wtedy na wyjściach stan wysoki to również 3,3V

Jako że do układu zastosowałem tranzystory IRF540N, których minimalne napięcie załączenia to około 4V ja musiałem podłączyć je do 5V.

Docelowo planuję wytrawić płytkę z 32 wyjściami, którą zastąpię arduino oraz ethernet shield co powinno znacznie uprościć cały układ mojej domowej automatyki. Dodatkowo dodanie jakichkolwiek urządzeń dodatkowych nie będzie wymagało przeprogramowywania arduino, co jest dość uciążliwe. Będzie można to zrobić zdalnie przez SSH logując się jedynie do raspberry PI.



1 komentarz:

  1. Rozpocząłem zabawe z MCP i nie bardzo rozumiem o co chodzi IOCON.BANK. W twoim przypadku IOCON.BANK=0 bo np. dla OLATA adres rejestru jest 14h. Czy ten BANK ustala tylko kolejność adresów rejestrów?

    OdpowiedzUsuń