Sommario:

IO Expander per ESP32, ESP8266 e Arduino: 24 passaggi
IO Expander per ESP32, ESP8266 e Arduino: 24 passaggi

Video: IO Expander per ESP32, ESP8266 e Arduino: 24 passaggi

Video: IO Expander per ESP32, ESP8266 e Arduino: 24 passaggi
Video: Flipper Zero Alternative? - m5stickC plus 🤯 #shorts 2024, Novembre
Anonim
Image
Image
introduzione
introduzione

Vorresti espandere gli IO del tuo ESP32, ESP8266 o Arduino? E hai pensato alla possibilità di 16 nuovi GPIO controllabili tramite bus I2C? Bene, oggi vi presenterò l'espansore GPIO MCP23016. Inoltre, ti mostrerò come comunicare un microcontrollore con l'MCP23016. Parlerò anche della creazione di un programma in cui utilizzeremo solo 2 pin di questo microcontrollore per comunicare con l'espansore. Li useremo per controllare i LED e il pulsante.

Passaggio 1: Introduzione

Il dispositivo MCP23016 fornisce 16 bit per l'espansione GPIO utilizzando il bus I2C. Ogni bit può essere configurato singolarmente (ingresso o uscita).

L'MCP23016 è costituito da più impostazioni a 8 bit per l'ingresso, l'uscita e la selezione della polarità.

Gli espansori forniscono una soluzione semplice quando sono necessari gli I/O per interruttori, sensori, pulsanti e LED, tra gli altri esempi.

Passaggio 2: caratteristiche

16 pin di ingresso/uscita (16 ingressi standard)

Frequenza di clock del bus I2C veloce (0-400 kbit/s)

Tre pin di indirizzo hardware consentono l'utilizzo di un massimo di otto dispositivi

Registratore di acquisizione porte di interruzione

Registro di inversione di polarità per l'impostazione della polarità dei dati della porta di ingresso

Compatibile con la maggior parte dei microcontrollori

Passaggio 3: ESP01 può avere 128 GPIO

ESP01 può avere 128 GPIO!
ESP01 può avere 128 GPIO!

Un esempio che mostra la grandezza di questo espansore è il suo utilizzo con ESP01, che può essere collegato a un massimo di otto espansioni con solo due IOS, raggiungendo 128 GPIO.

Passaggio 4: MCP23016

MCP23016
MCP23016

Qui abbiamo lo schema dell'espansore, che ha due gruppi di otto bit. Questo fa per un totale di 16 porte. Oltre a un pin di interrupt, ha il pin CLK, che collega il condensatore e il resistore, che sono collegati internamente in una porta logica. Questo serve per formare l'orologio, usando l'idea di un oscillatore a cristallo, che ha bisogno di un orologio da 1MHz. Il pin TP viene utilizzato per misurare l'orologio. I pin A0, A1 e A2 sono indirizzi binari.

Passaggio 5: OROLOGIO

OROLOGIO
OROLOGIO
OROLOGIO
OROLOGIO

L'MCP23016 utilizza quindi un circuito RC esterno per determinare la velocità del Clock interno. Per il corretto funzionamento del dispositivo è richiesto (di solito) un clock interno di 1 MHz. L'orologio interno può essere misurato sul pin TP. Di seguito sono riportati i valori consigliati per REXT e CEXT.

Passaggio 6: indirizzo

Per definire l'indirizzo dell'MCP23016, utilizziamo quindi i pin A0, A1 e A2. Lasciali su HIGH o LOW per il cambio di indirizzo.

L'indirizzo sarà formato come segue:

Indirizzo_MCP = 20 + (A0 A1 A2)

Dove A0 A1 A2 può assumere valori ALTO/BASSO, questo forma un numero binario da 0 a 7.

Per esempio:

A0> GND, A1> GND, A2> GND (significa 000, quindi 20 + 0 = 20)

O altro, A0> ALTO, A1> GND, A2> ALTO (che significa 101, quindi 20 + 5 = 25)

Passaggio 7: comandi

Comandi
Comandi

Di seguito una tabella con i comandi per la comunicazione. Usiamo GP0 e GP1, così come IODIR0 e IODIR1.

Passaggio 8: Categorie:

GP0 / GP1 - Registri porta dati

Ci sono due registri che forniscono l'accesso alle due porte GPIO.

La lettura del registro fornisce lo stato dei pin su quella porta.

Bit = 1> ALTO Bit = 0> BASSO

OLAT0 / OLAT1 - Uscita REGISTRI LACTCH

Ci sono due registri che forniscono l'accesso alle porte di uscita delle due porte.

IPOL0 / IPOL1 - Registri di polarità di ingresso

Questi registri consentono all'utente di configurare la polarità dei dati della porta di ingresso (GP0 e GP1).

IODIR0 / IODIR1

Ci sono due registri che controllano la modalità pin. (Ingresso o Uscita)

Bit = 1> INGRESSO Bit = 0> USCITA

INTCAP0 / INTCAP1 - Registri di cattura degli interrupt

Si tratta di registri che contengono il valore della porta che ha generato l'interrupt.

IOCON0 / IOCON1 - Registro di controllo espansione I/O

Questo controlla la funzionalità dell'MCP23016.

L'impostazione del bit 0 (IARES> Interrupt Activity Resolution) controlla la frequenza di campionamento dei pin della porta GP.

Bit0 = 0> (predefinito) Il tempo massimo di rilevamento dell'attività della porta è 32 ms (basso consumo energetico)

Bit0 = 1> il tempo massimo di rilevamento dell'attività sulla porta è 200usec (maggiore consumo energetico)

Passaggio 9: struttura per la comunicazione

Struttura per la comunicazione
Struttura per la comunicazione

Mostro qui la classe Wire, che è la comunicazione I2C nel nostro core Arduino, che consente anche all'espansore di funzionare con Arduino Uno e Mega. Tuttavia, quest'ultimo ha già diversi IO. Ci occupiamo qui degli indirizzi del chip, del controllo accessi, che sono i codici dei registri, oltre che dei dati.

Passaggio 10: programma

Programma
Programma

Il nostro programma consiste nel comunicare l'ESP32 con l'MCP23016 per avere più GPIO da utilizzare. Avremo quindi un pulsante e alcuni LED collegati all'MCP23016. Li controlleremo tutti utilizzando solo il bus I2C. Pertanto, verranno utilizzati solo due pin ESP32. Puoi vedere il circuito dell'immagine qui sotto nel video.

Passaggio 11: ESP01

ESP01
ESP01

Qui, mostro il Pinout di ESP01.

Passaggio 12: montaggio di ESP01

Montaggio ESP01
Montaggio ESP01

In questo esempio, abbiamo il GPIO0 connesso nell'SDA e il GPIO2 connesso nell'SCL. Abbiamo anche una scheda relè, un cicalino e un LED. Sull'altra porta, in GP1.0, abbiamo un LED in più con una resistenza.

Passaggio 13: NodeMCU ESP-12E

NodeMCU ESP-12E
NodeMCU ESP-12E

Qui abbiamo il pinout del NodeMCU ESP-12E.

Passaggio 14: montaggio di NodeMCU ESP-12E

Montaggio NodeMCU ESP-12E
Montaggio NodeMCU ESP-12E

In questo caso, l'unica differenza rispetto al primo esempio è che hai collegato D1 e D2 rispettivamente in SDA e SCL.

Passaggio 15: WiFi NodeMCU-32S ESP-WROOM-32

Nodo WiFiMCU-32S ESP-WROOM-32
Nodo WiFiMCU-32S ESP-WROOM-32

Ecco il pinout del WiFi NodeMCU-32S ESP-WROOM-32.

Passaggio 16: montaggio WiFi NodeMCU-32S ESP-WROOM-32

Nodo di montaggio WiFiMCU-32S ESP-WROOM-32
Nodo di montaggio WiFiMCU-32S ESP-WROOM-32

Questa volta, la differenza principale rispetto agli altri due esempi è il pulsante e i tre LED lampeggianti. Qui, l'SDA è collegato al GPIO19, mentre l'SCL è collegato al GPIO23.

Passaggio 17: librerie e variabili

Innanzitutto, includeremo Wire.h, che è responsabile della comunicazione i2c, nonché dell'impostazione dell'indirizzo i2c di MCP23016. Mostro diversi comandi, anche alcuni che non usiamo in questo progetto.

#include // specifica l'uso della libreria Wire.h. //endereço I2C do MCP23016 #define MCPAddress 0x20 // BYTE DI COMANDO PER REGISTRARE RELAZIONE: Tabella: 1-3 di Microchip MCP23016 - DS20090A //ENDEREÇOS DE REGISTRADORES #define GP0 0x00 // DATA PORT REGISTER 0 #define GP1 0x01 // DATA PORT REGISTER 1 #define OLAT0 0x02 // OUTPUT LATCH REGISTER 0 #define OLAT1 0x03 // OUTPUT LATCH REGISTER 1 #define IPOL0 0x04 // POLARITÀ INGRESSO PORT REGISTER 0 #define IPOL1 0x05 // POLARITÀ INGRESSO PORT REGISTER 1 #define IODIR0 0x06 / / REGISTRO DIREZIONE I/O 0 #define IODIR1 0x07 // REGISTRO DIREZIONE I/O 1 #define INTCAP0 0x08 // REGISTRO DI CATTURA INTERROMPI 0 #define INTCAP1 0x09 // REGISTRO DI CATTURA INTERROMPI 1 #define IOCON0 0x0A // CONTROLLO ESPANSIONE I/O REGISTRO 0 #define IOCON1 0x0B // CONTROLLO ESPANSIONE I/O REGISTRO 1

Passaggio 18: configurazione

Qui abbiamo le funzioni per inizializzare quattro diversi tipi di microcontrollori. Controlliamo anche la frequenza, impostiamo i GPIO e impostiamo i pin. Nel Loop, controlliamo lo stato del pulsante.

void setup() { Serial.begin(9600); ritardo(1000); Wire.begin(19, 23); //ESP32 // Wire.begin(D2, D1); //nodemcu ESP8266 // Wire.begin(); //arduino // Wire.begin(0, 2);//ESP-01 Wire.setClock(200000); //frequenza //configura o GPIO0 come OUTPUT (tutti i pin) configurePort(IODIR0, OUTPUT); //configura o GPIO1 como INPUT o GP1.0 e como OUTPUT os outros GP1 configurePort(IODIR1, 0x01); //seta tutto quello che vuoi fare GPIO0 come LOW writeBlockData(GP0, B00000000); //seta tutto quello che vuoi fare GPIO1 come LOW writeBlockData(GP1, B00000000); } void loop() { //verifica e o botão GP se premuto checkButton(GP1); } // termina il ciclo

Passaggio 19: configurazione della porta

In questo passaggio, configuriamo la modalità dei pin GPIO e identifichiamo la modalità delle porte.

//configura o GPIO (GP0 ou GP1)//como parametro passamos: //port: GP0 ou GP1 //custom: INPUT para tutto come porta GP trabalharem come entrada // OUTPUT para tutto come porta GP trabalharem come detto / / custom um valor de 0-255 indicando o modo das portas (1=INPUT, 0=OUTPUT) // es: 0x01 o B00000001 o 1: indica que apenas o GPX.0 trabalhará come entrada, o restando come saida void configurePort(uint8_t port, uint8_t custom) { if(custom == INPUT) { writeBlockData(port, 0xFF); } else if(custom == OUTPUT) { writeBlockData(port, 0x00); } else { writeBlockData (porta, personalizzato); } }

Passaggio 20: WriteBlockData e CheckButton

Qui, inviamo i dati all'MCP23016 tramite il bus i2c, controlliamo lo stato del pulsante e indichiamo il passaggio successivo tenendo conto della condizione di essere premuto o meno.

//envia dados para o MCP23016 através do barramento i2c//cmd: COMANDO (registrador) //data: dados (0-255) void writeBlockData(uint8_t cmd, uint8_t data) { Wire.beginTransmission(MCPAddress); Wire.write(cmd); Wire.write(dati); Wire.endTransmission(); ritardo(10); }

//verifica se o botão foi pressionado//parametro GP: GP0 ou GP1 void checkButton(uint8_t GP) { //faz a leitura do pino 0 no GP fornecido uint8_t btn = readPin(0, GP); //se premuto, setta per HIGH come portas GP0 if(btn) { writeBlockData(GP0, B11111111); } //caso contrario deixa todas em stado LOW else{ writeBlockData(GP0, B00000000); } }

Passaggio 21: LeggiPin e valore daPin

Ci occupiamo qui della lettura di uno specifico pin, e del ritorno del valore del bit nella posizione desiderata.

//faz a leitura de um pino específico//pin: pino desejado (0-7) //gp: GP0 ou GP1 //retorno: 0 ou 1 uint8_t readPin(uint8_t pin, uint8_t gp) { uint8_t statusGP = 0; Wire.beginTransmission(MCPAddress); Wire.write(gp); Wire.endTransmission(); Wire.requestFrom(MCPAddress, 1); // ler do chip 1 byte statusGP = Wire.read(); restituisce valueFromPin(pin, statusGP); } //retorna o valor do bit na posizione desejada //pin: posizione do bit (0-7) //statusGP: valor lido do GP (0-255) uint8_t valueFromPin(uint8_t pin, uint8_t statusGP) { return (statusGP & (0x0001 << pin)) == 0 ? 0: 1; }

Passaggio 22: programma ESP8266

Da qui vedremo come è stato creato il programma che abbiamo usato in ESP-01 e nel nodeMCU ESP-12E, che ci permette di capire come le differenze tra loro siano minime.

Modificheremo solo la linea del costruttore di comunicazione i2c, che è il metodo iniziale dell'oggetto Wire.

Basta decommentare la riga in base alla targa che andremo a compilare.

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

Impostare

Notare che il builder è ancora commentato. Pertanto, decommenta in base alla tua scheda (ESP-01 o nodeMCU ESP12-E).

void setup() { Serial.begin(9600); ritardo(1000); // Wire.begin(D2, D1); //nodemcu ESP8266 // Wire.begin(0, 2); //ESP-01 Wire.setClock(200000); //frequenza //configura o GPIO0 come OUTPUT (tutti i pin) configurePort(IODIR0, OUTPUT); //configura o GPIO1 come OUTPUT (tutti i pin) configurePort(IODIR1, OUTPUT); //seta tutto quello che vuoi fare GPIO0 come LOW writeBlockData(GP0, B00000000); //seta tutto quello che vuoi fare GPIO1 come LOW writeBlockData(GP1, B00000001); }

Ciclo continuo

Nel loop, cambiamo i pin ogni 1 secondo. Quindi, quando il pin0 di GP0 è acceso, i pin di GP1 sono spenti. Quando il pin0 di GP1 è acceso, i pin GP0 sono spenti.

void loop() { //seta o pino 7 do GP0 come HIGH e os demais come LOW writeBlockData(GP0, B10000000); //seta tutto quello che vuoi fare GPIO1 come LOW writeBlockData(GP1, B00000000); ritardo(1000); //seta tutto quello che vuoi fare GPIO0 come LOW writeBlockData(GP0, B00000000); //seta o pino 0 do GP1 come HIGH e os demais come LOW writeBlockData(GP1, B00000001); ritardo(1000); } // termina il ciclo

Passaggio 23: IMPORTANTE

Le variabili e la libreria utilizzate sono le stesse del programma che abbiamo fatto per ESP32, così come i metodi configurePort e writeBlockData.

Passaggio 24: file

Scarica i file:

PDF

INO (ESP8266)

INO (ESP32)

Consigliato: