Spisu treści:

IO Expander dla ESP32, ESP8266 i Arduino: 24 kroki
IO Expander dla ESP32, ESP8266 i Arduino: 24 kroki

Wideo: IO Expander dla ESP32, ESP8266 i Arduino: 24 kroki

Wideo: IO Expander dla ESP32, ESP8266 i Arduino: 24 kroki
Wideo: Control 32 Servo over Wi-Fi using ESP32 and PCA9685 via desktop or mobile phone V5 2024, Lipiec
Anonim
Image
Image
Wstęp
Wstęp

Czy chciałbyś rozszerzyć IO swojego ESP32, ESP8266 lub Arduino? A czy myślałeś o możliwości 16 nowych GPIO, którymi można sterować za pomocą magistrali I2C? Cóż, dzisiaj przedstawię wam ekspander GPIO MCP23016. Pokażę również, jak komunikować się z mikrokontrolerem z MCP23016. Opowiem też o stworzeniu programu, w którym będziemy używać tylko 2 pinów tego mikrokontrolera do komunikacji z ekspanderem. Wykorzystamy je do sterowania diodami LED i przyciskiem.

Krok 1: Wprowadzenie

Urządzenie MCP23016 zapewnia 16 bitów do rozszerzenia GPIO za pomocą magistrali I2C. Każdy bit można skonfigurować indywidualnie (wejście lub wyjście).

MCP23016 składa się z wielu 8-bitowych ustawień do wyboru wejścia, wyjścia i polaryzacji.

Ekspandery stanowią proste rozwiązanie, gdy potrzebne są IO między innymi dla przełączników, czujników, przycisków i diod LED.

Krok 2: Charakterystyka

16 pinów wejściowych / wyjściowych (16 standardowych wejść)

Szybka częstotliwość zegara magistrali I2C (0-400 kbit/s)

Trzy sprzętowe piny adresowe pozwalają na użycie do ośmiu urządzeń

Rejestrator przechwytywania portów przerwań

Rejestr odwrócenia polaryzacji do ustawiania polaryzacji danych portu wejściowego

Kompatybilny z większością mikrokontrolerów

Krok 3: ESP01 może mieć 128 GPIO

ESP01 może mieć 128 GPIO!
ESP01 może mieć 128 GPIO!

Przykładem pokazującym wielkość tego ekspandera jest jego użycie z ESP01, do którego można podłączyć do ośmiu ekspanderów za pomocą tylko dwóch IOS, osiągając 128 GPIO.

Krok 4: MCP23016

MCP23016
MCP23016

Tutaj mamy schemat ekspandera, który ma dwie grupy po osiem bitów. Daje to w sumie 16 portów. Oprócz styku przerwania ma styk CLK, który łączy kondensator i rezystor, które są wewnętrznie połączone w porcie logicznym. Ma to na celu utworzenie zegara, wykorzystującego ideę oscylatora kwarcowego, który potrzebuje zegara 1 MHz. Pin TP służy do pomiaru zegara. Piny A0, A1 i A2 są adresami binarnymi.

Krok 5: ZEGAR

ZEGAR
ZEGAR
ZEGAR
ZEGAR

Dlatego MCP23016 wykorzystuje zewnętrzny obwód RC do określenia prędkości wewnętrznego zegara. Do prawidłowego działania urządzenia wymagany jest (zazwyczaj) zegar wewnętrzny 1 MHz. Zegar wewnętrzny można zmierzyć na pinie TP. Zalecane wartości dla REXT i CEXT przedstawiono poniżej.

Krok 6: Adres

Aby zdefiniować adres MCP23016, używamy następnie pinów A0, A1 i A2. Po prostu zostaw je na HIGH lub LOW, aby zmienić adres.

Adres zostanie utworzony w następujący sposób:

MCP_Address = 20 + (A0 A1 A2)

Gdzie A0 A1 A2 może przyjmować wartości HIGH / LOW, tworzy to liczbę binarną od 0 do 7.

Na przykład:

A0>GND, A1>GND, A2>GND (czyli 000, potem 20 + 0 = 20)

Albo, A0> HIGH, A1> GND, A2> HIGH (czyli 101, a następnie 20 + 5 = 25)

Krok 7: Polecenia

