Tabla de contenido:

Expansor IO para ESP32, ESP8266 y Arduino: 24 pasos
Expansor IO para ESP32, ESP8266 y Arduino: 24 pasos

Video: Expansor IO para ESP32, ESP8266 y Arduino: 24 pasos

Video: Expansor IO para ESP32, ESP8266 y Arduino: 24 pasos
Video: Expansor de IO para arduino ou esp32, esp8266, esp01 2024, Noviembre
Anonim
Image
Image
Introducción
Introducción

¿Le gustaría expandir los IO de su ESP32, ESP8266 o Arduino? ¿Y ha pensado en la posibilidad de 16 nuevos GPIO que se pueden controlar mediante el bus I2C? Bueno, hoy les voy a presentar el expansor GPIO MCP23016. Además, le mostraré cómo comunicar un microcontrolador con el MCP23016. También hablaré sobre la creación de un programa en el que usaremos solo 2 pines de este microcontrolador para comunicarnos con el expansor. Los usaremos para controlar los LED y el botón.

Paso 1: Introducción

El dispositivo MCP23016 proporciona 16 bits para la expansión GPIO utilizando el bus I2C. Cada bit se puede configurar individualmente (entrada o salida).

El MCP23016 consta de múltiples configuraciones de 8 bits para la selección de entrada, salida y polaridad.

Los expansores brindan una solución simple cuando se necesitan IO para interruptores, sensores, botones y LED, entre otros ejemplos.

Paso 2: características

16 pines de entrada / salida (estándar de 16 entradas)

Frecuencia de reloj de bus I2C rápida (0-400 kbits / s)

Tres pines de dirección de hardware permiten el uso de hasta ocho dispositivos

Grabador de captura de puerto de interrupción

Registro de inversión de polaridad para configurar la polaridad de los datos del puerto de entrada

Compatible con la mayoría de microcontroladores

Paso 3: ¡ESP01 puede tener 128 GPIO

¡ESP01 puede tener 128 GPIO!
¡ESP01 puede tener 128 GPIO!

Un ejemplo que muestra la magnitud de este expansor es su uso con ESP01, el cual se puede conectar a hasta ocho expansores con solo dos IOS, llegando a 128 GPIOs.

Paso 4: MCP23016

MCP23016
MCP23016

Aquí tenemos el esquema del expansor, que tiene dos grupos de ocho bits. Esto hace un total de 16 puertos. Además de un pin de interrupción, tiene el pin CLK, que conecta el condensador y la resistencia, que están conectados internamente en un puerto lógico. Esto es para formar el reloj, usando la idea de un oscilador de cristal, que necesita un reloj de 1MHz. El pin TP se usa para medir el reloj. Los pines A0, A1 y A2 son direcciones binarias.

Paso 5: RELOJ

RELOJ
RELOJ
RELOJ
RELOJ

Por lo tanto, el MCP23016 utiliza un circuito RC externo para determinar la velocidad del reloj interno. Se requiere un reloj interno de 1 MHz (generalmente) para que el dispositivo funcione correctamente. El reloj interno se puede medir en el pin TP. Los valores recomendados para REXT y CEXT se muestran a continuación.

Paso 6: Dirección

Para definir la dirección del MCP23016, usamos los pines A0, A1 y A2. Déjelos en HIGH o LOW para el cambio de dirección.

La dirección se formará de la siguiente manera:

Dirección_MCP = 20 + (A0 A1 A2)

Donde A0 A1 A2 puede tomar valores HIGH / LOW, esto forma un número binario de 0 a 7.

Por ejemplo:

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

Si no, A0> HIGH, A1> GND, A2> HIGH (es decir 101, luego 20 + 5 = 25)

Paso 7: comandos

Comandos
Comandos

A continuación se muestra una tabla con los comandos de comunicación. Usemos GP0 y GP1, así como IODIR0 e IODIR1.

Paso 8: Categorías:

GP0 / GP1 - Registros de puerto de datos

Hay dos registros que proporcionan acceso a los dos puertos GPIO.

La lectura del registro proporciona el estado de los pines en ese puerto.

Bit = 1> ALTO Bit = 0> BAJO

OLAT0 / OLAT1 - Registros LACTCH de salida

Hay dos registros que proporcionan acceso a los puertos de salida de los dos puertos.

IPOL0 / IPOL1 - Registros de polaridad de entrada

Estos registros permiten al usuario configurar la polaridad de los datos del puerto de entrada (GP0 y GP1).

IODIR0 / IODIR1

Hay dos registros que controlan el modo pin. (Entrada o salida)

