O contador de voltas – Giro motor

Se você deseja avaliar o movimento de um objeto, como por exemplo quanto tempo um corpo demora para percorrer uma determinada distância ou quantas vezes o objeto passa por um determinado ponto, é interessante utilizar um equipamento que consiga detectar movimentos e que exiba em um display as informações que você deseja obter do movimento avaliado. Neste tutorial, iremos aprender a construir um contador de voltas que se baseia em dados obtidos pelo sensor ultrassônico HC-SR04 e que exiba em um display LCD 16×2 informações como o número de voltas dada pelo objeto, o tempo da volta, o tempo total do percurso e a diferença entre o tempo da volta e o tempo ideal.

Esse tipo de equipamento pode ser usado, por exemplo, para se obter a velocidade de um veículo a cada vez que este passa pelo contador durante uma volta em uma pista, ou em aplicações esportivas, como no atletismo, onde é necessário medir o tempo de prova do atleta.

Arduino Uno

O dispositivo básico para o desenvolvimento do projeto é a plataforma a ser utilizada na programação das funcionalidades e na integração dos componentes, que neste caso poderá ser um Arduino Uno, com o qual grande parte dos leitores já estão familiarizados.

Arduino Uno

kit robotica educacional com Arduino ESP ou Microbit

Para os leitores que estão entrando agora no mundo da eletrônica e não conhecem esta plataforma, o link abaixo explica com clareza o que é e como funciona o Arduino Uno e outros:

https://portal.vidadesilicio.com.br/o-que-e-arduino-e-como-funciona/

O sensor ultrassônico HC-SR04

O sensor ultrassônico HC-SR04 é composto de um circuito pronto com um emissor e um receptor de ondas sonoras. O sinal emitido, ao colidir com qualquer obstáculo, é refletido de volta na direção do sensor. Durante todo o processo, o aparelho está com uma espécie de “cronômetro” de alta precisão funcionando. Assim, é possível saber quanto tempo o sinal levou desde a sua emissão até o seu retorno. Como a velocidade do som no ar é conhecida, é possível, de posse do tempo que o sinal levou para ir até o obstáculo e voltar, calcular a distância entre o sensor e o obstáculo.

Sensor Ultrassônico HC-SR04

O sensor possui 4 pinos:

  • VCC: alimentação em 5V
  • GND
  • Trigger: pino digital; responsável por emitir 8 pulsos ultrassônicos na frequência de 40khz em intervalos de tempo contínuos que, ao encontrarem um objeto, são parcialmente refletidos ao sensor
  • Echo: um PWM, que recebe a informação coletada pelo sensor e traduz como dados ao arduino – no código, esses dados são tratados e transformados nas informações exibidas à quem utiliza o sistema.

O sensor é capaz de medir distâncias de 2 cm a 4 m com precisão de 3mm, e consegue detectar objetos cuja área mínima é de 0,05 m².

O display LCD 16×2

O display LCD 16×2 é muito usado em projetos com arduino onde é necessário que haja uma apresentação visual de informações. No link abaixo você poderá ter maiores informações sobre o funcionamento do display LCD e seu uso com o Arduino Uno e outros:

https://portal.vidadesilicio.com.br/display-lcd-16×2-com-arduino/

O display LCD utilizado neste tutorial é formado por 16 colunas e 2 linhas, com backlight (luz de fundo) azul e letras na cor branca. O dispositivo LCD apresenta 16 pinos de contatos, os quais:

  • Pino 1 (VSS): GND
  • Pino 2 (VCC): alimentação em 5V
  • Pino 3 (V0): tensão para ajuste de contraste
  • Pino 4 (RS): seleção do sinal (1 para passar um dado, 0 para passar uma instrução)
  • Pino 5 (RW): habilitação de escrita e leitura (1 para ler, 0 para escrever)
  • Pino 6 (E): enable (1 para habilitar, 0 para desabilitar)
  • Pinos 7 a 14 (B0 a B7): barramento de dados (conectados aos pinos digitais do arduino)
  • Pinos 15 e 16 (A e K): responsáveis por fornecer energia aos LEDs que ficam ao fundo do display
Display LCD 16×2

Você poderá optar por utilizar um módulo I2C para ligar o arduino ao display, o que lhe poupará pinos e permitirá que você insira novos componentes e funcionalidades ao seu projeto. Com o módulo I2C, as 16 ligações do display ao arduino são reduzidas a 4. O link abaixo mostra como utilizar o LCD dessa maneira:

https://portal.vidadesilicio.com.br/display-lcd-20×4-16×2-adaptador-i2c/

Mãos a obra – Imprimindo informações no display a partir de dados obtidos pelo sensor

Componentes necessários

Montando o projeto

Esquemático do projeto
  • Conecte os pinos de VCC (ou VDD) do display, do sensor, dos leds e do potenciômetro ao 5V do arduino.
  • Conecte os pinos de GND do display, do sensor, dos LEDs e do potenciômetro ao GND do arduino.
  • Conecte o pino V0 do display ao terminal do meio do potenciômetro.
  • Conecte o pino RS do display ao pino digital 13 do arduino e o pino de enable do display ao pino 12 do arduino.
  • Aterre os pinos B0 a B3 que não serão utilizados, além do pino RW.
  • Interligue os pinos D4 a D7 ao pinos 11 a 8 do arduino, respectivamente.
  • Aterre o pino K do display e interligue o pino A ao 5V do arduino.
  • Conecte o pino de Trigger do sensor ao pino 7 do arduino, e o pino de Echo ao pino digital 6.
  • Faça a conexão do LED vermelho ao pino 4 do arduino e o LED verde ao pino 3, lembrando de colocar os resistores de 330 Ω entre os LEDs e os pinos digitais.
  • O pushbutton deve ser interligado ao 5V e ao GND do arduino, sendo que a ligação do GND deve ser feita através de um resistor de 1k Ω. Conecte o pino 5 do arduino ao pushbutton, sendo que a ligação deve ser entre o pino digital e o meio entre o pushbutton e o resistor de 1k Ω (divisor de tensão do potenciômetro).

Tendo em vista que o potenciômetro é um resistor de resistência variável, ele foi utilizado no projeto para variar o contraste do display. Além disso, o pino A do display foi interligado ao 5V para fornecer brilho máximo a tela, facilitando visualizar as informações que serão exibidas.

Para este projeto, considerou-se a situação de um veículo dando voltas em uma pista e, portanto, as informações exibidas no display são tempo da volta, tempo total, número de voltas e diferença entre o tempo da volta e o tempo ideal. Você pode alterar o código do projeto para exibir informações diferentes dependendo do seu interesse.

Considerando que o sensor ultrassônico é capaz de calcular distâncias, a detecção da passagem do veículo pelo sensor, contabilizando uma volta, foi feita a partir de uma faixa de distâncias detectadas pelo sensor que indicaria a passagem do veículo. Dessa forma, o sensor estaria continuamente medindo uma distância fixa e, se caso a distância medida fosse reduzida para um valor dentre uma faixa de valores estipulados, haveria a indicação de que o veículo passou pelo sensor e completou uma volta.

Um pushbutton foi utilizado para indicar o início da contagem pelo contador de voltas. Também utilizou-se um led vermelho para alertar se caso o tempo da volta fosse maior do que o tempo ideal e um led verde para se caso o tempo da volta fosse menor do que o tempo ideal estipulado.

Verifique como ficou nossa montagem na prática:

Montagem do projeto na prática

Bibliotecas

Para estabelecer a comunicação com o display e imprimir informações no LCD, foi utilizada a biblioteca “LiquidCrystal.h”. Esta biblioteca geralmente já acompanha a IDE do arduino e pode ser encontrada na aba “Incluir Biblioteca” dentro de “Sketch”.

Como encontrar a biblioteca “LiquidCrystal.h”

Ademais, para obter os dados gerados pelo sensor ultrassônico HC-SR04, foi utilizada a biblioteca “Ultrasonic.h”. Você pode baixar-lá no site:  https://github.com/filipeflop/Ultrasonic.

Instale a biblioteca no diretório padrão de suas bibliotecas. Geralmente, este diretório se encontra dentro da pasta “Arduino”, localizada em “Documentos”.

Adicionando a biblioteca ao diretório

Código do projeto

Segue o código a ser usado no projeto:

#include <LiquidCrystal.h>
#include <Ultrasonic.h>

//Define os pinos do Arduino ligados ao Trigger e Echo
#define PINO_TRG  7
#define PINO_ECHO 6

//Pino para push button de ação
#define pino_pushbutton 5

//Pinos conectados aos Leds
#define LEDVM 4
#define LEDVD 3

//Tempo ideal por volta em segundos
#define IDEAL 20

//Número total de voltas
#define NVOLTAS 11

//Variavel para armazenar o valor obtido pelo sensor
long microsec;

//Variavel para guardar o valor da distância obtida pelo sensor em cm
float cmMsec;

//Faixa de distancia para a identificacao da placa
float distancia_minima = 100;
float distancia_maxima = 200;

//Variaveis para armazenar o tempo
unsigned long tempoTotal = 0;
unsigned long tempoAnt = 0;
unsigned long tempoAtual = 0;
unsigned long tempoSeg = 0;
unsigned long tempoMin = 0;
unsigned long tempoInicial;
int diferenca = 0;

//Numero de voltas completadas
int voltas = 0;

//Inicializa o sensor ultrasonico e LCD nos pinos especificados
Ultrasonic ultrasonic(PINO_TRG, PINO_ECHO);
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

void IniciaLCD() {
  lcd.begin(16, 2);
  lcd.clear();
  lcd.home();
  lcd.print("TV=");
  lcd.setCursor(4, 0);
  lcd.print(":");
  lcd.setCursor(8, 0);
  lcd.print("TT=");
  lcd.setCursor(13, 0);
  lcd.print(":");
  lcd.setCursor(0, 1);
  lcd.print("NV=");
  lcd.setCursor(6, 1);
  lcd.print("Dif=");
  lcd.setCursor(14, 1);
  lcd.print("s");
}

void AtualizaLCD() {
  // Escreve tempo de volta
  lcd.setCursor(3, 0);
  lcd.print((int)tempoMin);
  lcd.setCursor(5, 0);
  if (((int)tempoSeg % 60) < 10) {
    lcd.print('0');
    lcd.print((int)tempoSeg % 60);
  }
  else lcd.print((int)tempoSeg % 60);

  // Escreve tempo total
  unsigned long TT = 0.001 * (tempoTotal - tempoInicial);
  lcd.setCursor(11, 0);
  if (((int)TT / 60) < 10) {
    lcd.print('0');
    lcd.print((int)TT / 60);
  }
  else lcd.print((int)TT / 60);
  lcd.setCursor(14, 0);
  if (((int)TT % 60) < 10) {
    lcd.print('0');
    lcd.print((int)TT % 60);
  }
  else lcd.print((int)TT % 60);

  // Escreve número de voltas
  lcd.setCursor(0, 1);
  lcd.print("NV=");
  lcd.setCursor(3, 1);
  lcd.print(voltas);

  // Escreve diferença de tempo
  int dif = abs((int)diferenca);
  lcd.setCursor(10, 1);
  if (diferenca >= 0.0)
    lcd.print('+');
  else lcd.print('-');
  if (dif < 10) {
    lcd.print('0');
    lcd.print('0');
    lcd.print(dif);
  }
  else if (dif < 100) {
    lcd.print('0');
    lcd.print(dif);
  }
  else lcd.print(dif);
}

void setup() {
  //Inicializa a serial
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.home();
  lcd.setCursor(4, 0);
  lcd.print("Contador");
  lcd.setCursor(1, 1);
  lcd.print("tempo de volta");
  pinMode(pino_pushbutton, INPUT);
  pinMode(LEDVM, OUTPUT);
  pinMode(LEDVD, OUTPUT);
}

void loop() {
  // Inicia Leds de alerta desligados
  digitalWrite(LEDVM, LOW);
  digitalWrite(LEDVD, LOW);

  while (digitalRead(pino_pushbutton) == 0); // Aguarda botão ser pressionado
  IniciaLCD();
  tempoTotal = millis();
  tempoAnt = tempoTotal;
  tempoInicial = tempoTotal;
  int aux; // Variável auxiliar

  while (voltas < NVOLTAS) {

    tempoTotal = millis();//Guarda o tempo total contado pelo arduino em milissegundos

    //Le os valores do sensor ultrasonico
    microsec = ultrasonic.timing();

    //Converte o tempo retornado pelo sensor na distância identificada em cm
    cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);

    if (cmMsec > distancia_minima && cmMsec < distancia_maxima) {

      //Para se obter o tempo da ultima volta em minutos
      tempoAtual = tempoTotal - tempoAnt;

      tempoAnt = tempoTotal;

      tempoSeg = (0.001) * tempoAtual;//conversao do tempo atual para segundos

      tempoMin = (tempoSeg / 60.0); //conversao do tempo atual para minutos

      //Numero de voltas
      voltas++;

      //Diferenca de tempo entre a volta executada e ideal
      diferenca = tempoSeg - IDEAL;

      //Verificar se o tempo está com desvio de +-10% do ideal
      if (tempoSeg > IDEAL * 1.1) {
        // Acende led alerta velocidade baixa
        digitalWrite(LEDVD, LOW);
        digitalWrite(LEDVM, HIGH);
      }
      else digitalWrite(LEDVM, LOW);
      if (tempoSeg < IDEAL * 0.9) {
        // Acende led alerta velocidade alta
        digitalWrite(LEDVD, HIGH);
        digitalWrite(LEDVM, LOW);
      }
      else digitalWrite(LEDVD, LOW);

      // Espera 5 seg após passagem pela chegada enquanto atualiza display
      if (voltas < NVOLTAS) {
        for (aux = 0; aux < 10; aux++) {
          delay(500);
          tempoTotal = millis();
          AtualizaLCD();
        }
      }
    }
    AtualizaLCD();
  }
  while (!digitalRead(pino_pushbutton));
  voltas = 0;
  tempoSeg = 0;
  tempoMin = 0;
  diferenca = 0;
  lcd.clear();
  lcd.print("Aperte o botao");
  lcd.setCursor(0, 1);
  lcd.print("p/ nova contagem");
  delay(800);
}

Colocando para funcionar

Veja como ficou o resultado final:

Testando o código

 

Testando o código

Entendendo a fundo

Software

– Função LiquidCrystal()

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

Esta função cria um objeto do tipo LiquidCrystal. Para o projeto em questão, os parâmetros da função são os pinos do arduino para: RS, Enable, B4, B5, B6, B7. Você pode verificar as outras três maneiras de declarar esta função no site:

https://www.arduino.cc/en/Reference/LiquidCrystalConstructor

– Função lcd.begin()

lcd.begin(16, 2);

Função responsável por inicializar a interface com o LCD e deve ser chamada antes de qualquer outro comando da biblioteca. Os parâmetros são o número de colunas e linhas do display.

– Função lcd.print()

lcd.print("TV=");

Esta função escreve o conteúdo na tela do LCD, na posição atual do cursor.

– Função lcd.setCursor()

lcd.setCursor(4, 0);

Função que posiciona o cursor do LCD na posição desejada na tela, onde o texto será escrito. Os parâmetros são as coordenadas referentes a coluna e a linha desejadas.

– Função Ultrasonic()

Ultrasonic ultrasonic(PINO_TRG, PINO_ECHO);

Esta função cria um objeto do tipo Ultrasonic. Os parâmetros da função são, em sequência, os pinos do arduino conectados ao Trigger e ao Echo do sensor.

– Função ultrasonic.timing()

microsec = ultrasonic.timing();

Esta função retorna o tempo de retorno do pulso emitido pelo sensor.

– Função ultrasonic.convert()

cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);

Função que converte o tempo retornado pelo sensor na distância identificada em cm.

– Função millis()

tempoTotal = millis();

Esta função retorna o tempo em milissegundos desde quando o arduino começou a executar o programa.

Fechamento

Com este tutorial aprendemos a desenvolver um dispositivo muito útil na avaliação do movimento de objetos, com diversas aplicações práticas. Espero que tenham gostado do conteúdo e não se esqueçam de deixar suas dúvidas, sugestões, críticas ou elogios nos comentários abaixo.