Making F1 lap timer

Hello, I want to make a circuit where there are two USdistance sensors that are right next to each other, and when the car pass through the first one a green light goes on and makes the timer start, but the second one will not start until the car passes it again. Then a red light will go on and make the timer stop

Welcome to the forum

Where are you stuck ?
What electronics and programming experience do you have ?

I’m like intermediate, I know how to use the basic led, if, lcd, ultrasensors
When green light on-timer on lcd starts
When red light on-timer stops
When the first ultrasensor senses below 50cm it checks if the green light is on, if it isn’t it delays 5secs, then the second ultrasensor senses below 50cm and puts green light on,
Then when the car finishes a lap, if the first ultrasensor senses below 50cm it checks if green light is on and puts red light on

But the problem is the second ultrasensor would put the green light on again
And there’s a five second delay in the time that the lcd shows

That sounds like you have a sketch already. If so, please post it, using code tags when you do

I’m not understanding why the first sensor can’t start AND stop the lap timer…

int cm = 0;
int red = 2;
int green = 3;
int greenstat;

long readUltrasonicDistance(int triggerPin, int echoPin)
{
  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(triggerPin, OUTPUT);  // Clear the trigger
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(2);
  // Sets the trigger pin to HIGH state for 10 microseconds
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  pinMode(echoPin, INPUT);
  // Reads the echo pin, and returns the sound wave travel time in microseconds
  return pulseIn(echoPin, HIGH);
}

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  greenstat = digitalRead(green);
  // measure the ping time in cm
  cm = 0.01723 * readUltrasonicDistance(7, 7);
  // convert to inches by dividing by 2.54

  if(cm < 50){digitalWrite(green, HIGH); digitalWrite(red, LOW);
              delay(5000); 
               
              if(greenstat==HIGH){
                                  if(cm < 50){digitalWrite(red,HIGH); 
                          digitalWrite(green,LOW);} delay(2000);} 
              else{digitalWrite(green, HIGH);}}
  

  
}

I tried that but it didn’t work well at all, is there a way to do it?

In a word, yes…
Think it through, post your best try and we’ll look at it.

Snap the millis value when the race starts, ignore any triggers for a couple of seconds to avoid retriggering, then snap the finish event- subtract the two, and you have the lap time.

You can accumulate the race time over several laps, while displaying each individual lap.

Good practice for you. :grin:

yh, I did the code again, I added the start time and final time like you said with one sensor. I tried to change the code, so green light starts when sensor senses something, then 5secs delay(delay is accounted for by making LCD timer start at 5)(delay is to give object enough time to move away from the sensor). After delay timer starts in a 'while' loop. and if sensor senses something again within the loop it 'breaks' and the time taken is shown

#include <Adafruit_LiquidCrystal.h>
  int seconds = 5;

  int cm = 0;
  int green = 3;
  int greenstat;
  int start;
  int end;
  int time_taken;
  Adafruit_LiquidCrystal lcd_1(0);

  long readUltrasonicDistance(int triggerPin, int echoPin)
  {

    pinMode(green, OUTPUT);
    pinMode(triggerPin, OUTPUT);  // Clear the trigger
    digitalWrite(triggerPin, LOW);
    delayMicroseconds(2);
    // Sets the trigger pin to HIGH state for 10 microseconds
    digitalWrite(triggerPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(triggerPin, LOW);
    pinMode(echoPin, INPUT);
    // Reads the echo pin, and returns the sound wave travel time in microseconds
    return pulseIn(echoPin, HIGH);
  }

  void setup()
  {
    Serial.begin(9600);
    lcd_1.begin(16, 2);
     lcd_1.print("hello world");
  }

  void loop()
  {
    lcd_1.setCursor(0, 1);
    lcd_1.print(seconds);
    greenstat = digitalRead(green);
    // measure the ping time in cm
    cm = 0.01723 * readUltrasonicDistance(7, 7);
    // convert to inches by dividing by 2.54

    if(cm < 50){digitalWrite(green, HIGH); delay(5000);start = seconds;}


                while(greenstat==HIGH){
                                       delay(1000);
                                    seconds = seconds+1 ;
                                       lcd_1.setCursor(0, 1);
                                       lcd_1.print(seconds);
                  if(cm<50){digitalWrite(green, LOW); break;
                           }
                						}
                end = seconds;
                time_taken = end-start;
                lcd_1.setCursor(5, 1);
                lcd_1.print("=");lcd_1.setCursor(6, 1);
                lcd_1.print(time_taken);




               }
 

Please post the full revised sketch

the problem is that, the green light isn't going of the second time sensor senses object, so loop isn't breaking and time is going forever

i did

You did it just as I was posting my request to post the code

In your sketch you have this while loop

    while (greenstat == HIGH)
    {
        delay(1000);
        seconds = seconds + 1;
        lcd_1.setCursor(0, 1);
        lcd_1.print(seconds);
        if (cm < 50)
        {
            digitalWrite(green, LOW);
            break;
        }
    }

Neither greenstat or cm are changed in that loop so how will it ever end ?

like if the sensor senses it again, wouldn't it break. using the If statement? since it turns green light off

Where in the while look does the sensor read the distance and update the cm variable ?

ohhhhhh thank you
:grin:

like this?

while(greenstat==HIGH){
                  cm = 0.01723 * readUltrasonicDistance(7, 7);
                  if(cm<50){digitalWrite(green, LOW); break;}
                                       delay(1000);
                                    seconds = seconds+1 ;
                                       lcd_1.setCursor(0, 1);
                                       lcd_1.print(seconds);
                 

That looks better, even with your appalling code formatting. Please consider using Auto Format in the IDE before posting code. It makes it much easier to read. Please post your full revised sketch

Personally I would not use a while loop because it block program execution. Rather I would let the loop() function do what its name suggests, but maybe get this working first

There's still some errors but its progress, this is the tinkercad code and design

#include <Adafruit_LiquidCrystal.h>
  int seconds = 5;

  int cm = 0;
  int green = 3;
  int greenstat;
  int start;
  int end;
  int time_taken;
  Adafruit_LiquidCrystal lcd_1(0);

  long readUltrasonicDistance(int triggerPin, int echoPin)
  {

    pinMode(green, OUTPUT);
    pinMode(triggerPin, OUTPUT);  // Clear the trigger
    digitalWrite(triggerPin, LOW);
    delayMicroseconds(2);
    // Sets the trigger pin to HIGH state for 10 microseconds
    digitalWrite(triggerPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(triggerPin, LOW);
    pinMode(echoPin, INPUT);
    // Reads the echo pin, and returns the sound wave travel time in microseconds
    return pulseIn(echoPin, HIGH);
  }

  void setup()
  {
    Serial.begin(9600);
    lcd_1.begin(16, 2);
     lcd_1.print("hello world");
  }

  void loop()
  {
    lcd_1.setCursor(0, 1);
    lcd_1.print(seconds);
    greenstat = digitalRead(green);
    // measure the ping time in cm
    cm = 0.01723 * readUltrasonicDistance(7, 7);
    // convert to inches by dividing by 2.54

    if(cm < 50){digitalWrite(green, HIGH); delay(5000);start = seconds;}


                while(greenstat==HIGH){
                  cm = 0.01723 * readUltrasonicDistance(7, 7);
                  if(cm<50){digitalWrite(green, LOW); break;}
                                       delay(1000);
                                    seconds = seconds+1 ;
                                       lcd_1.setCursor(0, 1);
                                       lcd_1.print(seconds);
                 
                           
                						}
                end = seconds;
                time_taken = end-start;
                lcd_1.setCursor(5, 1);
                lcd_1.print("=");lcd_1.setCursor(6, 1);
                lcd_1.print(time_taken);
    




               }