Postagem em destaque

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte I

Este post é o primeiro de uma série de seis que escrevi tratando de controle de potência e PID (controle proporcional, integral e derivativo...

domingo, 15 de julho de 2012

O milagre da multiplicação das portas analógicas

No projeto da mesa da Mariana havia a necessidade de colocarmos sensores que permitissem que o usuário (?!?) da mesa conseguisse intervir na música e nos efeitos visuais.
Decidimos usar sensores de luminosidade (LDR-Light Dependent Resistor). São sensores baratos e eficientes, que captam a movimentação das mãos dos usuários sobre eles. Como o nome diz, eles são resistores cuja resistência à passagem da corrente varia em função da quantidade de luz que atinge a sua superfície. É encontrado em qualquer boa casa de componentes eletrônicos.



Esse é o LDR. Instalamos seis desses sensores na mesa.
Como o nosso pobre Arduino Uno não tem portas disponíveis, resolvi multiplexar também as portas analógicas, de maneira a liberar algumas delas para uso em outros circuitos.
Para isso, usei o CI CD4051, que é também fácil de encontrar e muito barato.



Abaixo o esquema do bicho:

Os pinos y0 a y7 podem ser conectados a entradas (ou saídas, ele pode também ser usado para demux, mas não é o nosso caso) analógicas ou digitais. O pino z é o pino de saída, foi conectado a alguma porta analógica do Arduino. Os pinos S0, S1 e S2 servem para selecionarmos qual porta será lida pelo pino z.
Os pinos E, Vee, gnd devem ser conectados ao terra do Arduino, e o pino Vcc ao +5V da plaquinha.

Ligando o LDR

 Como o LDR é um sensor que varia resistência e o Arduino "mede" (capta) variação de tensão, é necessário criar um circuito que transforme a variação de resistência em variação de tensão. Para isso, montou-se um  circuito divisor de tensão. Abaixo, o esquema que usaríamos se ligássemos o sensor direto no Arduíno:



Observe o circuito. Veja que o LDR é ligado em série com um outro resistor, cujo valor nem importa tanto (pode ser algo entre 220 e 10k ohms), e as extremidades dessa ligação em série são ligadas ao terra e a 5V, respectivamente. Isso significa que a queda de tensão será de 5V entre os pontos A e B.
E entre A e C? Nesse caso, a variação depende da razão entre os resistores R1 e R2.

Vac = Vab * R2 / (R1+R2)

Ex: se R1 = R2 = R temos:

Vac = Vab * R / (R+R)
Vac = 5 * 0.5 = 2.5 V

Se  R1=2R2, temos:

Vac=Vab * 2R2 / (2R2+R2)
Vac=5 * 2/3 = 3.33V

Ou seja, quanto maior o valor de R1, maior a queda de tensão Vac. Como R2 é fixo e R1 varia em função da luminosidade, teremos uma leitura tensão variando em função da luminosidade, bastando ligar o ponto C a uma porta analógica do Arduino para termos uma leitura numérica da variação de luminosidade.
A única diferença entre esse e o nosso circuito é que o sinal do ponto C dos sensores é ligado ao CI de multiplexação.

Montei então o seguinte circuito:




















O exemplo tem somente 5 sensores por facilidade no desenho da protoboard.
Para a multiplexação basta, através dos pinos s0 a s2, selecionar o sensor a ser lido em um determinado momento. A ideia é enviar ao chip usando 3 bits o número do sensor a ser lido, em seguida ler o valor da porta A5, onde está ligado o pino z do CI.

Usando esse CI vc pode multiplexar "n" portas de Arduino, ligando outros chips, como mostra a figura abaixo, onde podemos obter 64 portas analógicas sendo lidas por somente um pino analógico, usando 9 4051.



Abaixo, o código, devidamente comentado:
int r0 = 0;      //valor do pino select s0 no 4051
int r1 = 0;      //valor do pino select s1 no 4051
int r2 = 0;      //valor do pino select s2 no 4051

int sensorValue;

#define ps0 7
#define ps1 6
#define ps2 5

void setup()
{
  Serial.begin(9600);
// seta os pinos select como saída
  pinMode(ps0,OUTPUT);    
  pinMode(ps1,OUTPUT);    
  pinMode(ps2,OUTPUT);    
}

void loop()
{
  for (int i=0; i<5; i++)
  {
// pega os bits do contador e coloca nas variáveis a serem enviadas. 
    r0=bitRead(i,0);
    r1=bitRead(i,1);
    r2=bitRead(i,2);
// envia os bits para as respectivas portas select (s0 a s3 no CI)
    digitalWrite(ps0,r0);
    digitalWrite(ps1,r1);
    digitalWrite(ps2,r2);
//  em seguida, lê o valor do sensor correspondente, que vai estar disponível no pino A5    
    sensorValue=analogRead(5);
//  exibe os valores lidos, por sensor
    Serial.print(i);
    Serial.print(',');
    Serial.print(r0 | (r1 << 1) | (r2 << 2),BIN);
    Serial.print(',');
    Serial.print(sensorValue);         
    Serial.print(',');    
    delay(1000);
  }
  Serial.println("");
}