Output com CD74HC4067 e Arduino Pro Micro

Arduino Pro Micro

Escrevi 2 artigos sobre esse multiplexador; o primeiro, fazendo leitura analógica; o segundo, leitura digital. Acontece que estava convicto de que o Arduino Pro Micro teria a mesma disposição do Arduino Leonardo, mas ledo engano, já que com isso tenho a oportunidade de mostrar a migração do código feito no Arduino Leonardo. Como faltou o GPIO 11 no Arduino Pro Micro, tive que reavaliar a situação.

Datasheet do Atmega32u4

Arduino é o nome da placa de prototipagem, infelizmente confundido até os dias de hoje com a MCU, que é Atmel. Sabendo o nome da MCU (está escrito sobre ela, seja qual for), basta procurar no Google pelo datasheet. O link do datasheet, para os interessados.

De PORTB para PORTF

O grande susto foi quando, ao perceber a diferença, ter olhado para o pinout do Arduino Pro Micro, e perceber que o número de GPIO é menor, além de distribuídos em poucos bits. Por sorte, os pinos analógicos estão na sequência, do 0 ao 3 – digo, no registrador PORTF. Desse modo foi possível manter o código “econômico” dos artigos anteriores, mudando apenas o registrador. Mas primeiro tive que me certificar de que seria possível utilizar o ADC como pino de saída digital. No datasheet:

Arduino Pro Micro - Analog as digital pinA importância dos bits em sequência se dá ao fato de estarmos utilizando bitwise para configurar os pinos, e também para selecionar o canal do CD74HC4067. De outro modo, seria mais viável utilizar as funções da API do Arduino, mas o código cresceria um bocado.

Quando procurei pela sequência de pinos no mesmo registrador, me deparei também com a ausência de dois bits: PF2 e PF3.

É a primeira vez que preciso ler o datasheet de um Atmega, no caso, para me certificar do fato de não ter os bits PF2 e PF3. No datasheet está claro que não está no pinout, mas o bit obviamente existe, senão o registrador não iria até PF7.

Arduino Pro Micro - PORTF#define READ_MUX_PIN 9 uint16_t pb_values = 0; void handler(uint8_t value){ Serial.print(value,BIN); Serial.print(" - "); Serial.println(pb_values); } uint8_t getValues(){ for (uint8_t i=0;i<16;i++){ PORTF |= (i<<4); delay(1); pb_values = digitalRead(READ_MUX_PIN); Serial.print("C"); Serial.print(i); Serial.print(":"); handler(pb_values); PORTF &= ~(i<<4); delay(1); } } void setup() { DDRF = 0xF<<4; PORTF &= ~(0xF<<4); pinMode(READ_MUX_PIN,INPUT_PULLUP); Serial.begin(9600); } void loop() { getValues(); delay(2000); }

Como usar o CD74HC4067 no Arduino UNO?

Pode usar o PORTB tranquilamente, o registrador é o mesmo para o atmega328p:

Arduino Pro Micro e Arduino UNOOnde comprar o CD74HC4067?

Esse multiplexador extremamente barato você encontra na Eletrônica Mangili, que tem outros itens interessantes em sua lista, mas o link direto para o multiplexador é esse.

CD74HC4067 como OUTPUT

Para fazer o teste de OUTPUT, coloquei um LED em VCC e GND ao pino 0 do multiplexador. Criei um código simples incrementado ao disposto mais acima, com a função handler fazendo a interação. Ao abrir o monitor serial, coloque “nenhum final de linha” na caixa de seleção do rodapé. Se digitar 0, o LED deve se acender. Se digitar outro número (até 9), devolverá o estado do pino. Se não tiver colocado GND em nenhum pino, qualquer número maior que 0 deve retornar 1. Se estiver com algum pino menor que 9 deve retornar 0.

Arduino Pro Micro - INPUT e OUTPUT#define ENABLE_MUX_PIN 8 #define READ_MUX_PIN 9 uint16_t pb_values = 0; void handler(bool do_read,uint8_t channel, bool turn_on){ if (do_read){ Serial.println("reading..."); pinMode(READ_MUX_PIN,INPUT_PULLUP); PORTF |= (channel<<4); delay(1); pb_values = digitalRead(READ_MUX_PIN); Serial.println(pb_values); PORTF &= ~(channel<<4); return; } if (!turn_on){ PORTF |= (channel); } else{ PORTF &= ~(channel); } pinMode(READ_MUX_PIN,OUTPUT); digitalWrite(READ_MUX_PIN,LOW); pinMode(ENABLE_MUX_PIN,OUTPUT); digitalWrite(ENABLE_MUX_PIN,LOW); } uint8_t getValues(){ for (uint8_t i=0;i<16;i++){ PORTF |= (i<<4); delay(1); pb_values = digitalRead(READ_MUX_PIN); Serial.print("C"); Serial.print(i); Serial.print(":"); Serial.println(pb_values); PORTF &= ~(i<<4); delay(1); } } void setup() { DDRF = 0xF<<4; PORTF &= ~(0xF<<4); pinMode(READ_MUX_PIN,INPUT_PULLUP); pinMode(ENABLE_MUX_PIN,OUTPUT); Serial.begin(9600); delay(1000); } void loop() { if (Serial.available()){ uint8_t value = Serial.read()-48; if (value == 0){ handler(false, 0, true); } else{ handler(true, value, false); } } delay(2000); }

Acender vários LEDs de uma vez

Primeiro, não é possível acionar mais de um pino de uma vez. Lembre-se que essa placa é um multiplexador. Se houver a necessidade de manter continuamente o estado de mais de um pino, use um PCF8574, por exemplo.

Já se a intenção é só ligar diversos LEDs de uma vez, basta fazer um loop nos canais desejados com delay bem baixo. É como fazemos no display de 7 segmentos. A impressão de que estarão ligados todos ao mesmo tempo se chama POV (Persistence Of Vision).

Pin map Atmega32u4

Como deixei o mapa de pinos do Leonardo, fica como referência também o do Arduino Pro Micro:

Arduino Pro Micro - pin mapRevisão: Ricardo Amaral de Andrade