26 março 2017

Como usar o PCF8574 - Expansor de portas I2C

O CI PCF8574 é um expansor de portas I2C de 8 bits, utilizado para acionar até oito pinos do chip utilizando apenas duas portas do microcontrolador, liberando assim as demais portas para outras tarefas.
PCF8574 Expansor de portas I2C

O PCF8574 é um CI com baixo consumo de corrente e pinos com potência suficiente para controlar dispositivos como leds mas que também podemos usar como saídas (e entradas) de uso geral, acionando relés, atuadores ou recebendo dados de sensores.

Características do PCF8574


Na imagem abaixo temos a pinagem do chip que vamos usar aqui, o PCF8574P (datasheet):

Pinagem PCF8574P

Os pinos Vdd e Vss são os pinos de alimentação (Vdd é o positivo, 2,5 à 6VDC, e Vss é o GND). Os pinos destacados em azul são da interface I2C (SDA e SCL), e os pinos em laranja são os pinos das 8 saídas do PCF8574 (P0 à P7). Temos também um pino INT, usado para trabalhar com interrupções do microcontrolador.

Os pinos em vermelho (A0, A1 e A2) são os pinos de endereçamento do PCF8574, endereço esse que será usado para comunicação I2C com o chip e identificar o dispositivo no barramento. O PCF8574 pode ter até 8 endereços diferentes, o que significa que no nosso circuito podemos ter ao mesmo tempo até 8 desses chips, totalizando 64 portas adicionais:

Endereçamento PCF8574

Então para selecionar o endereço I2C que desejamos usar com o chip, basta seguir a tabela acima, atribuindo o valor 0 ou 1 aos pinos A0, A1 e A2.

Conectando o PCF8574 no Arduino


Neste exemplo vamos usar um botão para acionar 4 saídas (P0, P1, P4 e P5) do PCF8574. A cada toque do botão, um valor é enviado para o CI, que baseado nesse valor aciona a porta correspondente.

Monte o circuito abaixo, conectando os pinos A4 (SDA) e A5 (SCL) do Arduino Uno nos pinos SDA e SCL correspondentes do PCF8574 (pinos 14 e 15).

No circuito foram usados 4 leds nas saídas e também 5 resistores de 1K nos leds e no botão (como pull-up).

Circuito Arduino Uno e PCF8574

Os três pinos de endereçamento estão ligados ao negativo, o que significa que o nosso PCF8574 está com o endereço hexadecimal 0x20 (ou 32 em decimal) na interface I2C. Para verificar se o endereço está correto, utilize o programa I2CScanner que eu mostro neste post.

Programação do PCF8574 com Arduino


Usamos a biblioteca Wire (já inclusa na IDE) para comunicação do Arduino Uno com o PCF8574 utilizando a interface I2C. Dentro do loop, verificamos se o botão foi pressionado, o que incrementa a variável contador.

Essa variável é depois testada pelo SWITCH/CASE, que envia então para a sub-rotina transmissao() um valor (em decimal) correspondente à saída que deve ser acionada: 1 (saída P0), 2 (P1), 4 (P2), 8 (P3), 16 (P4), 32 (P5), 64 (P6) e 128 (P7). Como no circuito estamos utilizando somente as saídas P0, P1, P4 e P5, os valores serão 1, 2, 16 e 32, respectivamente.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//Programa: PCF8574 com Arduino
//Autor: Arduino e Cia

#include <Wire.h>

#define pino_botao 3

int contador = 1;

void setup()
{
  Serial.begin(9600);
  pinMode(pino_botao, INPUT);
  Wire.begin();
  Serial.println("Acionando portas do PCF8574");
}

void loop()
{
  int valor = digitalRead(pino_botao);
  if (valor == 0)
  {
    contador++;
    Serial.print("Contador: ");
    Serial.println(contador);
    while (digitalRead(pino_botao) == 0)
    {
      delay(100);
    }
  }

  switch (contador)
  {
    case 1:
      //Aciona a porta P0
      transmissao(1);
      break;
    case 2:
      //Aciona a porta P1
      transmissao(2);
      break;
    case 3:
      //Aciona a porta P4
      transmissao(16);
      break;
    case 4:
      //Aciona a porta P5
      transmissao(32);
      break;
  }

  if (contador >= 4)
  { contador = 0;
  }
}

void transmissao(byte val)
{
  //Inicia a transmissao para o PCF8574 endereço 32
  Wire.beginTransmission(32);
  Wire.write(0);  //Envia dados pela interface I2C
  Wire.endTransmission();     //Fim da transmissao
  Wire.beginTransmission(32);
  Wire.write(val);
  Wire.endTransmission();
}

Como estamos falando de um CI com saída de 8 bits, você pode substituir o valor em decimal pelo valor binário, simplesmente fazendo a conversão. Assim teremos a seguinte relação:

  • P0: 1 (decimal) => 00000001 (binário)
  • P1: 2 (decimal) => 00000010 (binário)
  • P4: 16 (decimal) => 00010000 (binário)
  • P5: 32 (decimal) => 00100000 (binário)

Para usar esse valor em binário no programa, por exemplo na porta P0, altere a linha 36 do programa para:

transmissao(B00000001);

Usando o valor em binário, podemos ver com mais clareza como funciona o processo de acionamento das portas no PCF8574.

3 comentários:

  1. Muito bacana! No Aliexpress há um módulo para esse IC, será que é melhor? https://goo.gl/ryDJqL

    ResponderExcluir
    Respostas
    1. Oi Fabio,

      Obrigado pela dica. Tudo vai depender da aplicação, mas essa placa sem dúvida facilita na hora de conectar vários PCF8574 e também a seleção de endereço.

      Abraço!

      Adilson

      Excluir
  2. como faço pra ler um valor de um sensor q esta conectado no PCF8574?

    ResponderExcluir