logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Moduł expandera portów PCF8574 - PlatformIO tutorial - rozszerzenie pinów Arduino/ESP/itd

p.kaczmarek2 17 Sty 2025 21:29 2880 11

TL;DR

  • PCF8574 rozszerza piny I/O Arduino i ESP8266/ESP przez I2C, oferując 8 konfigurowalnych wejść/wyjść oraz opcjonalny sygnał INT.
  • Przykłady na NodeMCU z ESP8266 pokazują skan I2C, konfigurację pinów przez bibliotekę Renzo Mischianti oraz obsługę wyjść, przycisku i przerwania.
  • Jeden adres PCF8574 daje 8 linii, osiem układów na jednej magistrali daje 64 piny, a wersja z alternatywnym adresem sięga 128.
  • Demonstracje potwierdzają działanie: dioda miga, odliczanie binarne działa, a INT wyzwala odczyt wejść dopiero po zboczu opadającym.
  • Sterowanie bajtem przez digitalWriteAllBytes okazało się prywatne, więc użyto pętli digitalWrite; moduł ma też wbudowane rezystory podciągające.
Wygenerowane przez model językowy.
REKLAMA
📢 Słuchaj (AI):
  • Kilka modułów PCF8574 z wyprowadzonymi goldpinami
    Przedstawię tutaj prosty w użyciu moduł pozwalający na uzyskanie dodatkowych portów I/O. Jeden PCF8574 sterowany jest tylko dwoma sygnałami, a daje nam aż całe 8 konfigurowalnych wejść/wyjść razem z dodatkowym opcjonalnym sygnałem przerwania. Co więcej, dwa piny mogą wysterować jednocześnie aż osiem PCF8574, co daje nam w sumie 64 piny, a połączeniu z wersją alternatywnym adresie do 128 pinów! Warto też wiedzieć, że nic nie stoi na przeszkodzie, by razem z PCF8574 na magistrali I2C podłączyć inne urządzenia, takie jak przykładowo czujniki czy tam zegar RTC... ale po kolei.

    PCF8574 to tzw. ekspander IO, czyli układ który odpowiednio sterowany pozwala nam uzyskać dodatkowe piny wejścia/wyjścia w naszym projekcie. PCF8574 konkretnie sterowany jest za pomocą magistrali I2C, czyli magistrali opierającej się o dwa sygnały (zegar i dane) i pozwalającej obsłużyć wiele urządzeń jednocześnie - do jednej linii I2C można podłączyć wiele układów o ile ich adresy nie kolidują.
    PCF pracuje na napięciu od 2,5 V do 6 V, więc nie powinno być problemów z jego uruchomieniem zarówno z klasycznym Arduino, jak i z ESP8266.
    Rozważmy wyprowadzenia PCF8574:
    Schemat układu PCF8574 z magistralą I2C.
    SDA i SCL to obowiązkowe linie I2C, nim sterujemy tym układem. P0-P7 to nóżki układu którymi sterujemy, mogą być w roli wejść i wyjść cyfrowych. Piny A0, A1, A2 pozwalają nam zmienić adres danej sztuki PCF, dzięki czemu można podłączyć ich więcej na jedną magistralę:
    Tabela adresów I2C dla PCF8574 z ustawieniami wejść A2, A1, A0.
    PCF oferuje cztery tryby pracy GPIO:
    Opis czterech trybów pracy portów w PCF8574.
    Dla bardziej zaawansowanych użytkowników warto jest też przedstawić dokładniejszy schemat, który uwzględnia też rezystory podciągające linii od I2C:
    Schemat aplikacji układu PCF8574 z podłączonymi rezystorami i urządzeniami.
    Z ciekawostek dodam, że nota katalogowa też proponuje układ PCB pod expander:
    Schemat połączeń PCF8574
    Tu jednak skorzystam z gotowego modułu, który wszystko znacznie uprości.


    Moduł PCF8574
    Ogólnodostępny w sprzedaży moduł PCF8574 wyprowadza wszystkie jego nóżki na goldpiny, co zwalnia nas z obowiązku lutowania. Wyprowadzone są wszystkie IO, wyjście przerwania, piny adresowe oraz magistrala I2C - i to z dwóch stron. Wspomniane rezystory podciągające też są na pokładzie.
    Kilka modułów PCF8574 z wyprowadzonymi goldpinami
    Moduły PCF8574 z żółtymi złączami na białym tle
    Moduły PCF8574 na płytkach prototypowych.
    Moduł można dostać za kilka złotych. Sprowadzając zza granicy można nawet dostać 5 sztuk za 10-20 zł, zależnie od promocji.
    Zdjęcie pięciu modułów PCF8574 na białym tle.
    Zestaw modułów PCF8574 zapakowanych w przezroczyste torebki foliowe.


    Platforma do demonstracji
    Z reguły tego typu prezentację wykonywałem na Arduino, ale tym razem pokusiłem się o NodeMCU z ESP8266. I tak wyjdzie prawie na to samo, ale moim zdaniem PlatformIO jest nieco wygodniejsze od Arduino IDE, a znajomość Visual Code przyda się też do innych języków. Przypomnijmy temat, gdzie już PlatformIO prezentowałem:
    Zegar na ESP12 i wyświetlaczu MAX7219 - tutorial - część 1, ArduinoOTA, podstawy
    Jak programować płytkę Wemos D1 (ESP8266) w kształcie Arduino? ArduinoOTA w PlatformIO
    Użyta płytka:
    Moduł ESP8266 podłączony do płytki stykowej.


    Skan I2C
    Użycie expandera jest bardzo proste, ale użytkownicy często gubią się przez adresy I2C. Z tego powodu na początek zawsze proponuję uruchomienie skanera I2C. Ten prosty program zweryfikuje nasze połączenia oraz wyświetli adresy I2C urządzeń podłączonych do magistrali. To powie nam, czy chociaż sprzętowo sytuacja jest okej, bo łatwo jest zamienić SCL z SDA lub coś źle podłączyć...
    Tu moje podłączenie:
    Moduł PCF8574 z podłączonymi przewodami.
    No i wspomniany skaner:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Działa, adres układu jest widziany:
    Zrzut ekranu z terminala pokazujący wyniki skanowania I2C.
    Teraz to samo, ale w przypadku pięciu expanderów z różnymi adresami. Podłączenie jest banalnie proste:
    Zdjęcie ośmiu modułów PCF8574 połączonych szeregowo.
    Rezultat:
    
    Scanning...
    I2C device found at address 0x20
    I2C device found at address 0x21
    I2C device found at address 0x22
    I2C device found at address 0x24
    I2C device found at address 0x26
    

    Wszystkie expandery są widziane.





    Dodajemy bibliotekę PCF8574
    Dodawanie biblioteki w PlatformIO już wcześniej omawiałem, ale zasadniczo to wykonuje się to poprzez Libraries, wystarczy wyklikać. W wyszukiwarkę wpisujemy PCF8574 i dodajemy najlepiej ten sam wynik co u mnie na zrzucie ekranu (by Renzo Mischianti):
    Zrzut ekranu z PlatformIO, pokazujący bibliotekę PCF8574 autorstwa Renzo Mischianti.
    Wyszukiwarka może pokazać wcześniej też bibliotekę od LCD 2x16 sterowanego przez PCF8574, ale nam zależy na samym sterowaniu PCF8574. LCD uruchomimy innym razem.
    Przy dodawaniu biblioteki można zapoznać się z jej przykładami, ale sam też przygotowałem poniżej kilka uproszczonych demonstracji.





    Blink
    Proponowaną przeze mnie bibliotekę (autorstwa Renzo Mischianti) charakteryzuje składnia do złudzenia przypominająca piny z Arduino, czyli mamy tu dalej nasze słynne pinMode, digitalWrite i digitalRead, tyle że nie jako funkcje globalne, tylko na obiekcie klasy PCF8574. Aby uruchomić PCF8574 korzystamy z konstruktora, który na moim przykładzie za argumenty pobiera adres I2C urządzenia oraz piny SDA i SCL:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Uruchomienie PCFa, powie nam ono, czy go dobrze podłączyliśmy oraz czy adres się zgadza:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Ustawienie trybu pracy pinu wygląda tak jak już wcześniej wspomniałem:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Analogicznie ustawienie wartości na wyjściu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Pełny kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Raczej nie ma tu co komentować, dioda po prostu mruga:



    Oczywiście dioda podłączona z rezystorem - dałem około 300 omów, by nie spalić diody.



    Odliczanie binarne
    To teraz pomigajmy wszystkimi diodami. Nie jest to chyba konieczne, ale kusiło mnie odpalenie w ten sposób jakiejś prostej animacji. Zróbmy odliczanie binarne.
    Tu nastąpił pierwszy zgrzyt, bo myślałem, że wystawię bajt na piny IO, tak jakbym to zrobił normalnie na mikrokontrolerze, ale funkcja z klasy PCF8574 jest prywatna...
    
    src\main.cpp: In function 'void loop()':
    src\main.cpp:29:33: error: 'bool PCF8574::digitalWriteAllBytes(byte)' is private within this context
       29 |   pcf8574.digitalWriteAllBytes(x);
    

    Ostatecznie użyłem wywołań digitalWrite w pętli... ale to zostawiam do samodzielnej interpretacji.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Działa:



    PS: Teraz widzę, że zdefiniowanie PCF8574_LOW_MEMORY by może pomogło i wystawiło funkcję przyjmującą bajt, zostawiam to do wypróbowania Wam.

    Przycisk
    Skoro było digitalWrite, to mamy też digitalRead. Co więcej, nie musimy sami podłączać rezystora pull-up, gdyż układ sam "ściaga" wejścia na potencjał logicznego 1. My jedynie możemy zwierać je do masy (np. przyciskiem) i wtedy uzyskamy na nim stan niski. Dzięki temu nie musimy samodzielnie podłączać rezystora.
    Fragment karty katalogowej opisujący reset i inicjalizację I/O układu z wewnętrznym źródłem prądu.
    A więc podłączyłem:
    - przycisk między GPIO a masą
    - dodatkowo, tylko dla wizualizacji, diodę LED na drugim GPIO wraz z rezystorem kilkaset omów
    Uruchomienie pinów:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Pętla, odczyt GPIO, wypisywanie na konsolę (na UART), oraz ustawienie drugiego pinu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Działa, tyle że przycisk zwolniony tu oznacza stan 1, więc dioda jest zapalona, a wciśnięty przycisk to stan 0 - dioda zgaszona.





    Przycisk i przerwanie
    Zostaje do omówienia pin INT od PCF8574. Na tym pinie pojawi się zbocze opadające gdy zmieni się coś na wejściu PCF8574. Można to użyć w połączeniu z przerwaniem GPIO na naszym NodeMCU by otrzymać informacje o tym, że coś się przy PCF8574 zadziało, przykładowo ktoś wcisnął przycisk.
    Podłączamy zatem INT do, powiedzmy, GPIO5. Teraz trzeba uruchomić przerwanie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Funkcja interruptHandler wywoła się gdy na D5 będzie zbocze opadające (FALLING):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Tutaj w celach demonstracyjnych tylko ustawiam zmienną, której potem używam do sprawdzenia w głównej pętli, czy trzeba odczytać ponownie piny PCFa.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Działanie jest dość podobne do poprzedniego przykładu, tyle, że pętla sprawdza stan pinów tylko po otrzymaniu przerwania.

    W ten sposób można obsłużyć więcej pinów - oto przykład z dokumentacji użytej biblioteki:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Zwalnia to nas z obowiązku wykonywania skanu digitalReadAll co odświeżenie.

    Czy można podłączyć jeszcze więcej wyjść/wejść?
    Na rynku jest też dostępna wersja układu z innym adresowaniem, co w sumie daje nam 128 kontrolowanych pinów:
    Informacja o ekspanderach I/O PCF8574 i PCF8574A.


    Podsumowanie
    Przydatny i prosty w użyciu moduł. Wszystko co potrzeba jest wyprowadzone na goldpiny, a i wybór adresu jest dość szeroki. Przy 8 sztukach można wysterować całe 64 odbiorniki, czy ktoś będzie potrzebować więcej?
    Warto też wspomnieć, że pokazany tu moduł potrafi znacznie więcej - w użytej bibliotece jest nawet demko enkodera, ale nie miałem żadnego pod ręką by je dzisiaj wypróbować:
    Spoiler:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Ale nawet i bez tego mogę stwierdzić, że to bardzo przydatny układ. A jak Wy uważacie? Czy korzystaliście w swoich projektach z PCF8574 a jeśli tak to do czego?

    Fajne? Ranking DIY
    Pomogłem? Kup mi kawę.
    O autorze
    p.kaczmarek2
    Moderator Smart Home
    Offline 
    Inżynier programista z wieloletnim doświadczeniem embedded i full stack developer.
    Specjalizuje się w: embedded, Full-Stack Developer
    p.kaczmarek2 napisał 14627 postów o ocenie 12646, pomógł 655 razy. Jest z nami od 2014 roku.
  • REKLAMA
  • #2 21398046
    _ACeK_
    Poziom 15  
    Posty: 164
    Pomógł: 6
    Ocena: 194
    :) Wiele lat temu tasza opracowała bardzo fajny ⇨ układ LXT ⇦ Mam nawet juz troche zmieniona plytke do niego ;)

    Schemat układu elektronicznego LXT z kolorowymi ścieżkami.
  • REKLAMA
  • #3 21398168
    p.kaczmarek2
    Moderator Smart Home
    Posty: 14627
    Pomógł: 655
    Ocena: 12646
    Fajny projekt, czysta klasyka. Otworzyłem załącznik i widzę pliki datowane na 2004:
    Lista plików źródłowych w oprogramowaniu do zarządzania plikami ZIP.
    Jeszcze ten MAX232... pamiętam jak jeszcze w czasach szkolnych uruchamiałem MAX232 i dziwiłem się tym podłączeniem kondensatora elektrolitycznego, który jest celowo odwrócony polaryzacją. Wtedy myślałem, że jeszcze może z RS232 w tej formie będę korzystać, ale od tamtego momentu jadę tylko na konwerterach USB<->UART.

    Sam z kolei kiedyś zrobiłem projekt w oparciu o MCP23017, tam jest 16 pinów, ale reszta jest dość podobna do PCF:
    Płytka drukowana z przekaźnikami i okablowaniem.
    To płytka rozszerzeń do:
    Sterownik przekaźników kompatybilny z Home Assistant/Tasmota HTTP + obudowa
    Pomogłem? Kup mi kawę.
  • #4 21398236
    _ACeK_
    Poziom 15  
    Posty: 164
    Pomógł: 6
    Ocena: 194
    :) Nie chciałem podawać dokładnej daty, bo niewiasty z reguły nie lubią, jak porusza się temat wieku ;)

    Tak się składa, że w ciągu kilku dni mam zamiar zrobić ten układ :) Moja wersja będzie SMD z możliwością wyboru między MAX3232 a USB ;)

    Tu prawie skończona płytka ⇓

    Grafika przedstawiająca projekt płytki drukowanej z kolorowymi ścieżkami.

    Płytka PCB z elementami elektronicznymi na kolorowym tle.


    Zgromadzone części oraz płytka ⇑ ;)
  • #5 21398387
    p.kaczmarek2
    Moderator Smart Home
    Posty: 14627
    Pomógł: 655
    Ocena: 12646
    Jaką metodą wykonujesz PCB i jak docelowo chcesz zorganizować LEDy? Z tego co widzę to w oryginalnym projekcie brakuje nieco jakiegoś końcowego już efektu, gdzie LEDy są rzeczywiście jakoś ułożone w tytułowe "christmas tree", nie wiem, na jakimś mini-drzewku :D

    Choć dzisiaj i tak chyba prościej sięgnąć po WS2812 i najtańsze MCU, może zrobię jakiś projekt gdzie to z PIC12F spróbuję wysterować. PCF8574 bym już bardziej widział z przekaźnikami:
    Zestaw modułów przekaźnikowych różnych rozmiarów na białym tle.
    Pomogłem? Kup mi kawę.
  • REKLAMA
  • #6 21398560
    _ACeK_
    Poziom 15  
    Posty: 164
    Pomógł: 6
    Ocena: 194
    :) Rysuję w Illustrator. Potem termotransfer jak na zdjęciu ⇓

    Proces produkcji płytek elektronicznych metodą termotransferu z użyciem żelazka.

    Prototyp płytki stykowej z wyświetlaczem segmentowym i oznaczonymi pinami I2C.


    Układ będzie na razie układem samym w sobie :) Wyświetlacz jak na zdjęciu oznaczonej elipsie ⇑ Mam wyprowadzone piny I2C, dzięki czemu łatwo będę mógł podglądać, co się dzieje na magistrali ;)
  • #8 21398636
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #10 21399517
    Karol966
    Poziom 31  
    Posty: 2038
    Pomógł: 83
    Ocena: 645
    khoam napisał:
    Typowe rejestry przesuwne (jak 74HC595) obsługują tylko wyjścia,

    No ale możesz za pomocą dodatkowego pinu oraz wraz z użyciem najtańszych diod zrealizować również klawiaturę wraz z wyjściami. Na x164 robiłem taki coś. Do obsługi klawiatury, podobnie jak przy klawiaturze matrycowej, wysyłało się jeden stan (0/1 zależnie od koncepcji) i szukało na której pozycji wyjście klawiatury ma ten właśnie, szukany stan.
    Rejestry takie jak 595 mają tą zaletę, że można je również podłączyć pod sprzętowy SPI. Do prostych aplikacji, jak wyświetlanie stanu diod czy generalnie sterowanie mało ważnymi wyjściami takie rejestry przesuwne jak 595/164 są OK, cena niewielka wiec się kalkuluje. Przy bardziej restrykcyjnych osobiście stosuję już scalone expandery. Akurat PCF857x to taki dinozaur więc zdecydowanie wolę MCP23017. Niestety zo raz częściej zastanawiam się czy "to miało sens" bo dokładając niewiele do ceny procesora kupuję taki z większą ilością IO i ekspander staje się zbędny.

    Tylko potem płytka jakaś taka biedna, mało na niej się dzieje :D
  • #11 21429567
    Mocny Amper
    Poziom 11  
    Posty: 87
    Ocena: 19
    PCF8574 jest też dość powolny, niby może dostawać zegar max 100kHz, ale ja go używam w projekcie, gdzie I2C chodzi na 200kHz, i działa bez zarzutu, ale lekkie obawy mam.
    No i wydajność prądowa GPIO ekspandera w stanie wysokim jest nędzna, trzeba sterować "zerem".
    No i przydałby się jeszcze PWM, którego nie ma.
  • #12 21432429
    KarolGT
    Poziom 10  
    Posty: 38
    Ocena: 3
    Który ekspander jest lepszy, stabilniejszy?
    PCF8574 czy mcp23017 ?

    a może jeszcze jakiś inny, najlepiej na 16 pinów?

    Dodano po 1 [minuty]:

    Karol966 napisał:
    Przy bardziej restrykcyjnych osobiście stosuję już scalone expandery. Akurat PCF857x to taki dinozaur więc zdecydowanie wolę MCP23017. Niestety zo raz częściej zastanawiam się czy "to miało sens" bo dokładając niewiele do ceny procesora kupuję taki z większą ilością IO i ekspander staje się zbędny.

    Możesz rozwinąć? jakie scalone expandery?
    i o jakim procesorze mówisz z większą ilością IO zamiast expandera?
📢 Słuchaj (AI):

Podsumowanie tematu

✨ Moduł PCF8574 to ekspander I/O, który umożliwia uzyskanie dodatkowych 8 pinów wejścia/wyjścia za pomocą magistrali I2C, sterując jednocześnie do 8 takich układów, co daje 64 lub nawet 128 pinów. Użytkownicy dzielą się doświadczeniami z projektami opartymi na PCF8574 oraz MCP23017, wskazując na różnice w funkcjonalności, takie jak brak możliwości maskowania przerwań w PCF8574 oraz ograniczenia w wydajności prądowej. W dyskusji poruszono również alternatywne metody rozszerzania I/O, takie jak rejestry przesuwne (74HC595, 74HC165) oraz ich zastosowanie w różnych projektach. Uczestnicy wymieniają się pomysłami na wykorzystanie tych układów w praktycznych aplikacjach, takich jak sterowanie wyświetlaczami czy klawiaturami.
Wygenerowane przez model językowy.
REKLAMA