O MC14067bcp é um (de)multiplexador. Basicamente, um multiplexador é um circuito chaveador capaz de combinar vários canais de entrada em uma única via de saída. Um de-multiplexador tem a função contrária, através de um canal de entrada temos várias vias de saída.

Multiplexadores e de-multiplexadores são circuitos muito úteis quando estamos lidando com plataformas que possuem quantidades de pinos de entrada e saída limitados, como é o caso do Arduino, com apenas 6 pinos de entrada analógica. O 4067 possui 16 pinos que podem ser utilizados como entradas ou saídas, para realizar a transmissão ou recebimento de dados analógicos.

Seu funcionamento é simples. Através de 1 pino enviamos ou recebemos os dados, e energizando outros 4 pinos conseguimos indicar para qual canal queremos enviar os dados ou recebê-los.

Estive testando outro circuito lógico com as mesmas funções para o projeto Modular Synth, o 4051. Ao meu ver o 4067 tem algumas vantagens. Possui 16 pinos que podem ser utilizados como entradas ou saídas contra 8 do 4051, a organização dos pinos do 4067 é melhor, aparentemente ele é mais fácil de se encontrar em Joinville, Santa Catarina, por um preço menor comparado ao preço do 4051. Para ambos encontra-se alguma informação on-line, e para o 4067, o tutorial do ITP Physical Computing é uma boa documentação, esse post é baseado no que li por lá.


pinos do 4067

pinagem do 4067


Colocar esse circuito lógico para funcionar é simples. Para exemplificar seu uso, vou aproveitar o circuito que estou montando para o Modular Synth, um módulo com várias entradas analógicas. Nesse caso, o pino 1 (X), é o pino onde faremos a leitura dos dados. Os pinos de 2 à 9 (X0 até X7) e de 16 à 23 (X8 até X15) são os pinos de entrada, os pinos 12 (VSS, o terra) e 15 (INHIBIT) são ligados ao terra do circuito, e o pino 24 (VDD) deve ser ligado a uma fonte de alimentação de 5 volts. Para realizar o chaveamento entre os 16 canais de entrada, escolhendo um deles para fazer a leitura pelo pino 1 (X), usamos os pinos 10 (A), 11 (B), 14(C) e 13(D).

A tabela abaixo mostra a relação entre os pinos de controle A, B, C, D e o canal que será lido a partir do pino de entrada 1(X).

A B C D Canal Selecionado
0 0 0 0 0
1 0 0 0 1
0 1 0 0 2
1 1 0 0 3
0 0 1 0 4
1 0 1 0 5
0 1 1 0 6
1 1 1 0 7
0 0 0 1 8
1 0 0 1 9
0 1 0 1 10
1 1 0 1 11
0 0 1 1 12
1 0 1 1 13
0 1 1 1 14
1 1 1 1 15

Para entender essa tabela é necessário entender um pouco sobre números binários:

Dado um número N, binário, para expressá-lo em decimal, deve-se escrever cada número que o compõe (bit), multiplicado pela base do sistema (base = 2), elevado à posição que ocupa. Uma posição à esquerda da vírgula representa uma potência positiva e à direita, uma potência negativa. A soma de cada multiplicação de cada dígito binário pelo valor das potências resulta no número real representado. Exemplo:

1011(binário)

1 × 23 + 0 × 22 + 1 × 21 + 1 × 20 = 11

Portanto, 1011 é 11 em decimal

(via wikipedia)

Então, escolhendo quais dos pinos A, B, C e D são energizados, selecionamos o canal do qual vamos realizar a leitura a partir do pino 1 (X).

A ligação do 4067 ao Arduino é simples, nesse exemplo vou utilizar os pinos digitais 2, 3, 4 e 5 para selecionar os canais e o pino analógico 0 para a leitura. No diagrama abaixo não consta a ligação dos pinos 12 e 15 ao terra e o pino 24 na fonte de alimentação, não esqueça deles!


Ligação do 4067 com o Arduino

Ligação do 4067 com o Arduino


Nos pinos de X0 até X15 estão ligados os potenciômetros. O código abaixo demonstra de forma simples como realizar a leitura de um determinado pino:

void setup() {
        Serial.begin(9600);
        pinMode(2, OUTPUT);
        pinMode(3, OUTPUT);
        pinMode(4, OUTPUT);
        pinMode(5, OUTPUT);
        digitalWrite(2, HIGH);
        digitalWrite(3, LOW);
        digitalWrite(4, LOW);
        digitalWrite(5, LOW);
}
 
void loop() {
        int valor = analogRead(0);
        Serial.print("Valor lido no canal: ");
        Serial.println(valor, DEC);
        delay(1000);
}

Veja que na função setup o único pino setado como HIGH é o pino dois, assim obtemos o valor em binário 0001, ou seja, 1 em decinal, selecionando então o canal X1 para realizar a leitura. No tutorial do ITP Physical Computing é apresentada a função setChannel que nos facilita a leitura de dados de um determinado canal. Reproduzo essa função abaixo com algumas modificações:

int pino_entrada = 0;
void setup() {
        Serial.begin(9600);
        pinMode(2, OUTPUT);
        pinMode(3, OUTPUT);
        pinMode(4, OUTPUT);
        pinMode(5, OUTPUT);
        digitalWrite(2, LOW);
        digitalWrite(3, HIGH);
        digitalWrite(4, LOW);
        digitalWrite(5, LOW);
}
 
void loop() {
        int valor_entrada;
        for (int canal = 0; canal < 16; canal++) {
                setChannel(canal);
                valor_entrada = analogRead(pino_entrada);
                Serial.print("Leitura do Canal ");
                Serial.print(canal);
                Serial.print(": ");
                Serial.println(valor_entrada, DEC);
                delay(1000);
        }
}
 
void setChannel(int canal) {
        for (int posicao_bit = 0; posicao_bit < 4; posicao_bit++) {
                // Realiza o deslocamento à direita (&gt;&gt;) e
                //a função bitwise AND (&amp;)
                int valor_bit = (canal >> posicao_bit) & 1;
                // Como o primeiro pino de controle é o pino 2,
                // soma-se posicao_bit a ele
                int pino = 2 + posicao_bit;
                // Escreve no pino indicando se ele está ligado
                // ou desligado
                digitalWrite(pino, valor_bit);
        }
}

A função setChannel realiza um shift (deslocamento à direita) para cada canal e realiza a função bitwise AND (&) para verificar se o canal deve ser colocado como ligado ou desligado. Ok, mas como assim? Por exemplo, se o canal selecionado for o canal 5, sua representação em binário é 0101. Assim, ao realizar o deslocamento à direita (>>) na primeira iteração do loop, obteremos 0101, na segunda iteração, 0010, na terceira, 0001 e na quarta, 0000.
Dessa forma, ao realizarmos a função de bitwite AND (&) comparando o número 1 com o resultado obtido com o deslocamento à direita, receberemos como retorno 1 ou 0, indicando se o pino de controle deve estar ligado ou desligado, e o setamos usando a função digitalWrite logo em seguida.

Pronto, 16 entradas ou saídas analógicas usando 5 pinos do Arduino.

arduinomc14067

Yah! Tenho que agradecer ao Pedro Rito pelos jumpers! Foram um presente muito giro, isso tem facilitado a vida imensamente, thks!

, , , , , , , ,
Trackback

only 1 comment untill now

  1. ;)
    vou aproveitar este teu mini tutorial em breve :P

    um abraço
    Pedro Rito

Add your comment now