Básico - Hub 013

Cronômetro com pause e reset (interrupção por timer)

 

Sugerido por: Wagner G L ENVIAR SUGESTÃO

Objetivo

O objetivo é adaptar o Projeto 64 - Cronômetro com display TM1637 e Arduino acrescentando botões de pause (congelar tempo) e reset (zerar cronômetro). Também deve ser acrescentado a um display LCD para visualizar minutos, segundos e centésimos de segundos.  Neste projeto vamos utilizar o recurso de interrupção por timer, substituindo a função millis() que utilizamos no projeto Hub 012 - Cronômetro com botões de pause e reset - Arduino.

Obs.: O cronômetro sugerido é limitado até 60 minutos.

Interrupção por timer (Timer Interrupts)

Embora semelhante à interrupção externa, a interrupção por timer ocorre através do tempo e não por uma ação externa do hardware. Assim, a cada período podemos executar uma função independente, sem que a contagem do tempo seja interferida pelos demais comandos do programa. A interrupção por timer substitui as funções: delay(), millis() e o controle de loop for, gerando um intervalo de tempo independente. Neste projeto, a cada 10.000 microssegundos, ou seja, a cada centésimo de segundo, a função de contagem de tempo é executada.

Obs.: Para utilizarmos o recurso da interrupção por timer no Arduino precisaremos instalar a biblioteca TimerOne, conforme mostraremos durante o tutorial do projeto.

Componentes necessários

Referência

Componente

Quantidade

Imagem

Observação

Protoboard Protoboard 830 pontos 1 Resultado de imagem para protoboard 830v

No mínimo utilizar protoboard com 830 pontos

Jumpers Kit cabos ligação macho / macho 1  
Módulo TM1637

Módulo TM1637 - 4 dígitos(anodo comum)

 

1 Módulo TM1637 com display 4 dígitos - Controlador TM1637
- Alimentação: 3.3 à 5V DC
- Display 7 segmentos 4 dígitos anodo comum

datasheet

Push Button

Push button 6X6X5mm

2  
Display LCD Display LCD 16X2 1 DISPLAY LCD 16X2

LCD que utilize o controlador HD44780 (veja na descrição ou datasheet do componente)

O display poderá ser de qualquer cor (fundo verde, azul ou vermelho)

Módulo I2C para display LCD

Módulo I2C com CI PCF8574

(opcional)

1 Módulo I2C display LCD Arduino

O módulo I2C poderá vir separado ou já soldado no display LCD

(datasheet)

Se você não possui um módulo I2C para display LCD, poderá adaptar o projeto para o display LCD sem o adaptador

Arduino UNO R3 Arduino UNO 1

Você poderá utilizar uma placa Arduino UNO original ou similar

Montagem do Circuito

Referências

Projeto 79 - Interrupção por timer no Arduino - disparo de alarme com sensor de toque

Projeto 64 - Cronômetro com display TM1637 e Arduino

Projeto 63 - Usando o módulo TM1637 (display 4 dígitos) com Arduino

Projeto 48 - Como controlar um display LCD com o módulo I2C

Projeto 38 - Controlando um display LCD (instalação e comandos básicos) - Caso opte por usar o LCD sem o módulo I2C

Bibliotecas

Para controlarmos o módulo TM1637 vamos precisar das bibliotecas TM1637Display (download) e para o display LCD com módulo I2C precisaremos da biblioteca NewliquidCrystal_1.3.4.zip (download).

Também utilizaremos a biblioteca TimerOne (download) para facilitar a utilização do timer interno do Arduino via software. Assim, podemos configurar o Arduino através de métodos pré-definidos na biblioteca, para medir repetidamente um período de tempo em microssegundos. No final de cada período, uma função de interrupção poderá ser executada.

Após fazer o download dos arquivos das bibliotecas com todos os arquivos compactados no formato zip, abra o IDE do Arduino e siga o tutorial: Como incluir uma biblioteca no IDE do Arduino.

Para conhecer outras bibliotecas veja a Tabela Biblioteca para Módulos e Tabela Bibliotecas para Sensores.

Código do Projeto (Sketch)

Faça o download e abra o arquivo hub013.ino no IDE do Arduino: DOWNLOAD - hb013.ino

Ou se preferir, copie e cole o código abaixo no IDE do Arduino:

/*******************************************************************************
*
*    Hub 13: Cronômetro (Interrupção por timer) e Arduino (pause e reset)
*    Autor: Angelo Luis Ferreira
*    Data: 07/07/2021
*    
*             http://squids.com.br/arduino             
*
*******************************************************************************/
// incluindo bibliotecas
#include  <LiquidCrystal_I2C.h> // Inclui a biblioteca LiquidCrystal_I2C (LCD)
#include <TM1637Display.h> // Inclui a biblioteca TM1637Display
#include <TimerOne.h> // Inclui a biblioteca TimerOne
 
// definições pinos do Arduino
const byte CLK = 2; // Define pino 2 como CLK
const byte DIO = 3; // Define pino 3 como DIO

const byte pinButPause = 8; // Define a porta digital 8 para o push button (pausa)
const byte pinButReset = 9; // Define a porta digital 12 para o push button (reset)

// declarações de variáveis
byte mode = 0;
unsigned long cSegundos = 0;
unsigned int segundos = 0;
byte minutos = 0;

// Cria o array position[] para armazenar os valores do cronômetro no TM1637
uint8_t position[] = { 0, 0, 0, 0 }; //
 
// Cria o objeto "lcd" (display no endereço 0x27)
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE);
 
// Cria o objeto "display" da biblioteca TM1637
TM1637Display display(CLK, DIO);
 
void setup() {
  // define o timer
  Timer1.initialize(10000); // conta tempo a cada centésimo (1/100) de segundo 
  // ajusta displays     
  display.setBrightness(3); // Ajusta o brilho para do do TM1637
  lcd.begin (16,2); // inicia o display LCD 
  // exibe título no display LCD
  lcd.setCursor(1,0);
  lcd.print("Cron");
  lcd.write(239);
  lcd.print("metro");  
  // define pinMode dos botões
  pinMode(pinButPause, INPUT_PULLUP); // Habilita o pull up interno do Arduino
  pinMode(pinButReset, INPUT_PULLUP); // Habilita o pull up interno do Arduino
}
 
void loop() {
     // verifica se o botão Pause (pushbutton) está pressionado e muda o controle
    if (!digitalRead(pinButPause)) {         
      mode = 1; // vai para pauseMode
      while (!digitalRead(pinButPause)) {  }  //esperera soltar o botão
      delay(50);
    }
     // verifica se o botão Reset (pushbutton) está pressionado e muda o controle
    if (!digitalRead(pinButReset)) {         
      mode = 0; // vai para resetMode
      while (!digitalRead(pinButReset)) {  }  //esperera soltar o botão
      delay(50);
    }
  
    // menu de controle
    switch (mode) {
      case 0:
        resetMode();
        break;
      case 1:
        pauseMode();
        break;
      case 2:
        runMode();
        break;
      default:
        resetMode();   
    }
}

// Modo RUN - roda o cronômetro
void runMode() {
    // conta o tempo do cronômetro
    Timer1.attachInterrupt(contadorTempo);
  
  // Calculo individual para posição no display
  position[0] = display.encodeDigit((segundos / 60) / 10); // Dezena de minuto
  position[1] = display.encodeDigit((segundos / 60) % 10); // Unidade de minuto
  position[1] = position[1] + 128; // coloca o separador ":"
  position[2] = display.encodeDigit((segundos % 60) / 10); // Dezena de segundo
  position[3] = display.encodeDigit((segundos % 60) % 10); // Unidade de segundo
 
  //Mostra os valores no display TM1637
  display.setSegments(position);

  //Mostra os valores no display LCD
  lcd.setCursor(1,1);
  lcd.print((segundos / 60) / 10); // Dezena de minuto  
  lcd.setCursor(2,1);
  lcd.print((segundos / 60) % 10); // Unidade de minuto
  lcd.setCursor(3,1);
  lcd.print(":");
  lcd.setCursor(4,1);
  lcd.print((segundos % 60) / 10); // Dezena de segundo
  lcd.setCursor(5,1);
  lcd.print((segundos % 60) % 10); // unidade de segundo
  lcd.setCursor(6,1);
  lcd.print(",");
  lcd.setCursor(7,1);
  lcd.print((cSegundos / 10) % 10); // Décimo de segundo
  lcd.setCursor(8,1);
  lcd.print((cSegundos % 10) % 10); // Centésimo de segundo 

  // Define máximo de 60 minutos -> vai para pause
  if (((segundos / 60) / 10) == 6) {
    pauseMode(); // vai para pauseMode
  }                  
}

// mod RESET -> zera o cronômetro
void resetMode() {
  // interrompe contador de tempo
  Timer1.stop(); // remover interrupção do timer 
  Timer1.setPeriod(10000);  
  // Zera o display
  position[0] = display.encodeDigit(0); // Dezena de minuto
  position[1] = display.encodeDigit(0); // Unidade de minuto
  position[2] = display.encodeDigit(0); // Dezena de segundo
  position[3] = display.encodeDigit(0); // Unidade de segundo
  // coloca o separador dois pontos (:)
  position[1] = position[1] + 128; 

  //Mostra os valores no display TM1637
  display.setSegments(position);

  //Zera display LCD
  lcd.setCursor(1,1);
  lcd.print("00:00,00"); 
   
  // Aguarda pressionar o botão Pause
  while(digitalRead(pinButPause)) { } // espera apertar o botão para iniciar
  while (!digitalRead(pinButPause)) { }  //esperera soltar o botão  
  delay(50);
  cSegundos = 0; // zera o contador de tempo
  mode = 2;  
}

// mode Pause -> pausa o cronômetro
void pauseMode() {
  // interrompe contador de tempo
  Timer1.detachInterrupt(); // remover interrupção do timer  
    
  // Aguarda pressionar o botão Pause para reiniciar  
  while(digitalRead(pinButPause)) { 
    // verifica se o botão Reset (pushbutton) está pressionado e muda o controle
    if (!digitalRead(pinButReset)) {         
      while (!digitalRead(pinButReset)) {  }  //esperera soltar o botão Reset
      delay(50);
      resetMode(); // vai para modeReset
      break;
    }  
  } // espera apertar o botão
  while (!digitalRead(pinButPause)) { }  //esperera soltar o botão Pause
  delay(50);
  mode = 2; 
}

void contadorTempo() {
  cSegundos++;
  segundos = cSegundos / 100;
}

Vídeo

Compartilhe:

Doações

Contribua pra manter o site online :)

Inscreva-se no canal Squids

Squids Arduino News

Básico - Projeto 98 Módulo Matriz de Led rítmico - MAX7219 Objetivo O objetivo deste projeto é criar um circuito para fazer com que os leds de uma matriz de leds pisquem de acordo com o ritmo d...

Básico - Projeto 97 Leds piscam de acordo com o som Objetivo O objetivo deste projeto é criar um circuito para fazer piscar vários leds de acordo com o ritmo de uma música. Para isso, vamos uti...

Desafio 89 - Projeto I13 Dez efeitos de iluminação com controle remoto Com base no projeto I13 - Como usar o Controle Remoto Infravermelho com Arduino resolva o seguinte desafio: 1. Com base...

Intermediário - Projeto 13 Usando o Controle Remoto IR com Arduino com leds Objetivo Utilizar o Controle Remoto Infravermelho junto com o Arduino e um fotorreceptor IR para controlar 6 leds de ...

Desafio 88 - Projeto I12 Cronômetro contador de voltas com sensor infravermelho Com base no projeto I12 - Cronômetro com pause controlado por leds infravermelhos - Arduino resolva os seguintes ...

Outros artigos

Mais: Projetos Básicos Desafios Projetos Intermediários Básico

Você está preparado?

Topo