22 de setembro de 2012

Contador de Passagem

O infravermelho detectou, o display contou!



O projeto é composto basicamente de um display de 7 segmentos com 4 digitos e anodo comum, um CI 74HC595, um Led IR, um receptor IR (fototransitor) e um arduino.

Para o funcionamento correto desse display é necessário multiplexar os digitos. Reparem no código que apenas um digito é acionado por vez.

Segue o esquema elétrico do display, o esquema do projeto, e o código fonte.

Valeu!

/*-------------------------------------
 CONTADOR DE PASSAGEM
 4 digitos / 7 segmentos / anodo comum.
 Fellipe Couto - 22/09/2012
 ------------------------------------*/

/*
 LIGACAO DOS PINOS DO DISPLAY AO REGISTRADOR:
 74HC595 - 15 | 01 | 02 | 03 | 04 | 05 | 06 | 07 |
 DISPLAY - 14 | 16 | 13 | 03 | 05 | 11 | 15 |    |
 Ex.: Pino 15 do registrador ligado ao pino 14 do display, com resistor 220 ohms;

 ARDUINO - 02 | 03 | 04 | 05
 DISPLAY - 01 | 02 | 06 | 08
 Ex.: Pino 2 do arduino ligado ao pino 1 do display, com resistor 220 ohms;

 LIGACAO DO 'DOIS PONTOS' DO DISPLAY:
 -Pino 6 do Arduino é ligado ao pino 4 do display, com um resistor de 220 ohms.
 -Pino 12 do display é ligado ao GND.
 */

int latchPin = 8;  //Conectado ao pino 12 do 74HC595.
int clockPin = 12; //Conectado ao pino 11 do 74HC595.
int dataPin = 11;  //Conectado ao pino 14 do 74HC595.
int d[5] = {
  2, 3, 4, 5, 6};  //digito 1, digito, 2, digito 3, digito 4, dois-pontos.
int count = 0;
long previousMillis = 0;
long interval = 1000;

void setup(){
  pinMode(latchPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(dataPin,OUTPUT);
  for (int i=0; i<5; i++){
    pinMode(d[i], OUTPUT);
  }
}

void loop(){
  if (analogRead(0) > 90){
    if(millis() - previousMillis > interval) {
      previousMillis = millis();
      count++;
    }
  }
  displayNumber(count);
}


void displayNumber(int num){
  int n[4];
  String aux;

  if (num > 9999){
    num = 0;
  }

  if (num < 10){
    aux += "000";
    aux += num;
  }
  else if (num < 100){
    aux += "00";
    aux += num;
  }
  else if (num < 1000){
    aux += "0";
    aux += num;
  }
  else{
    aux += num;
  }

  n[0] = aux.substring(0,1).toInt();
  n[1] = aux.substring(1,2).toInt();
  n[2] = aux.substring(2,3).toInt();
  n[3] = aux.substring(3,4).toInt();

  for (int p=0; p<4; p++){ //Acende um digito por vez.
    byte bDisplay[10] = {
      B11111100, B01100000, B11011010, B11110010, B01100110, B10110110, B10111110, B11100000, B11111110, B11110110                        };
    for (int i=0; i<4; i++){ //Apaga todos os digitos
      digitalWrite(d[i], LOW);
    }
    digitalWrite(latchPin, LOW); //Define latchPin como LOW, para permitir o envio de dados ao registrador.
    shiftOut(~bDisplay[n[p]]); //Envia os dados ao registrador.
    digitalWrite(latchPin, HIGH); //Define latchPin como HIGH, para interromper o envio da dados ao registrador.
    digitalWrite(d[p], HIGH); //Acende a posição do digito.
    delay(1);
  }

}

void shiftOut(byte dataOut){
  //Desloca 8 bits, com o bit menos significativo (LSB) sendo deslocado primeiro, no extremo ascendente do clock.
  boolean pinState;
  digitalWrite(dataPin, LOW); //Deixa o registrador de deslocamento pronto para enviar dados.
  digitalWrite(clockPin, LOW);
  for (int i=0; i<8; i++){ //Para cada bit em dataOut, envie um bit.
    digitalWrite(clockPin, LOW); //Define clockPin como LOW antes de enviar o bit.
    //Se o valor de dataOut E(&) de uma mascara de bits forem verdadeiros, defina pinState como 1 (HIGH).
    if (dataOut & (1<<i)){
      pinState = HIGH;
    }
    else{
      pinState = LOW;
    }
    digitalWrite(dataPin, pinState); //Define dataPin como HIGH ou LOW, dependendo de pinState.
    digitalWrite(clockPin, HIGH); //Envia o bit no extremo ascendente do clock.
  }
  digitalWrite(clockPin, LOW); //Interrompe o deslocamento de dados.
}

7 comentários:

  1. Boa Noite amigo,na sua lib como faço para mostrar por exemplo : A512?

    ResponderExcluir
    Respostas
    1. Bom dia, Ernado!

      Na função que fiz, os dígitos estão declarados dentro do array byte bDisplay[10].
      Esse display não é próprio para exibição de letras. Mas poderia improvisar a letra A (maiúsculo) e a letra b (minúsculo). Na forma "A500" e "b100". E neste caso, seria necessário efetuar uma mudança na função displayNumber também, pois ela recebe números como parâmetro. A mudança seria para identificar quando seria exibido a letra.

      Essa alteração pode ser ser de várias formas. Fica a seu critério.
      Se precisar de ajuda para essa alteração também, só dizer que tento alguma modificação para te passar, ok?!

      Abraços!

      Excluir
    2. Boa noite Felipe,estive ausente mas agora estou retomando o projeto.
      Ja consegui fazer 90% de meu projeto e como não estou conseguindo fazer aparecer o Axxx e o dxxx estou acendendo e apagando o ponto decimal.
      Quando aperto um botao gostaria que display aparecesse (A) de automatico ou (d) de demo e poderia colocar o numero nos outros 3 digitos. Ex A500 ou d210.

      Excluir
    3. Bom dia, Ernando!
      Os números são armazenados no vetor (array) " byte bDisplay[10] ". São 10 posições para armazenar os digitos de 0 a 9. Altere para 12, e adicione o byte referente as letras.
      Ex.: B01100000 diz que o segmento A do display estará apagado, os segmentos B e C estarão acessos, e os demais segmentos apagados. Assim montamos os números, e dessa mesma forma pode montar as possíveis letras.

      Excluir
  2. Este comentário foi removido pelo autor.

    ResponderExcluir
  3. PODE SE USAR UM DISPLAY DE LCD NO LUGAR DO SETE SEGMENTOS?

    ResponderExcluir
    Respostas
    1. Bom dia! É necessário uma alteração no fonte para substituir o display pelo LCD, mas nada complicado. Pode sim.
      Abraços!

      Excluir