Aumentando as portas digitais do Arduino com o CI 74HC595 - shift register
Um CI barato, fácil de conectar e de operar, pode fazer com que 8 ou (bem) mais portas digitais sejam controladas por apenas 3 pinos físicos do Arduino.
Várias aplicações da vida real exigem mais pinos do Arduino do que gostaríamos de disponibilizar, a ponto de esgotá-los. Aplicações que usam displays LCD, displays de 7 segmentos, matrizes de leds, teclados, etc. às vezes chegam a esgotar o número de pinos disponíveis.
Uma das alternativas para esse tipo de situação é o uso de CIs do tipo shift register, que usam apenas 3 pinos do Arduino e controlam de maneira rápida e precisa o estado de até dezenas de pinos de outros componentes.
Usei o CI 74HC595 para solucionar uma situação similar com o meu projeto de pionola com solenóides acionando teclas de um instrumento musical: precisarei controlar 30 solenóides independentemente, e o Arduino tem menos pinos do que isso.
Minha solução será usar 4 chips 74HC595 encadeados: eles usarão só 3 pinos do Arduino no total, e cada um deles tem 8 pinos de saída, perfazendo 32.
Neste artigo não tratarei dos chips encadeados, mas apenas do que aprendi quanto ao uso de um chip 74HC595 isoladamente: usa os mesmos 3 pinos do Arduino que um conjunto encadeado usaria, e tem 8 pinos de saída à disposição.
Temo que seja um artigo um pouco mais técnico que o usual: entender a formação dos números binários e as operações que tratam números bit a bit será necessário para o seu melhor aproveitamento prático.
74HC595 e Arduino: como conectar
Os 3 pinos do 74HC595 que realizam a comunicação com o Arduino são o 14 (DS, dados), 11 (SH_CP ou SRCLK, clock da comunicação) e 12 (ST_CP ou RCLK, latch).
Graças à existência da função shiftOut()
na própria biblioteca padrão do Arduino, não é mais necessário implementar ou mesmo entender o funcionamento dos pinos acima mas, em um rápido resumo, a cada vez que o pino 11 (clock) muda de LOW para HIGH, o conteúdo do pino 14 (dados) é deslocado para o registro interno de 8 bits, e o bit mais antigo do registro é descartado1.
Em resumo, a operação de mover serialmente 1 bit para o 74HC595 pode ser descrita assim: coloca LOW no pino 11, coloca um bit (1 é HIGH, 0 é LOW) no pino 14, coloca HIGH no pino 11.
Assim, quando repetirmos a operação acima 8 vezes, teremos comunicado ao 74HC595 o estado desejado para todos os seus pinos de saída, e será o momento de dizer para ele transferir os bits do seu registro interno para o estado dos pinos em si. E isso é feito de uma maneira bem simples: mudando o estado do pino 12 (latch) de LOW para HIGH.
Parece um procedimento longo, mas pode ser realizado várias centenas de vezes por segundo e, como os pinos físicos só mudam de estado na hora do latch, dificilmente será possível perceber que os dados chegam de 1 em 1, e não 8 de cada vez.
Os outros pinos necessariamente relevantes do 74HC595 são o 8 (GND, conectado ao terra), 16 (Vcc, conectado aos 5V do Arduino), OE (13, conectado ao terra – a não ser que haja necessidade de controlar a habilitação da saída), e 10 (MR, conectado aos 5V do Arduino – a não ser que haja necessidade de controlar o reset do registro interno).
E os pinos de saída são, nesta ordem: 15, 1, 2, 3, 4, 5, 6, 7. É a eles que você deve conectar os pinos dos outros componentes (displays, leds, um driver para os meus solenóides, etc.), como conectaria a pinos digitais do Arduino. Mas comandá-los é um pouco mais complexo do que usar o tradicional comando digitalWrite...
Arduino e 74HC595: como programar
Como vimos acima, para controlar o estado dos pinos de saída do 74HC595 o Arduino precisa manipular os pinos 14, 11 e 12 do chip, os quais naturalmente precisarão estar conectados a pinos de saída do Arduino.
Digamos que os pinos 14, 11 e 12 do 74HC595 estejam conectados, respectivamente, aos pinos 4, 5 e 6 do Arduino. A inicialização típica deles envolve simplesmente configurá-los em modo OUTPUT, como no exemplo:
// pinos do shift 595 / pinos do Arduino
int latchPin = 4;
int clockPin = 5;
int dataPin = 6;
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
Para transferir dados do Arduino para o 74HC595, podemos contar com a conveniente função shiftOut()
.
Por exemplo, se queremos que os 2 últimos pinos do 74HC595 fiquem em HIGH e os outros 6 fiquem em LOW, o número binário que representa este estado é 00000011 (cada zero é um pino LOW, cada 1 é um pino HIGH), e o comando correspondente (considerando que os pinos do 74HC595 estão conectados ao Arduino conforme exemplificado acima) poderia ser:
shiftOut(6, 5, LSBFIRST, 0b00000011);
O número 6 indica o pino do Arduino que está conectado ao pino 14 (dados) do 74HC595, o número 5 indica o pino do Arduino que está conectado ao pino 11 (clock) do 74HC595, LSBFIRST indica a ordem em que os bits serão enviados (LSBFIRST é a ordem normal, a alternativa seria MSBFIRST, para enviar bits em ordem decrescente de magnitude), e 0b00000011 é o valor que queremos enviar, sendo que 0b é o prefixo que indica números binários.
Na prática, a operação geralmente é realizada primeiro garantindo que o pino do Arduino conectado ao pino 12 (latch) do 74HC595 esteja LOW, e logo em seguida movendo-o para HIGH. A sequência completa ficaria assim:
digitalWrite(4, LOW);
shiftOut(6, 5, LSBFIRST, 0b00000011);
digitalWrite(4, HIGH);
O número 4, você adivinhou corretamente, representa o pino do Arduino conectado ao pino 12 (latch) do 74HC595.
Transferir dados tratando-os como constantes binárias (números com o prefixo 0b) é conveniente para explicar como a função funciona, mas não é tão prático para boa parte dos seus usos reais. Você pode perfeitamente passar números em decimal (por exemplo, shiftOut(6, 5, LSBFIRST, 3);
), e construi-los a partir de matrizes ou outros dados à sua escolha, com ajuda dos operadores e funções binárias do Arduino2.
Em um futuro artigo vou tratar da conexão de mais de um 74HC595 aos mesmos 3 pinos do Arduino. Até lá!
- Ou enviado para um segundo chip 74HC595 que esteja conectado, mas não veremos isso neste artigo. ↩
- Na referência do Arduino, consulte as seções com os seguintes títulos: Bitwise operators e Bits and Bytes ↩
Comentar