
.
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

É 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):
O 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.
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:

Pinos 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:

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!
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:

.
O primeiro caso é para o PCF8574, e o segundo para o PCF8574A
Totalizando os 8 bits do endereço podemos montar a tabela completa com os 16 endereços possíveis:

Tabela de endereços do PCF8574 e PCF8574A
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:
Para as configurações acima temos a seguinte tabela:

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.
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á?

circuito na protoboard

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.
.
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:

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

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);
}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!
|
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!