Polecenia
Polecenia

Poniżej znajduje się tabela z poleceniami do komunikacji. Użyjmy GP0 i GP1, a także IODIR0 i IODIR1.

Krok 8: Kategorie:

GP0 / GP1 - Rejestry portów danych

Istnieją dwa rejestry, które zapewniają dostęp do dwóch portów GPIO.

Odczyt rejestru dostarcza stan pinów na tym porcie.

Bit = 1> WYSOKI Bit = 0> NISKI

OLAT0 / OLAT1 - WYJŚCIE ZATRZYMANIE REJESTRÓW

Istnieją dwa rejestry, które zapewniają dostęp do portów wyjściowych obu portów.

IPOL0 / IPOL1 - Rejestry polaryzacji wejściowej

Rejestry te pozwalają użytkownikowi skonfigurować polaryzację danych portu wejściowego (GP0 i GP1).

IODIR0 / IODIR1

Istnieją dwa rejestry, które kontrolują tryb pin. (Wejście lub Wyjście)

Bit = 1> WEJŚCIE Bit = 0> WYJŚCIE

INTCAP0 / INTCAP1 - rejestry przechwytywania przerwań

Są to rejestry zawierające wartość portu, który wygenerował przerwanie.

IOCON0 / IOCON1 - Rejestr kontrolny ekspandera we / wy

Kontroluje to funkcjonalność MCP23016.

Ustawienie bitu 0 (IARES> Interrupt Activity Resolution) kontroluje częstotliwość próbkowania pinów portu GP.

Bit0 = 0> (domyślnie) Maksymalny czas wykrywania aktywności portu to 32 ms (niskie zużycie energii)

Bit0 = 1> maksymalny czas wykrywania aktywności na porcie to 200usec (większe zużycie energii)

Krok 9: Struktura komunikacji

Struktura komunikacji
Struktura komunikacji

Pokazuję tutaj klasę Wire, która jest komunikacją I2C w naszym rdzeniu Arduino, co pozwala również ekspanderowi współpracować z Arduino Uno i Mega. Jednak ten ostatni ma już kilka IO. Zajmujemy się tutaj adresami chipa, kontrolą dostępu, czyli kodami rejestrów, a także danymi.

Krok 10: Program

Program
Program

Nasz program polega na komunikacji ESP32 z MCP23016, aby mieć więcej GPIO do użycia. Następnie do MCP23016 będzie podłączony przycisk i kilka diod LED. Wszystkimi nimi będziemy sterować tylko za pomocą magistrali I2C. W ten sposób zostaną użyte tylko dwa piny ESP32. Możesz zobaczyć obwód obrazu poniżej w filmie.

Krok 11: ESP01

ESP01
ESP01

Tutaj pokazuję pinout ESP01.

Krok 12: Montaż ESP01

Montaż ESP01
Montaż ESP01

W tym przykładzie mamy podłączone GPIO0 w SDA i GPIO2 podłączone w SCL. Mamy również płytkę przekaźników, brzęczyk i diodę LED. Na drugim porcie, w GP1.0, mamy jeszcze jedną diodę LED z rezystorem.

Krok 13: NodeMCU ESP-12E

NodeMCU ESP-12E
NodeMCU ESP-12E

Tutaj mamy pinout NodeMCU ESP-12E.

Krok 14: Montaż NodeMCU ESP-12E

Węzeł montażowy MCU ESP-12E
Węzeł montażowy MCU ESP-12E

W tym przypadku jedyną różnicą w stosunku do pierwszego przykładu jest to, że połączyłeś D1 i D2 odpowiednio w SDA i SCL.

Krok 15: Wi-Fi NodeMCU-32S ESP-WROOM-32

Węzeł WiFiMCU-32S ESP-WROOM-32
Węzeł WiFiMCU-32S ESP-WROOM-32

Oto pinout WiFi NodeMCU-32S ESP-WROOM-32.

Krok 16: Węzeł montażowy WiFiMCU-32S ESP-WROOM-32

Węzeł montażowy WiFiMCU-32S ESP-WROOM-32
Węzeł montażowy WiFiMCU-32S ESP-WROOM-32

