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!

, , , , , , , ,

Nesse último final de semana esteve rolando o AZLabs hackmeeting, com os labs LCD, xDA e AltLab, um momento para intensificar o desenvolvimento dos projetos da malta dos laboratórios e criar um ambiente de troca de conhecimentos.

Sentia já a algum tempo falta desse tipo de momento. Lá em Joinville a rapaziada do MuSA juntaa-se as vezes no que costumamos chamar de projetos de final de semana para montar suas coisas e trocar idéias.

Curti testar alguns sensores flexíveis com Pedro Rito e hackear o robosito do VitorLS adicionando a interface de comunicação usando Xbee. Durante o período da tarde rolou uma oficina de Stencil onde cada um cortou seu molde e aplicou em camisetas e na parede do espaço. Domingo, rolaram umas flash talks, e falei um pouquinho do MuSA para o pessoal daqui.

Divertido, é isso. Conhecer pessoas, trocar idéias, criar coisas.

Fotos no flickr.

Tshirt colaborativa, resultado da oficina

Camiseta coletiva

Seguindo as dicas disponibilizadas pela Plusea no Instructables montamos um sensor bend usando dois pedaços de Neoprene, um pedaço de Velostat e linha de costura condutiva (valeu Paulo, estamos usando muito esse presente!). Tanto a linha de costura quanto o Velostat são difíceis de achar no Brasil, então a melhor maneira de conseguir eles de forma barata é pedindo amostras grátis para testes de empresas que comercializam eles fora do pais.

Para quem não conhece, Velostat é um plástico que possui características elétricas, tendo a sua resistência variada quando sofre pressão.

material

recortescortescosturado

Vídeo do funcionamento do sensor:

, ,

Muitas vezes necessitamos de mais portas para nosso projeto do que o microcontrolador pode fornecer, casos de exemplo são matrizes de LEDs, matrizes de botões e displays LCD. Podemos usar um registrador de deslocamento com entrada serial e saída paralela para reduzir a quantidade de pinos usados, liberando os outros pinos para outras atividades. O CI 74hc164 é um registrador de deslocamento que converte a entrada no formato serial para a saída no formato paralelo, muito simples de usar.

74hc164

Como exemplo, para controlar 8 LEDs ligados no 74hc164 com o Arduino faça as seguintes ligações nos pinos:

  • A -> Arduino dataPin
  • B -> 5V
  • Qa .. Qh -> LEDs
  • GND -> GND (duh)
  • CLK -> Arduino clockPin
  • CLR -> Arduino resetPin
  • VCC -> 5V

Os pinos dataPin, clockPin e resetPin são configurados no programa escrito para o Arduino, como mostrado abaixo, e é através deles que vamos controlar o 74hc164. Nesse programa que escrevi, a função initShift inicializa os pinos de controle do 74hc164, o clock e deixa o ci no modo reset. A função sendShift envia um byte que indica quais leds estão ligados e desligados:

int resetPin = 6;
int clockPin = 7;
int dataPin = 5;
 
void setup() {
      initShift(resetPin, clockPin, dataPin);
      sendShift(B10101010);
}
void loop() {
}
 
void initShift(int resetPin, int clockPin, int dataPin) {
      pinMode(resetPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      digitalWrite(resetPin, LOW);
      digitalWrite(clockPin, LOW);
}
 
void sendShift(byte message) {
      int i;
      byte testByte =  B00000001;
      digitalWrite(resetPin, HIGH);
 
      for(i=0; i <= 7; i++) {
            digitalWrite(clockPin, LOW);
            digitalWrite(dataPin, (message >> i) & testByte);
            digitalWrite(clockPin, HIGH);
      }
}
, ,

seminátios colméia

, , , ,