quarta-feira, 5 de janeiro de 2011

Arduino dimmer com display de sete segmentos



A idéia é controlar o brilho de uma lâmpada com um potenciômetro ligado ao arduino mostrando o nível de luminosidade numa escala de zero a nove num display de sete segmentos. O display deve ficar aceso apenas enquanto estiver sendo feito ajuste pelo potenciômetro, apagando alguns segundos depois.

O display de sete segmentos

O funcionamento do display é bem simples. Os sete segmentos são formados por leds e para formar o caractere desejado basta acender os leds correspondentes. Em alguns displays existe um oitavo led que é um ponto na extremidade inferior esquerda. Existem displays com anodo comum ou catodo comum, lembrando que para acender um led o catodo deve ser ligado no negativo e o anodo no positivo. O que quer dizer que no caso do catodo comum este deve ser ligado ao pólo negativo e, logicamente, para acender o segmento desejado a saída correspondente do arduino deve ser colocada em nível alto. O inverso vale para o display de anodo comum.
A tabela ao lado mostra a relação entre o número formado e os segmentos que devem ser acesos.

O programa não tem nada de complicado.
Cada conjunto que representa um número foi armazenado em um vetor de bytes "sete_seg".
O potenciômetro é lido através da entrada analógica 0, o valor é armazenado na variável "val" que tem sua escala alterada para que seja compatível com PWM (0 a 255) e é aplicado ao pino 10 no qual esta ligado o circuito de acionamento da lâmpada A função escreve() é chamada passando um número de 0 a 9 proporcional ao PWM. A função escreve() pega o byte correspondente no vetor "sete_seg" lê bit a bit colocando em nível alto ou baixo o pino do segmento correspondente conforme os uns e zeros lidos respectivamente.

O circuito de acionamento da lâmpada dicróica 12V, 50W,  é formado basicamente por um MOSFET  IRF540 e um opto isolador 4N25, foi montado a partir do diagrama  deste site.

O código usado pode ser visto abaixo.
Se quizer pode baixa-lo aqui.

//     __a__
//   f|     |b
//    |__g__|
//   e|     |c
//    |__d__|
 
  
int sete_seg[7] = {8,7,6,5,4,3,2};  // pinos ligados ao display de 7 segmentos 
int lamp_Pin = 11;  // pino de saida
int potPin = 1;     // pino potenciometro
float val, val2 = 0;
unsigned long time = 10000;
unsigned long preview;


// cada byte abaixo corresponde a um numero no display. Desprezando o primeiro 0 cada bit corresponde a um segmento (a,b,c,d,e,f,g) respectivamente.
//  Bit 1 significa segmento correspondente aceso. Bit 0 significa segmento correspondente apagado
                      //    0         1         2           3         4           5         6           7          8          9      
byte     numero[10] = {B01111110, B00110000, B01101101, B01111001, B00110011, B01011011, B01011111, B01110000, B01111111, B01111011};


void setup()
{
  for(int i = 0; i<7; i++)
  pinMode (sete_seg[i], OUTPUT);
  
  pinMode ( lamp_Pin, OUTPUT);
  pinMode ( potPin, INPUT);
  preview = millis();

}

void loop()
{
val = analogRead (potPin);    // le o potenciometro
val = map(val,0,1024,0,255);  // ajusta a escala do valor lido 
analogWrite(lamp_Pin, val);  // manda o valor do PWM para a lampada

delay(50);

if((val2 < val - 1) || (val2 > val +1) )
{

escreve(val/25.5);     // escreve o valo de o a 9 no display
preview = millis();
}
else if ( time <  millis() - preview )
{
apaga();
}

val2 = val;

}


void escreve(int num)
{
 byte aux;
 aux = numero[num];
 
 for(int i= 7; i >= 0; i --)     // laco despresa o bit mais significativo
 {
 if(bitRead(aux,i )==1)         // le bit a bit
 {

 digitalWrite(sete_seg[i] , HIGH); 
 } 
 else
 {
 digitalWrite(sete_seg[i] , LOW);

 }
   
 }

}

void apaga()
{
  for(int i = 7; i >= 0; i --)
  digitalWrite(sete_seg[i] , LOW);

}