Tym razem główną różnicą w stosunku do pozostałych dwóch przykładów jest przycisk i trzy migające diody. Tutaj SDA jest podłączony do GPIO19, podczas gdy SCL jest podłączony do GPIO23.

Krok 17: Biblioteki i zmienne

Najpierw dołączymy Wire.h, który odpowiada za komunikację i2c, a także ustawienie adresu i2c MCP23016. Pokazuję kilka poleceń, nawet tych, których nie używamy w tym projekcie.

#include // określ użycie biblioteki Wire.h. //endereço I2C do MCP23016 #define MCPAddress 0x20 // COMMAND BYTE TO REJESTRACJA RELACJI: Tabela: 1-3 Microchip MCP23016 - DS20090A //ENDEREÇOS DE REGISTRADORES #define GP0 0x00 // DATA PORT REGISTER 0 #define GP1 0 REJESTR PORTÓW 1 #define OLAT0 0x02 // REJESTR ZATRZASKÓW WYJŚCIA 0 #define OLAT1 0x03 // REJESTR ZATRZASKÓW WYJŚĆ 1 #define IPOL0 0x04 // POLARYZACJA WEJŚCIA REJESTR PORTÓW 0 #define IPOL1 0x05 // POLARYZACJA WEJŚCIA 0 #define REJESTR PORTU / REJESTR KIERUNKÓW WE/WY 0 #define IODIR1 0x07 // REJESTR KIERUNKÓW WE/WY 1 #define INTCAP0 0x08 // REJESTR PRZERWANIA PRZECHWYTYWANIA 0 #define INTCAP1 0x09 // REJESTR PRZERWANIA PRZECHWYTYWANIA 1 #define IOCON0 0x0A // STEROWANIE EKSPANDEREM WE/WY REJESTR 0 #define IOCON1 0x0B // REJESTR STEROWANIA EKSPANDEREM WE/WY 1

Krok 18: Konfiguracja

Tutaj mamy funkcje do inicjalizacji czterech różnych typów mikrokontrolerów. Sprawdzamy również częstotliwość, ustawiamy GPIO i ustawiamy piny. W Pętli sprawdzamy stan przycisku.