Bit = 1> ENTRADA Bit = 0> SALIDA

INTCAP0 / INTCAP1 - Registros de captura de interrupciones

Estos son registros que contienen el valor del puerto que generó la interrupción.

IOCON0 / IOCON1 - Registro de control del expansor de E / S

Esto controla la funcionalidad del MCP23016.

La configuración del bit 0 (IARES> Resolución de actividad de interrupción) controla la frecuencia de muestreo de los pines del puerto GP.

Bit0 = 0> (predeterminado) El tiempo máximo de detección de actividad del puerto es 32 ms (bajo consumo de energía)

Bit0 = 1> el tiempo máximo de detección de actividad en el puerto es 200usec (mayor consumo de energía)

Paso 9: Estructura para la comunicación

Estructura para la comunicación
Estructura para la comunicación

Muestro aquí la clase Wire, que es la comunicación I2C en nuestro núcleo Arduino, que también permite que el expansor funcione con Arduino Uno y Mega. Sin embargo, este último ya cuenta con varios IO. Aquí nos ocupamos de las direcciones del chip, el control de acceso, que son los códigos de los registros, así como los datos.

Paso 10: Programa

Programa
Programa

Nuestro programa consiste en comunicar el ESP32 con el MCP23016 para tener más GPIOs a utilizar. Luego tendremos un botón y algunos LED conectados al MCP23016. Los controlaremos todos utilizando solo el bus I2C. Por lo tanto, solo se utilizarán dos pines ESP32. Puede ver el circuito de imágenes a continuación en el video.

Paso 11: ESP01

ESP01
ESP01

Aquí, muestro el Pinout de ESP01.

Paso 12: Montaje de ESP01

Montaje ESP01
Montaje ESP01

En este ejemplo, tenemos el GPIO0 conectado en el SDA y el GPIO2 conectado en el SCL. También tenemos una placa de relés, un zumbador y un LED. En el otro puerto, en GP1.0, tenemos un LED más con una resistencia.

Paso 13: NodeMCU ESP-12E

NodeMCU ESP-12E
NodeMCU ESP-12E

Aquí, tenemos el Pinout del NodeMCU ESP-12E.

Paso 14: Montaje de NodeMCU ESP-12E

Nodo de montaje MCU ESP-12E
Nodo de montaje MCU ESP-12E

En este caso, la única diferencia con el primer ejemplo es que ha conectado D1 y D2 en SDA y SCL, respectivamente.

Paso 15: Nodo WiFi MCU-32S ESP-WROOM-32

Nodo WiFi MCU-32S ESP-WROOM-32
Nodo WiFi MCU-32S ESP-WROOM-32

Aquí está el Pinout del WiFi NodeMCU-32S ESP-WROOM-32.

Paso 16: Nodo de montaje WiFi MCU-32S ESP-WROOM-32

Nodo de montaje WiFi MCU-32S ESP-WROOM-32
Nodo de montaje WiFi MCU-32S ESP-WROOM-32

Esta vez, la principal diferencia con los otros dos ejemplos es el botón y los tres LED parpadeantes. Aquí, el SDA está conectado al GPIO19, mientras que el SCL está conectado al GPIO23.

Paso 17: Bibliotecas y variables

Primero, incluiremos Wire.h, que es responsable de la comunicación i2c, así como de configurar la dirección i2c de MCP23016. Muestro varios comandos, incluso algunos que no usamos en este proyecto.

#include // especifica el uso de la biblioteca Wire.h. // endereço I2C do MCP23016 #define MCPAddress 0x20 // COMMAND BYTE PARA REGISTRAR RELACIÓN: Tabla: 1-3 de Microchip MCP23016 - DS20090A // ENDEREÇOS DE REGISTRADORES #define GP0 0x00 // DATA PORT REGISTER 0 #define GP1 0x01 // DATA REGISTRO DE PUERTO 1 #define OLAT0 0x02 // REGISTRO DE LATCH DE SALIDA 0 #define OLAT1 0x03 // REGISTRO DE LATCH DE SALIDA 1 #define IPOL0 0x04 // REGISTRO DE PUERTO DE POLARIDAD DE ENTRADA 0 #define IPOL1 0x05 // REGISTRO DE PUERTO DE POLARIDAD DE ENTRADA 1 / #IR0xdefine / REGISTRO DE DIRECCIÓN DE E / S 0 #define IODIR1 0x07 // REGISTRO DE DIRECCIÓN DE E / S 1 #define INTCAP0 0x08 // REGISTRO DE CAPTURA DE INTERRUPCIÓN 0 #define INTCAP1 0x09 // REGISTRO DE CAPTURA DE INTERRUPCIÓN 1 #definir IOCON0 0x0A // CONTROL DE EXPANSOR DE E / S REGISTRO 0 #define IOCON1 0x0B // REGISTRO DE CONTROL DE EXPANSOR DE E / S 1

Paso 18: configuración

Aquí tenemos las funciones para inicializar cuatro tipos diferentes de microcontroladores. También verificamos la frecuencia, configuramos los GPIO y configuramos los pines. En el Loop, verificamos el estado del botón.

configuración vacía () {Serial.begin (9600); retraso (1000); Wire.begin (19, 23); // ESP32 // Wire.begin (D2, D1); // nodemcu ESP8266 // Wire.begin (); // arduino // Wire.begin (0, 2); // ESP-01 Wire.setClock (200000); // frecuencia // configura o GPIO0 como OUTPUT (todos los pinos) configurePort (IODIR0, OUTPUT); // configura o GPIO1 como ENTRADA o GP1.0 e como SALIDA os outros GP1 configurePort (IODIR1, 0x01); // seta todos los pinos do GPIO0 como LOW writeBlockData (GP0, B00000000); // seta todos los pinos de GPIO1 como LOW writeBlockData (GP1, B00000000); } void loop () {// verifica e o botão GP para presionar checkButton (GP1); } // fin del ciclo

Paso 19: ConfigurePort

En este paso, configuramos el modo de los pines GPIO e identificamos el modo de los puertos.

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

Paso 20: WriteBlockData y CheckButton

Aquí enviamos datos al MCP23016 a través del bus i2c, verificamos el estado del botón e indicamos el siguiente paso teniendo en cuenta la condición de ser presionado o no.

// enviamos 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 (datos); Wire.endTransmission (); retraso (10); }

// verifica se o botão foi pressionado // parámetro 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 botão pressionado, seta para HIGH como portas GP0 if (btn) {writeBlockData (GP0, B11111111); } // caso contrario deixa todas en el estado LOW else {writeBlockData (GP0, B00000000); }}

Paso 21: ReadPin y ValueFromPin

Aquí nos ocupamos de la lectura de un pin específico y el retorno del valor del bit a la posición deseada.

// 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); // lea el estado del chip 1 byte GP = Wire.read (); return valueFromPin (pin, statusGP); } // retorna o valor do bit 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 << pin)) == 0? 0: 1; }

Paso 22: Programa ESP8266

A partir de aquí veremos cómo se creó el programa que usamos en ESP-01 y en el nodoMCU ESP-12E, lo que nos permite entender cómo las diferencias entre ellos son mínimas.

Solo modificaremos la línea del constructor de comunicación i2c, que es el método inicial del objeto Wire.

Simplemente descomente la línea según la placa que vamos a compilar.

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

Configuración

Tenga en cuenta que el constructor todavía está comentado. Por lo tanto, descomente según su placa (ESP-01 o nodeMCU ESP12-E).

configuración vacía () {Serial.begin (9600); retraso (1000); // Wire.begin (D2, D1); // nodemcu ESP8266 // Wire.begin (0, 2); // ESP-01 Wire.setClock (200000); // frecuencia // configura o GPIO0 como OUTPUT (todos los pinos) configurePort (IODIR0, OUTPUT); // configura o GPIO1 como SALIDA (todos los pinos) configurePort (IODIR1, SALIDA); // seta todos los pinos do GPIO0 como LOW writeBlockData (GP0, B00000000); // seta todos los pinos do GPIO1 como LOW writeBlockData (GP1, B00000001); }

Círculo

En el bucle, cambiamos los pines cada 1 segundo. Por lo tanto, cuando el pin0 de GP0 está activado, los pines de GP1 están desactivados. Cuando el pin0 de GP1 está activado, los pines GP0 están desactivados.

void loop () {// seta o pino 7 do GP0 como HIGH e os demais como LOW writeBlockData (GP0, B10000000); // seta todos los pinos de GPIO1 como LOW writeBlockData (GP1, B00000000); retraso (1000); // seta todos los pinos do GPIO0 como LOW writeBlockData (GP0, B00000000); // seta o pino 0 do GP1 como HIGH e os demais como LOW writeBlockData (GP1, B00000001); retraso (1000); } // fin del ciclo

Paso 23: IMPORTANTE

Las variables y biblioteca utilizadas son las mismas que las del programa que hicimos para ESP32, así como los métodos configurePort y writeBlockData.

Paso 24: Archivos

Descarga los archivos:

PDF

INO (ESP8266)

INO (ESP32)

Recomendado: