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

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

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.

Faça seu comentário

Acesse sua conta e participe

7 Comentários

  1. Gostaria de fazer um timer com display de 2 dígitos para controlar dois grupos de micro bombas peristalticas de 12 volts onde 3 podem ser ligadas juntas para ejetar líquido e uma outra separada, então seria um temporizador com a opção de selecionar uma ou outra bomba com start para o acionamento e outro botão de ajuste de tempo, desde já agradeço.

  2. O exemplo do LM35 precisa ser revisado, já troquei o sensor e as leituras ficam instáveis quando uso do multishield Arduino, já consegui 12 exemplos legais incluindo este maravilhoso do temporizador. O do relógio com alarme é bem legal também.

    1. Olá Carlos,

      Você testou o LM35 sem a multishield Arduino? Pode ser que o problema esteja no seu LM35.

      Abraço!
      Rosana – Equipe MakerHero

  3. Parabéns por explorar o multishield Arduino, tenho 4 unidades e utilizo com aulas introdutorias ao Arduino. Tem que isolar o conector usb do Arduino Uno pois toca nos terminais do display e fecha curto.

    1. Você tem razão sobre o risco de curto, se observar com muita atenção a primeira foto, vai ver que eu colei uma fita isolante na parte superior do shield.

  4. Bacana de mais esse tutorial, vou tentar fazer, obrigado

    Gostaria de aproveitar e pedir um tutorial relacionado ao esp32 e firebase, e fazer com que os dois se comuniquei e que guardem informações de RFID enviando para o firebase e tambem que faça comparação com as tags salvas no firebase com as tags que estão sendo lidas.

    Se ja existir esse tutorial por favor me informe.

    Desde já agradeço.

    1. Olá Marcos,

      No nosso blog temos um tutorial sobre a Raspberry Pi Zero W e o Google Firebase. A programação no ESP32 será diferente, mas acredito que seja uma boa referência.

      Abraço!
      Rosana – Equipe MakerHero