void setup() { Serial.begin(9600); opóźnienie (1000); Drut.początek(19, 23); //ESP32 // Wire.begin(D2, D1); //nodemcu ESP8266 // Wire.begin(); //arduino // Wire.begin(0, 2);//ESP-01 Wire.setClock(200000); //częstotliwość //configura o GPIO0 como OUTPUT (wszystko i wszystkie piny) configurePort(IODIR0, OUTPUT); //konfiguruj GPIO1 jako WEJŚCIE lub GP1.0 i połącz WYJŚCIE z wyjściami GP1 configurePort(IODIR1, 0x01); //ustaw wszystkie piny na GPIO0 como LOW writeBlockData(GP0, B00000000); //ustaw wszystkie piny na GPIO1 como LOW writeBlockData(GP1, B00000000); } void loop() { //weryfikuj botão GP przy naciskaniu checkButton(GP1); } // koniec pętli

Krok 19: Konfiguracja portu

W tym kroku konfigurujemy tryb pinów GPIO i identyfikujemy tryb portów.

//konfiguracja GPIO (GP0 lub GP1)//como parametro passamos: //port: GP0 lub GP1 //niestandardowe: INPUT dla wszystkich jako porty do GP Trabalharem como entrada // OUTPUT dla wszystkich jako portas do GP trabalharem como powiedział / / Niestandardowa wartość 0-255 wskazuje na tryb portów (1=WEJŚCIE, 0=WYJŚCIE) // np.: 0x01 lub B00000001 lub 1: wskazuje, jakie są apeny lub GPX.0, można przejść do wejścia lub przywrócić, że jest to void configurePort (uint8_t port, uint8_t niestandardowy) { if(niestandardowy == WEJŚCIE) { writeBlockData(port, 0xFF); } else if(custom == WYJŚCIE) { writeBlockData(port, 0x00); } else { writeBlockData(port, niestandardowy); } }

Krok 20: WriteBlockData i CheckButton

Tutaj przesyłamy dane do MCP23016 przez magistralę i2c, sprawdzamy stan przycisku i wskazujemy kolejny krok, biorąc pod uwagę stan wciśnięcia lub nie.

//envia dados para o MCP23016 através do barramento i2c//cmd: COMANDO (rejestrator) //data: dados (0-255) void writeBlockData(uint8_t cmd, uint8_t data) { Wire.beginTransmission(MCPAddress); Wire.write(cmd); Drut.zapis(dane); Wire.endTransmission(); opóźnienie(10); }

//weryfikuj botão do presji//parametro GP: GP0 lub GP1 void checkButton(uint8_t GP) { //załącz leitura do pino 0 bez GP fornecido uint8_t btn = readPin(0, GP); //sedź presją, ustaw para HIGH jako portas GP0 if(btn) { writeBlockData(GP0, B11111111); } //caso contrario deixa todas em estado LOW else{ writeBlockData(GP0, B00000000); } }

Krok 21: Odczytaj PIN i wartość od PIN

Mamy tutaj do czynienia z odczytem konkretnego pinu i powrotem wartości bitu na żądaną pozycję.

//faz a leitura de um pino específico//pin: pino desejado (0-7) //gp: GP0 lub GP1 //retorno: 0 lub 1 uint8_t readPin(uint8_t pin, uint8_t gp) { uint8_t statusGP = 0; Wire.beginTransmission(MCPAadres); Wire.write(gp); Wire.endTransmission(); Wire.requestFrom(MCPAadres, 1); // ler do chip 1 bajt statusGP = Wire.read(); zwraca wartośćFromPin(pin, statusGP); } //retorna o valor do bitu na posição desejada //pin: posição do bit (0-7) //statusGP: valor lido do GP (0-255) uint8_t valueFromPin(uint8_t pin, uint8_t statusGP) { return (statusGP & (0x0001 << szpilka)) == 0 ? 0:1; }

Krok 22: Program ESP8266

Stąd zobaczymy, jak powstał program, którego używaliśmy w ESP-01 oraz w nodeMCU ESP-12E, co pozwala nam zrozumieć, jak różnice między nimi są minimalne.

Zmodyfikujemy jedynie wiersz konstruktora komunikacyjnego i2c, który jest początkową metodą obiektu Wire.

Wystarczy odkomentować linię zgodnie z tabliczką, którą zamierzamy skompilować.

// Wire.begin(D2, D1); //nodemcu ESP8266// Wire.begin(0, 2); //ESP-01

Ustawiać

Zauważ, że konstruktor jest nadal wykomentowany. Dlatego odkomentuj zgodnie z twoją płytą (ESP-01 lub nodeMCU ESP12-E).

void setup() { Serial.begin(9600); opóźnienie (1000); // Wire.begin(D2, D1); //nodemcu ESP8266 // Wire.begin(0, 2); //ESP-01 Wire.setClock (200000); //częstotliwość //configura o GPIO0 como OUTPUT (wszystko i wszystkie piny) configurePort(IODIR0, OUTPUT); //configura o GPIO1 como OUTPUT (wszystkie piny) configurePort(IODIR1, OUTPUT); //ustaw wszystkie piny na GPIO0 como LOW writeBlockData(GP0, B00000000); //ustaw wszystkie piny na GPIO1 como LOW writeBlockData(GP1, B00000001); }

Pętla

W pętli zamieniamy piny co 1 sekundę. Tak więc, gdy pin0 GP0 jest włączony, styki GP1 są wyłączone. Gdy pin0 GP1 jest włączony, piny GP0 są wyłączone.

void loop() { //ustaw lub wybierz pin 7 do GP0 COMO WYSOKI i opóźniony LOW writeBlockData(GP0, B10000000); //ustaw wszystkie piny na GPIO1 como LOW writeBlockData(GP1, B00000000); opóźnienie (1000); //ustaw wszystkie piny na GPIO0 como LOW writeBlockData(GP0, B00000000); //ustaw na pin 0 do GP1 COMO WYSOKI i alternatywny tryb LOW writeBlockData(GP1, B00000001); opóźnienie (1000); } // koniec pętli

Krok 23: WAŻNE

Użyte zmienne i biblioteka są takie same jak w programie, który zrobiliśmy dla ESP32, a także metody configurePort i writeBlockData.

Krok 24: Pliki

Pobierz pliki:

PDF

INO (ESP8266)

INO (ESP32)

Zalecana: