Tecnosalva

Contador de vueltas con Arduino (Arduino Lap Counter)

Vota!

Durante los meses de confinamiento que tuvimos que cumplir los ciudadanos para evitar la propagación del coronavirus muchos fueron los hábitos que tuvimos de cambiar. Una de mis pasiones es el running, necesitaba hacer ejercicio durante esos meses, no tenía cinta de correr en casa, así que no tuve más remedio que improvisar un circuito en el garaje de casa.

Se me ocurrió entonces diseñar un circuito que me contara las vueltas (Arduino Lap Counter) , y me contabilizara los kilómetros recorridos, con avisador acústico de vuelta, kilómetro, incluso con avisador de vuelta rápida. 

El sensor de ultrasonidos HC-SR04 es el encargado de registrar el paso de vuelta, un pequeño módulo de buzzer pasivo es el encargado de emitir las señales acústicas y una pantalla LCD, muestra el resultado, dicho display es el shield KEYPAD, que es ideal pues incorpora incluso sus botones.

Este es el resultado del pequeño proyecto:

https://www.tecnosalva.com/wp-content/uploads/2020/05/IMG_0666.mov
https://www.tecnosalva.com/wp-content/uploads/2020/05/counter-lap2.m4v
#include <LiquidCrystal.h>


// Inicializamos la libnrería con los números de los pines
// El módulo Arduino LCD KeyPad Shiel


LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int trigPin = 3;   // Elegimos el pin 3 para Trig
int echoPin = 11;  // Elegimos el pin 11 para Echo
int buzzer = A1;  //Pin A1 para usar el buzzer


// Variables que utilizaremos

float duracion; 
int distancia;
int vueltas = 0;
float km=0;

unsigned long lapMillis = 0;
unsigned long startMillis = millis();
unsigned long bestMillis = 9999999;
float lapTime = 0.00;
float bestLap = 0.00;
boolean firstLap = true;
boolean newBest = false;


//Varables para leer las teclas y el ADC
int lcd_key     = 0;
int adc_key_in  = 0;

//Contantes para identificar las teclas
#define btnDERECHA      0
#define btnARRIBA      1
#define btnABAJO       2
#define btnIZQUIERDA   3
#define btnSELECT      4
#define btnNADA        5


//función que lee la pusación de teclas del KeyPad Shield

int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // Leer la entrada analógica

 //Las teclas se conectan a un divisor resistivo que produce distintos valores de tensión según la tecla pulsada
 
 if (adc_key_in > 1000) return btnNADA; //Si no hay ninguna tecla pulsada, sale para demorar menos tiempo

 if (adc_key_in < 50)   return btnDERECHA;  
 if (adc_key_in < 195)  return btnARRIBA; 
 if (adc_key_in < 380)  return btnABAJO; 
 if (adc_key_in < 555)  return btnIZQUIERDA; 
 if (adc_key_in < 790)  return btnSELECT;   

 return btnNADA;  // No debería llegar aquí, pero por las dudas retorna este valor.
}


void setup() {

Serial.begin(9600);
pinMode(trigPin, OUTPUT);  //Definimos inputs y outputs
pinMode(echoPin, INPUT);

pinMode(buzzer,OUTPUT);
digitalWrite(buzzer, LOW);

lcd.begin(16, 2);// definimos número de columnas y filas del LCD

lcd.clear();  //borramos pantalla
lcd.setCursor(0,0);
lcd.print("Comienza el");
lcd.setCursor(0,1);
lcd.print("entreno");

// Ponemos en pantalla lo que se verá durante la ejecución del scketch
//  lcd.setCursor(0,0);
//  lcd.print("Vueltas:");
//  lcd.setCursor(10,0);
//  lcd.print("0");
//  lcd.setCursor(0,1);
//  lcd.print("Kms:");
//  lcd.setCursor(10,2);
//  lcd.print("0");
}

void loop() {

//Descomentar código para hacer funcionar el sensor SR04 sin necesiad de usar librería
delay (50);
    
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
delayMicroseconds(15);

duracion = pulseIn(echoPin, HIGH);
distancia = (duracion/2)/29.2;

//por si se engancha el SR04, que es frecuente que falle

if (distancia == 0 && digitalRead(echoPin) == LOW) {
    pinMode(echoPin, OUTPUT);
    digitalWrite(echoPin, LOW);
    delay(100);
    pinMode(echoPin, INPUT);   
  }



 if (distancia <= 50 && distancia >= 1)
      {
//valor del tiempo de vuelta en milisegundos
    lapMillis = millis() - startMillis;
    startMillis = millis();

// pasamos el tiempo de vuelta a segundos
    lapTime = lapMillis / 1000.00;

    //nuestra primera vuelta
    if (firstLap == true)
    {
       vueltas=0;
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("FIRST LAP!!!");
       
    }

    //resto de vueltas
    if (firstLap != true)
    {
     vueltas++;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Vueltas:");
         lcd.setCursor(10,0);
        lcd.print(vueltas);
        km=(vueltas*29.1)/1000;
        lcd.setCursor(0,1);
        lcd.print("Kms:");
        lcd.setCursor(10,1);
        lcd.print(km);
      
      Serial.print("lapTime: ");
      Serial.println(lapTime);
      Serial.print("lapMillis: ");
      Serial.println(lapMillis);

//Señal acústica cada Km recorrido
if ((vueltas % 35)==0){
  tone(buzzer, 600); // tone (BUZZER PIN, FREQUENCY);
  delay (150);  // DURATION OF THE TONE
  tone(buzzer, 294); 
  delay (200);  
  tone(buzzer, 494); 
  delay (400);  
  noTone(buzzer);
      
  }
    }

    //comprobamos si el tiempod e vuelta es el más rápido
    if (lapMillis < bestMillis && firstLap != true)
    {
      bestMillis = lapMillis;
      bestLap = lapTime;
      Serial.print("bestLap: ");
      Serial.println(bestLap);
      newBest = true;
    }

    //damos tono paso de vuelta
    if (newBest == true)
    {
    tone(buzzer, 700);
      delay(100);
      noTone(buzzer);
      newBest = false;
      delay (500);
    }
     //damos tono paso de vuelta más rápida
    else
    {
      tone(buzzer, 200);
      delay(100);
      noTone(buzzer);
      delay(500);
    }

    firstLap = false;
    Serial.println("----------------");
  
      }
   
lcd_key = read_LCD_buttons();  // Lee las teclas

 switch (lcd_key)               // Imprime un texto según el valor de la tecla detectada
 {
   case btnDERECHA:
     {
     break;
     }
   case btnIZQUIERDA:
     {
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("VUELTA + RAPIDA");
     lcd.setCursor(0,1);
     lcd.print(bestLap);
     lcd.setCursor(7,1);
     lcd.print("segundos");
     break;
     }
   case btnARRIBA:
     {
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("KILOMETROS  ");
     lcd.setCursor(0,1);
     lcd.print(km);
     break;
     }
   case btnABAJO:
     {
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("VUELTAS   ");
     lcd.setCursor(0,1);
     lcd.print(vueltas);
     break;
     }
   case btnSELECT:
     {
     lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Vueltas:");
      lcd.setCursor(10,0);
      lcd.print(vueltas);
      lcd.setCursor(0,1);
      lcd.print("Kms:");
      lcd.setCursor(10,2);
      lcd.print(km);
     break;
     }
     case btnNADA:
     {
     break;
     }
 }
}

Archivos adjuntos

Salir de la versión móvil