VictorJAM.zapto.org
Entradas/salidas  Arduino 

2021-12-16

El expansor MCP23X17 y su uso con Arduino.

¿Qué es el MCP23X17?

El MCP23017 o el MCP23S17 es un chip que nos permite aumentar el número de entradas o salidas de nuestro Arduino. La diferencia entre ambas versiones radica en el bus que se usar para controlar el chip. En el caso del MCP23017 se usa el bus I2C mientras que en la versión marcada con una "S" se utiliza el bus SPI.

Ambos chips son internamente iguales, solo varia el patillaje correspondiente a cada bus. Internamente dispones de 16 pines que se pueden programar como entradas o salidas independientemente. También tiene la opción de generar una interrupción si alguna de las entradas ha cambiado.

Pinout

La entrada/salida se realiza mediante dos puertos de 8 bits llamados GPA y GPB. Al igual que los pines de un Arduino, estos pines poseen una resistencia de PULL_UP que se puede configurar. A cada uno de esos puertos existe asociado un pin de interrupción llamados INTA e INTB, según el puerto que estemos usando.

En el control del chip encontramos la diferencia: mientras que el MCP23017 tenemos las líneas SCL/SDA del bus I2C en el MCP23S17 tenemos las líneas CS, SCK, MOSI y MISO del bus SPI.

También disponemos de tres pines de dirección A2, A1 y A0. Estos pines sirven para configurar la dirección dentro del bus correspondiente, permitiendo conectar múltiples chips y aumentar el número de líneas. El número total de chips que podemos direccionar es 8, lo cual nos da un total de 128 pines solo controlados por unos poco pines del Arduino.

Antes de nada indicar que el chip posee una dirección base que es la 0x20.

A esa dirección base le debemos sumar el valor binario que representan los pines A2 a A0.

El chip posee un reset interno, que podremos controlar mediante otro pin o simplemente conectarlo a VCC.

Hay que tener cuidado con la corriente de fuente/sumidero que puede manejar cada pin. Individualmente cada pin puede manejar hasta 25mA, pero entre todos los pines no se puede llegar a los 125mA.

Conexión I2C

En el siguiente esquema podemos ver la conexión a un Arduino.

Como vemos la conexión es muy simple: llevar las líneas SCL/SDA del Arduino a los pines SCL/SDA del chip. En el esquema he puesto un juego de jumpers y unas resistencias que permite modificar la dirección del chip fácilmente. Esto es totalmente opcional y podemos llevar los pines Ax a tensión o masa según la dirección que queremos que tenga.

Programación

El mcp23017 es como cualquier otro dispositivo I2C/SPI, internamente dispone de unos registros que guardan el estado de las entradas, de las salidas y la configuración.

Pero gracias a los chicos de Adafruit disponemos de una librería que nos permite realizar la programación fácilmente.

La librería ha sufrido grandes cambios y por lo tanto dependiendo de la versión se manejará de una manera u otra, sobre todo en el uso de constructores para crear una instancia del puerto. Así que conviene ver la librería que tenemos instalada, mirando los ejemplos que vienen instalados para saber como se inicializa.

La versión 2.0 hace uso de una segunda librería llamada BusIO sin la cual la librería del mcp23xxx nos dará errores de compilación. Dicha versión trae soporte para el chip mcp23x08, que es idéntico a nuestro expansor, pero únicamente dispone de 8 pines de entrada/salida.

Independientemente de la librería que estemos usando, el manejo de los pines sigue siendo el mismo, siendo las siguientes funciones las mas importantes:

  • pinMode(pin, modo): Establece un pin como entrada o salida. El modo puede ser INPUT, INPUT_PULLUP o OUTPUT, igual que un pin normal de Arduino.
  • digitalWrite(pin, valor): Sirve para poner un valor en el pin.
  • digitalRead(pin): Sirve para leer el valor del pin.

Un detalle importante de la librería es que nombra los pines de 0 a 15, correspondiéndose los pines 0-7 al puerto A y de 8 a 15 los del puerto B.

He aquí un ejemplo de uso:

/*
 *  EJEMPLO DE USO DE LA LIBRERIA MCP23X17
 */ 
#include <Adafruit_MCP23X17.h>

// Creamos un objeto mcp23x17.
Adafruit_MCP23X17 mcp;

// Variables auxiliares para guardar el estado de los pins.
uint16_t port, nport;

void setup() {
  Serial.begin(9600);

  // Inicializamos el chip. Como parámetro acepta la dirección
  // del chip fisica empezando por 0x20. Si no lo indicamos 
  // tomará este valor por defecto.
  if (!mcp.begin_I2C(0x21)) {
    Serial.println("Error.");
    while (1);
  }
  // Inicamos todos los pines como entrada activando la resistencia
  // pull up.
  for (int i=0; i<16; i++) mcp.pinMode(i, INPUT_PULLUP);
}



void loop() {
 // Leemos todos los pines.
 for (int i=0; i<16; i++) 
   bitWrite(nport, i, mcp.digitalRead(i));
 // Si algún pin ha cambiado mostramos el cambio.
 if ( nport!=port ) {
  Serial.println(nport, BIN);
  port = nport;
 }  
 
}

Referencias

Datasheet del MCP23x17

Versión 1.00 de libreria MCP23018

Versión 1.20 de libreria MCP23x17

Versión 2.0 de la libreria (Incluye la libreria BusIO