como-controlar-hasta-16-gpio-por-i2c-con-extensor-pcf8575-y-arduino

Cómo controlar hasta 16 GPIO por I2C con extensor PCF8575 y Arduino

¿Qué es un PCF8575?

El PCF8575 es un extensor I/O de 16 bits controlado por bus I2C. Este dispositivo nos permite tener 16 GPIO adicionales usando únicamente dos pines de un procesador como Arduino.

La dirección del PCF8575 es configurable mediante pines. De esta forma, podemos incluir en un mismo bus I2C hasta 8 de estos dispositivos, para un total de 128 GPIO adicionales.

La tensión de funcionamiento es de 2.5 a 5.5Vdc. Por su parte, el consumo eléctrico en Stand-by es de unos 10uA, y la máxima corriente que puede proporcionar de unos 100mA.

El control se realiza por I2C hasta 400kHZ, por lo que es muy sencillo controlarlo desde un microprocesador como Arduino.

EL tiempo de conmutación es de unos 4us. Sin embargo, aunque es posible emplearlo para generar señales cuadrada de baja frecuencia, no es un integrado apropiado para realizar señales PWM de frecuencia elevada.

Para obtener señales PWM controlables por I2C lee el artículo sobre el PAC9685

Precio

Los PCF8575 son dispositivos relativamente baratos. Podemos encontrar un módulo con un PCF8575, incluida la placa de medición, por 1,80€ en vendedores internacionales de eBay y AliExpress.

arduino-PCF8575-componente

Como decimos, es un dispositivo relativamente barato. Es barato, pero por un rango similar podemos encontrar algunos procesadores. Esto nos daría la misma capacidad de extensión de GPIO, así como funcionalidades adicionales (PWM, lecturas analógicas, etc). A cambio, tendríamos una complejidad superior y un mayor consumo de energía. Tendrás que valorar la solución más apropiada para tu proyecto.

¿Cómo funciona un PCF8575?

El PCF8575 está integrado por 16 GPIO cuasi-bidirecionales, organizados en dos puertos (P0-P07 y P10-P17). Cada uno de los GPIO puede ser configurado como input o input.

arduino-PCF8575-funcionamiento

Actuando como salidas, cada una de ellas dispone de un circuito de latch (enclavamiento). Es decir, es capaz de mantener el estado por sí mismas, sin necesidad de proporcionarles una tensión externa.

arduino-PCF8575-funcionamiento-2

Por otro lado, para que un pin pueda cambiarse como input, previamente es necesario establecer un valor HIGH. Durante el arranque, por defecto todos los pines se inicializan como inputs con un valor de HIGH.

Adicionalmente el PCF8575 proporciona un pin de salida en configuración Open Drain, que puede usarse para informar al procesador ante un cambio de estado en una de las entradas, sin tener que preguntar constantemente el estado por I2C.

Esquema de montaje

El control de módulo se realiza a través de I2C, por lo que el conexionado es muy sencillo. Simplemente alimentamos el módulo mediante Gnd y Vdd, y conectamos los pines del I2C SDA y SCL.

arduino-PCF8575-conexion

La conexión vista desde Arduino sería la siguiente.

arduino-PCF8575-esquema

Lo normal en estos módulos es que podamos configurar la dirección I2C del PCF8575 soldando unos pines en la parte trasera del módulo.

Por otro lado, en algunos módulos la tensión de las salidas GPIO está fijada por un regulador interno de 3V3. Para hacer que las salidas funcionen a 5V debemos alimentar el módulo a 5V y, adicionalmente, soldar un pin en la parte trasera identificado como Vdd-Vcc.

Ejemplos de código

Para controlar el PCF8575 podemos usar la librería desarrollada por Xreef, cuyo código está disponible en https://github.com/xreef/PCF8575_library.

Con esta librería el uso de los GPIO adicionales es muy similar al que haríamos con cualquier otro pin digital del procesador. Por defecto la librería trabaja en un rango de P0-P15, en lugar de P0-P07 y P10-P17

La librería incorpora ejemplos de su uso, que resulta aconsejable consultar. El siguiente es un resumen extraído de los mismos.

#include "PCF8575.h"

// Iniciar el PCF8575 en la dirección 0x20
PCF8575 pcf8575(0x20); 

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

  // Establecer el pin P0 como salida
  pcf8575.pinMode(P0, OUTPUT);

  pcf8575.begin();
}

void loop()
{
  pcf8575.digitalWrite(P0, HIGH);
  delay(1000);
  pcf8575.digitalWrite(P0, LOW);
  delay(1000);
}

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github. github-full