Componentes Eletronicos

Expandindo as Portas do Arduino

Eletrogate 16 de julho de 2021

Introdução

Blog-Eletrogate-PCF8574-Protoboard

.

Imagine que você precisa desenvolver um projeto que utilize muitas portas, tipo umas 60 (ou mais). Isso é muito mais do que as 14 portas digitais que o Arduino UNO pode oferecer. Na verdade nem as 54 portas do Arduino mega dariam conta… Então temos que descartar o Arduino do nosso projeto e pensar em outra solução.

Mas… Será mesmo? Será que não existe uma maneira de aumentar o número de portas digitais no seu Arduino? Será que não existisse um circuito integrado cuja finalidade é exatamente servir como pinos I/O adicionais? E se esse circuito funcionasse com um protocolo simples e facil de usar?

Pois bem, é exatamente o que o PCF8574  da Philips faz pra você  através do protocolo I²C

Blog-Eletrogate-PCF8574-I2C


Protocolo I²C BUS

É um modelo de comunicação serial síncrono, multi-master, multi-slave, criado em 1982 pela Philips Semiconductors. A grande vantagem desse protocolo é que ele permite o acionamento de várias portas com apenas 2 fios: SDA – (Serial Data Line) e SCL – (Serial Clock Line):
Blog-Eletrogate-Ligacao-I2CO nome “Bus” é uma analogia ao trajeto de um ônibus através de uma linha, e cada ponto de parada é um dispositivo onde se transmite ou recebe uma informação.
E assim como uma rede de computadores, que possuem endereços de identificação, o I²C também possui sua estrutura própria de endereço para que possam direcionar os dados transmitidos.


PCF8574 

De acordo com o datasheet desse circuito integrado,  o PCF8574 foi projetado justamente para servir como um expansor de portas I/O para microcontroladores compatíveis com o protocolo de comunicação I2C Bus.

Seus pinos são configurados da seguinte forma:

Blog-Eletrogate-PCF8574-Pinout

Pinos do PCF8574


Endereçamento físico do PCF8574

O endereço completo do PCF é composto por 1 byte completo (8 bits). Parte desse endereço é configurável fisicamente através das portas A0, A1 e A2. Combinando-as ao Vcc e Gnd temos:

Blog-Eletrogate-PCF8574-Tabela-Enderecos

Tabela de endereços do PFC8574

Isso significa que podemos colocar na mesma linha até 8 CIs, cada um com 8 portas. Então podemos chegar até 64 portas.

Nota:. Existe uma variação desse CI que é o PCF8574A. Ele funciona praticamente igual mudando apenas o endereço interno. Porém as portas físicas são configuradas da mesma maneira, sendo assim podemos adicionar mais 8 desses modelo, chegamos ao total máximo de 16 CIs (8 PCF8574 e 8 PCF8574A) com 128 portas digitais!


Endereçamento total do PCF8574

Nós já vimos acima que 3 bits do endereço são configurados fisicamente, vamos ver agora como funciona o restante dos bits de endereçamento:

Blog-Eletrogate-PCF8574-Bits

.

O primeiro caso é para o PCF8574, e o segundo para o PCF8574A

  • Os 4 primeiros bits são um endereço fixo, do controle interno do Bus do  I²C.
  • Os 3 seguintes se referem ao endereçamento de configuração física.
  • O último bit (Read/Write) configura leitura ou gravação.

Totalizando os 8 bits do endereço podemos montar a tabela completa com os 16 endereços possíveis:

Blog-Eletrogate-PCF8574-Tabela-Enderecos-2

Tabela de endereços do PCF8574 e PCF8574A


Acionando as Portas do PCF8574

Para mudar o estado das portas, devemos passar para o PCF um byte, um número binário ou equivalente em dec ou hexa, onde cada bit representa uma porta.
Para exemplificar, imagine que você gostaria de:

  1. Deixar a porta P0 em nível alto e as demais em nível baixo.
  2. Deixar a porta P2, P4 e P6 em nível alto e as demais em nível baixo.
  3. Deixar a porta P0, P3, P5 e P7 em nível alto e as demais em nível baixo.

Para as configurações acima temos a seguinte tabela:

Blog-Eletrogate-PCF8574-Configurando-Pinos

Tabela de acionamentos das portas

A lógica é a mesma para qualquer configuração desejada onde a porta P0 é o bit menos significativo. E o número mínimo é zero e o máximo é 255(Dec) ou 11111111(Bin) ou FF(Hex)

Note que a forma menos extensa de representar o estado das portas é através do código Hexa, pois para todos os casos utiliza no máximo 2 digitos.


PCF8574 + I²C + Arduino

Agora que já temos uma noção do que é o PCF8574, o protocolo I²C e como eles funcionam, vamos juntar tudo isso no arduino na prática.
Como exemplo sugiro usar o PCF8574 para acionar 2 displays de 7 segmentos com apenas 2 portas no Arduino. Vamos lá?

Materiais necessários para o projeto Expandindo as Portas do Arduino

cta_cart


O Circuito

Blog-Eletrogate-PCF8574-Circuito

circuito na protoboard

Blog-Eletrogate-PCF8574-Ligacao-Pinos

Esquema de ligação de pinos

 

Note que ambos os circuitos PCF/display são praticamente idênticos, a única coisa que muda de uma montagem para a outra é o endereçamento, que no circuito da direita o pino 3 (A2) vai para o Vcc invés do Gnd.

 

 

Para que a comunicação I²C funcione é necessário adicionar resistores de pull-up de 1kΩ em paralelo com as portas de SLC e SLK.

 

.


O Código

Para fazer esse projeto, iremos utilizar a biblioteca Wire do Arduino. A documentação com alguns exemplos pode ser encontrada aqui. E caso você tenha dúvidas sobre o processo de importação de bibliotecas, clique aqui

Algumas considerações inicias antes de irmos para o código:

Diagrama do display de 7 segmentos:

Blog-Eletrogate-PCF8574-Display-7-Segmentos

diagrama display

Mapeando a ligação dos pinos do display com as portas do PCF temos a seguinte tabela:

Blog-Eletrogate-PCF8574-Mapeamento-Display

Mapeamento do display

 

 

 

Caso você conecte os terminas do PCF e do display de outra maneira é preciso mapear novamente qual porta controla cada segmento.

//Inclui a biblioteca Whire
#include <Wire.h>

/*definindo os endereços dos PCFs no BUS
de acordo com a montagem do circuito

Criei nas 3 bases apenas para exemplificar.
No seu código, use apenas um, o de sua preferência
*/

#define pcf_1_addressDec 32       // em decimal
#define pcf_1_addressBin 0b100000 // em binário
#define pcf_1_addressHex 0x20     // em hexadecimal

#define pcf_2_address2Dec 36       // em decimal
#define pcf_2_address2Bin 0b100100 // em binário
#define pcf_2_address1Hex 0x24     // em hexadecimal

//Criando o mapa de caracteres de acordo com o mapeamento
//como o display é anodo comum, as portas são acionadas em nível
//logico baixo (zero) e desligadas em nível lógico alto (1)

                  // b a f g e d c pt
#define n0 = 0x11 // 0 0 0 1 0 0 0 1 
#define n1 = 0x7D // 0 1 1 1 1 1 0 1 
#define n2 = 0x21 // 0 0 1 0 0 0 0 1 
#define n3 = 0x29 // 0 0 1 0 1 0 0 1 
#define n4 = 0x4D // 0 1 0 0 1 1 0 1 
#define n5 = 0x89 // 1 0 0 0 1 0 0 1 
#define n6 = 0x81 // 1 0 0 0 0 0 0 1 
#define n7 = 0x3D // 0 0 1 1 1 1 0 1 
#define n8 = 0x1  // 0 0 0 0 0 0 0 1 
#define n9 = 0x9  // 0 0 0 0 1 0 0 1 	

//cria uma array com a sequencia dos caracteres
//para serem mostrados nos displays
int seqArr = {n0, n1, n2, n3, n4, n5, n6, n6, n7, n8, n8}

// varivel de contagem
int cont= 0;
  
void setup(){
  //inicia a Serial
  Serial.begin(9600);
  //inicia a comunicação i2c
  Wire.begin();
}

//o loop mostra uam contagem progressiva (de 0 a 9)no diplay 1
//e uam contagem regressiva (de 9 a 0) no display 2

void loop(){
  
  //inicia uma trasmissão passando o endereço do PCF1
  Wire.beginTransmission(pcf_1_addressHex); 
  //escreve e envia o hexa contido noarray pelo indice cont
  Wire.write(seqArr[cont]);
  //finaliza a transmissão
  Wire.endTransmission();
  
  //inicia uma trasmissão passando o endereço do PCF1
  Wire.beginTransmission(pcf_2_addressHex); 
  //escreve e envia o hexa contido noarray pelo indice (10 - cont)
  Wire.write(seqArr[10-cont]);
  //finaliza a transmissão
  Wire.endTransmission();
  
  //incrementa o contador
  cont++;
  
  //delay de 250ms
  delay(250);
}

Conclusão

Uma vez que você consiga entender a parte de endereços e acionamentos, operar as portas do PCF se torna tão simples quanto as próprias portas digitais nativas do Arduino. Problemas com faltas de portas nunca mais!

No código abaixo, deixei apenas a parte que interessa para deixar, ainda mais claro, como com poucas linhas pode-se acionar um grande número de portas. Extremamente útil para projetos específicos com essa necessidade:

#include <Wire.h> //Inclui a biblioteca Whire

int address = 0x00 // seu enredeço aqui 
int setup = 0x00   // código dos estados das portas aqui

void setup(){
  Wire.begin(); //inicia a comunicação i2c
}

void loop(){ 
  Wire.beginTransmission(address); //inicia uma transmissão passando o endereço
  Wire.write(setup); //escreve e envia o setup das portas
  Wire.endTransmission(); //finaliza a transmissão
  delay(500);//delay de 500ms
}

Conheça a Metodologia Eletrogate e ofereça aulas de robótica em sua escola!


Sobre o Autor


foto-autor
Diogo Zanardini
LinkedIn

Técnico em processamento de dados, em eletrotécnica e cursando engenharia de controle e automação.
Eletrogate Expert, apaixonado por pizza, carros elétricos, automação residencial / industrial e ciência de dados.


Eletrogate

16 de julho de 2021

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Tenha a Metodologia Eletrogate dentro da sua Escola! Conheça nosso Programa de Robótica nas Escolas!

Eletrogate Robô

Assine nossa newsletter e
receba  10% OFF  na sua
primeira compra!