Contador de vueltas

Desde mi infancia soy aficionado a las carreras de coches y en particular los Scalextrics.

Mi primer proyecto era integrar Arduino en una pista para hacer competiciones entre los amigos.

Como podéis observar, en este proyecto he implementado con dos sensores de ultrasonido HC-SR04 los cuales nos mide las distancias a la velocidad del sonido.

Por este motivo, en el programa que os dejo podéis observar que cuando obtengo la distancia la divido entre 2 ya que este sensor mide la ida y la vuelta y este resultado lo divido entre 29,2 para pasar la distancia a centímetros.

Cuando lo tuve montado en un puente con piezas de mecano, tuve que ajustar la distancia deseada de los sensores, me explico: que solo contara una vuelta cuando la distancia entre el sensor y la pista es menor que la altura de amos. También observareis que cuando cuenta la vuelta no uso la sentencia delay(), sino que tengo unas variables “contol_e y control_i” que en el void loop{} la voy decrementando hasta llagar a 0 ya que si utilizamos la instrucción delay() nos pararía todo el circuito i si en aquel momento pasa el otro coche no sumaria la vuelta; y dentro de la función de contar las vuestras pongo un valor de 20 cuando pasa el coche.

Materiales:

Protoboard
Pulsador
Arduino UNO

Y juego de cables

LCD 20X4 con I2C
Módulo ultrasónico HC-SR04

Esquema de conexión:

Código fuente:

/*
 * Contador de vueltas Scalextric
 * Autor Josep Martínez Tejedor
 * Data inici projecte: 6-7-17
 * Data finalització projecte: 30-07-17
 */
// LCD
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
 
// Relotge
#include <Time.h>
#include <TimeLib.h>
 
// Variables del sensor exterior
#define trigpin_e 7
#define echopin_e 8
 
// Variables del sensor interior
#define trigpin_i 5
#define echopin_i 6
 
 
#define I2C_ADDR    0x27
LiquidCrystal_I2C             lcd(I2C_ADDR,2, 1, 0, 4, 5, 6, 7);
 
#define pulsador 4   // Definimos el puerto par el pulsador de reset
 
float duracio_i; 
float duracio_e;  
float distancia_i; 
float distancia_e;  
int volta_e = -1;
int volta_i = -1;
int control_i = 0;  // Son las dos variables que hacen un retardo antes de contar otra vuelta
int control_e = 0;
 
// Variables pulsador
int botocero = 0;  //Estado de la salida
int estatAC = 0;  // Estado actual
int estatAN = 0;  // Variable para guardar el estado anterior del pulsador
 
// Procedimiento de los sensores
void distancia()
{
    // Pista interior
  digitalWrite(trigpin_i, LOW);
  delayMicroseconds(2);
   
  digitalWrite(trigpin_i, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigpin_i, LOW);
 
  duracio_i = pulseIn(echopin_i, HIGH);
  distancia_i = (duracio_i/2)/29.2;
 
  
   
    lcd.setCursor(5,3);
  //  lcd.print(distancia_i);
  if (control_i == 0)
  {
    if (distancia_i <= 4 && distancia_i >= 0)
      {
        volta_i = volta_i + 1;
        lcd.setCursor(12,2);
        lcd.print(volta_i);
        control_i = 20;
      }
  }
  // Pista exterior
  digitalWrite(trigpin_e, LOW);
  delayMicroseconds(2);
   
  digitalWrite(trigpin_e, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigpin_e, LOW);
 
  duracio_e = pulseIn(echopin_e, HIGH);
  distancia_e = (duracio_e/2)/29.2;
 
    lcd.setCursor(12,3);
   // lcd.print(distancia_e);
  if (control_e == 0)
  {
    if (distancia_e <= 4 && distancia_e >= 0)
      {
        volta_e = volta_e + 1;
        lcd.setCursor(12,1);
        lcd.print(volta_e);
        control_e = 20;
      }
  }  
}
 
// Reloj
void relotge()
{
   // Imprimimos la hora
   lcd.setCursor(4,0);
   lcd.print("Hora: ");
   lcd.print(hour());
   lcd.print(":");
   lcd.print(minute());
 
}
 
 
void setup()
{
  //Serial.begin (9600);
 
  pinMode(trigpin_i, OUTPUT);
  pinMode(echopin_i, INPUT);
  pinMode(trigpin_e, OUTPUT);
  pinMode(echopin_e, INPUT);
  pinMode(pulsador, INPUT);
// Establecemos la hora y la fecha 
  setTime(12, 10, 0, 01, 01, 2017);
   
// Inicializar el display con 20 caraceres 4 lineas
  lcd.begin (20,4);    
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.clear();
  lcd.home ();
 
// Contador de vueltas inicial
  lcd.setCursor(0,1);
  lcd.print("Pista Ext.:");
  lcd.setCursor(0,2);
  lcd.print("Pista Int.:");
  lcd.setCursor(12,1);
  lcd.print("0");
  lcd.setCursor(12,2);
  lcd.print("0");
  
}
 
void loop()
{
  // Comprueva el estado del botón
  estatAC = digitalRead (pulsador);  // Actualizamos el valor de las variables
     lcd.setCursor(10,1);
      //   lcd.print(estatAC);
  if (estatAC && estatAN == 0)
  {
    botocero = 1 - botocero;
    volta_e = -1;
    volta_i = -1;
    lcd.setCursor(12,1);
    lcd.print("   ");
    lcd.setCursor(12,1);
    lcd.print("0");
    lcd.setCursor(12,2);
    lcd.print("   ");
    lcd.setCursor(12,2);
    lcd.print("0");
    control_i = 20;
    control_e = 20;
    delay(50);
  }
  estatAN = estatAC;
  relotge();
  distancia();
   
  if (control_i > 0)
  {
    control_i = control_i - 1;
  }
    if (control_e > 0)
  {
    control_e = control_e - 1;
  }
 
} 

Librerias: