blog Temporizador com o Shield Arduino Multifunções intermediário

Temporizador com o Shield Arduino Multifunções Intermediário Deixe um comentário

O Shield Arduino Multifunções Nível intermediário não somente é uma excelente ferramenta para aprendizado do uso do Arduino, como pode ser usada para construir alguns dispositivos de uso prático. Neste tutorial vamos ver como construir um temporizador – um circuito que faz uma contagem decrescente de tempo e sinaliza o seu fim com um sinal sonoro. É um aparelho útil para controlar o tempo na cozinha, em apresentações, etc.

temporizador com shield

Como já foi falado aqui no blog, o Shield Arduino Multifunções Intermediário tem vários dispositivos, vamos usar três deles: os botões, o buzzer e o display de quatro dígitos. A montagem se resume a encaixar o shield no Arduino – este é um projeto essencialmente de software. Vejamos como vamos tratar os dispositivos:

Buzzer

Este é o mais simples: é controlado pela saída digital 3. Colocando o pino 3 em nível alto (HIGH) o som é emitido, colocando o pino em nível baixo (LOW) o som para.

Botões

O shield possui três botões, ligados aos pinos A1, A2 e A3 (os pinos analógicos do Arduino podem ser usados também para entrada e saída digital). Com o jumper J2 instalado, estes pinos serão lidos em nível 0 quando o botão for apertado e em nível 1 quando o botão estiver solto (o jumper J2 liga resistores entre os pinos das chaves e a alimentação de 5 V).

Um cuidado a tomar é com o debounce: quando os botões são apertados ou soltos o sinal pode oscilar por algum tempo. Existem diversas estratégias para evitar que esta oscilação seja tratada como vários pressionamentos, vou usar aqui a mais simples: aguardar um tempo após detectar a mudança no sinal.

Display

O display é composto de quatro dígitos, cada um com sete segmentos e um ponto decimal. A conexão ao Arduino é feita através de dois integrados 74HC595 em série. O 595 é um shift register de 8 bits; usando os dois integrados temos um registrador de 16 bits para o qual você envia os bits um a um através de um sinal de dados (pino digital 8 do Arduino) e de um sinal de clock (pino digital 7). Um terceiro sinal (latch, pino digital 4) é usado para colocar o valor atual do registrador nos pinos do display. A figura abaixo (adaptada do esquema da placa) mostra a conexão.

Display do temporizador

Com este tipo de display apresentamos um dígito por vez, nesta montagem controlamos os segmentos através do segundo 74HC595 e escolhemos o dígito a apresentar no primeiro.O truque é mostramos rapidamente um dígito de cada vez, a vista é enganada para pensar que todos estão acesos ao mesmo tempo.

Operação do Temporizador

A operação do temporizador é bastante simples:

  • Use o primeiro botão para escolher o valor inicial. Este botão só é aceito quando o contador está parado.
  • Use o segundo botão para iniciar (ou retomar) a contagem. Este botão só é aceito quando o contador está parado.
  • Use o terceiro botão para parar a contagem. Este botão só é aceito quando o contador está andando.

Os dois primeiros dígitos no display são os minutos e os dois últimos os segundos. Quando a contagem chega a zero, o sinal sonoro é emitido. Aperte qualquer botão para parar o som.

Para expor melhor o funcionamento do shield multifunções vamos interagir direto com ele ao invés de usar a biblioteca específica. A única biblioteca externa que vamos usar é a TimerOne, que você pode instalar diretamente do Gerenciador de Bibliotecas.

temporizador com biblioteca

temporizador com biblioteca2

O código do temporizador com o shield arduino multifunções intermediário fica:

/*
    Temporizador com o Shield Arduino Multifunções Intermediário
*/

#include <TimerOne.h>  

// conexões
const int pinBotao1 = A1;  
const int pinBotao2 = A2;  
const int pinBotao3 = A3;  
const int pinBuzzer = 3;
const int pinLatch = 4;  
const int pinClock = 7;  
const int pinDado = 8;  

// teste de botão apertado
#define apertado(pino) (digitalRead(pino) == LOW)
  
// Desenho dos numeros  
const uint8_t numero[10] = {  
  0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90  
};  
  
// Selecao dos digitos  
const uint8_t digito[4] = {  
  0x01, 0x02, 0x04, 0x08  
};  
  
// Valor a apresentar no display  
volatile uint8_t valor[4] = { 0, 0, 0, 0 };  

// Temporizações disponíveis (mmss)
uint16_t temporizacao[] = { 30, 100, 500, 1500, 3000, 0 };
uint8_t sel = 0;

// Contagem para medir um segundo
volatile uint16_t contSeg;

// Controle
volatile enum { PARADO, ANDANDO, ALARME } estado = PARADO;

// Iniciação  
void setup() {
  // Inicia os pinos
  pinMode (pinLatch, OUTPUT);  
  pinMode (pinClock, OUTPUT);  
  pinMode (pinDado, OUTPUT);  
  pinMode (pinBuzzer, OUTPUT);  
  pinMode (pinBotao1, INPUT);  
  pinMode (pinBotao2, INPUT);  
  pinMode (pinBotao3, INPUT);  
  
  // Coloca o valor inicial no display  
  iniciaValor();
  
  // Inicia o timer  
  Timer1.initialize(2000); // 2 ms  
  Timer1.attachInterrupt (timerIsr);
}

// Loop principal - trata botões
void loop() {
  switch (estado) {
    case PARADO:
      if (apertado(pinBotao2)) {
        esperaSoltar();        
        cli();
        contSeg = 500;
        estado = ANDANDO;
        sei();
      } else if (apertado(pinBotao1)) {
        esperaSoltar();        
        sel++;
        if (temporizacao[sel] == 0) {
          sel = 0;
        }
        iniciaValor();
      }
      break;
    case ANDANDO:
      if (apertado(pinBotao3)) {
        cli();
        digitalWrite (pinBuzzer, LOW);
        estado = PARADO;
        sei();
      }
      break;
    case ALARME:
      if (apertado(pinBotao1) || apertado(pinBotao2) || apertado(pinBotao3)) {
        digitalWrite (pinBuzzer, LOW);
        //noTone (pinBuzzer);
        estado = PARADO;
        esperaSoltar();        
        iniciaValor();
      }
      break;
  }  
}

// Espera soltar todos os botões
void esperaSoltar() {
  delay(100);  // debounce
  while (apertado(pinBotao1) || apertado(pinBotao2) || apertado(pinBotao3)) {
    delay(100);
  }
  delay(100);  // debounce
}

// Coloca a temporização selecionada no display
// Só chamar com o contador parado
void iniciaValor() {
  uint16_t tempo = temporizacao[sel];
  valor[0] = (uint8_t) (tempo / 1000);
  valor[1] = (uint8_t) ((tempo / 100) % 10);
  valor[2] = (uint8_t) ((tempo / 10) % 10);
  valor[3] = (uint8_t) (tempo % 10);
}

// Interrupção do timer, atualiza o display a cada 2 ms e
// decrementa a contagem de tempo e testa se chegou a zero
void timerIsr() {  
  static uint8_t iDig = 0;

  // decrementa contador se andando
  if ((estado == ANDANDO) && (--contSeg == 0)) {
    if (valor[3] != 0) {
      valor[3]--;
    } else {
      valor[3] = 9;
      if (valor[2] != 0) {
        valor[2]--;
      } else {
        valor[2] = 5;   // 60 segundos em cada minuto
        if (valor[1] != 0) {
          valor[1]--;
        } else {
          valor[1] = 9;
          if (valor[0] != 0) {
            valor[0]--;
          } else {
            valor[0] = 9;
          }
        }
      }
    }
    if ((valor[0] + valor[1] + valor[2] + valor[3]) == 0) {
      // Contagem chegou a zero, dispara o alarme
      digitalWrite (pinBuzzer, HIGH);
      estado = ALARME;
    }
    contSeg = 500;
  }

  // atualiza o display    
  digitalWrite(pinLatch, LOW);  
  shiftOut(pinDado, pinClock, MSBFIRST, numero[valor[iDig]]);  
  shiftOut(pinDado, pinClock, MSBFIRST, digito[iDig]);  
  digitalWrite(pinLatch, HIGH);  
  iDig = (iDig+1) & 3;  
}

Gostou de ver como fazer um temporizador usando um Shield Arduino Multifunções Nível Intermediário? Ajude-nos a melhorar o blog comentando abaixo sobre este tutorial. Não se esqueça de visitar o fórum da FILIPEFLOP!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *