Break beam timer

Hello,

I finally hooked up a break beam timer system where a toy car rolls by a start and finish line and a time is given. It is all going well and I am just printing on the serial monitor right now.

Unfortunately, it is printing multiple values (if the car is moving slowly and staying in the second beam). How can I end the code so that it only prints 1 value. Attached is the code.

// Define pin numbers
const int irDetectorPin1 = A0;   // Analog pin connected to the IR Detector (Receiver)
const int irDetectorPin2 = A1;

unsigned long timeFirst1; //first beam lane 1 speed trap beam
unsigned long timeSecond1; //finish line lane 1

float TotalT = 0;


void setup() {
  Serial.begin(9600);   // Initialize serial communication
}

void loop() {
  int sensorValue1 = analogRead(irDetectorPin1);  // Read the analog value from the IR Detector pin


  
  // Map the analog value to a detection status


delay (1);
///////
if(sensorValue1 < 100) 
{
timeFirst1 = millis(); //First sensor trigged start time
}


  int sensorValue2 = analogRead(irDetectorPin2);  // Read the analog value from the IR Detector pin 2

// wait/check for the Finish Line sensors to be triggered
if(sensorValue2 < 100 && timeFirst1 > 0)
{
timeSecond1 = millis();
TotalT = timeSecond1 - timeFirst1;


Serial.print (TotalT);
}


}

Thank you

I made some changes to your code.
See if it works as you need.

If it works, try to understand my modifications.

// Define pin numbers
const int irDetectorPin1 = A0;   // Analog pin connected to the IR Detector (Receiver)
const int irDetectorPin2 = A1;
unsigned long timeFirst1; //first beam lane 1 speed trap beam
unsigned long timeSecond1; //finish line lane 1
float TotalT = 0;
int sensorValue1;
int sensorValue2;
bool flagSensor1 = false;
bool flagSensor2 = false;
//------------------------------------------------------------------
void setup() {
  Serial.begin(9600);   // Initialize serial communication
}
//------------------------------------------------------------------
void loop() {
  sensorValue1 = analogRead(irDetectorPin1);  // Read the analog value from the IR Detector pin
  // Map the analog value to a detection status
  delay (1);
  ///////
  if (flagSensor1 == false) {
    if (sensorValue1 < 100) {
      timeFirst1 = millis(); //First sensor trigged start time
      flagSensor1 = true;
    }
  }
  sensorValue2 = analogRead(irDetectorPin2);  // Read the analog value from the IR Detector pin 2
  // wait/check for the Finish Line sensors to be triggered

  if (flagSensor2 == false) {
    if (sensorValue2 < 100 && timeFirst1 > 0) {
      timeSecond1 = millis();
      TotalT = timeSecond1 - timeFirst1;
      Serial.print (TotalT);
      flagSensor2 = true;
    }
  }
}

@ruilviana I tossed your sketch into the wokwi.

Nothing resets the flag sensor bools.

I haven't time to try to fix, nor even be sure, but it functions correctly, or should I say prints a good result time, just once per board reset.

a7

1 Like

OK, at the bottom of the loop


  if (flagSensor1 && flagSensor2) {
    Serial.println("\nGo Again!");

    flagSensor1 = false;
    flagSensor2 = false;

    timeFirst1 = 0;
  }
}

Just in time - she who must not be kept waiting is seconds out.

a7

Ok that works great to produce just 1 value. However, the board sensor doesn't ever reset so i cannot repeat it without power the board down and then back on.

How could I display the value for lets say 2 seconds and then reset the board to read another again?

Thank you

If it works, try to understand my modifications.

I got a few minutes to agree! Reading code is the best. @ruilviana's code was easy to read and understand.

Here's an alternate based on the same structure and logic: see a beam get broken, note the time, see the other beam, print the elapsed time, rinse and repeat.

I hope as easy to read and glean some things from which:

const int irDetectorPin1 = A0;   // Analog pins connected to the IR Detector (Receiver)
const int irDetectorPin2 = A1;

unsigned long timeFirst1;   //first beam lane 1 speed trap beam
unsigned long timeSecond1;  //finish line lane 1

void setup() {
  Serial.begin(115200);   // Initialize serial communication
}

void loop() {
  static bool inTiming;
  bool sensorValue1 = analogRead(irDetectorPin1) < 100;  // true = broken beam
  bool sensorValue2 = analogRead(irDetectorPin2) < 100;

  unsigned long now = millis();

// see if it is time to start
  if (sensorValue1) {
    if (!inTiming) {
      timeFirst1 = millis(); // start time
      inTiming = true;
    }
  }

// check for the Finish Line sensors to be triggered
  if (inTiming) {
    if (sensorValue2) {
      timeSecond1 = millis();
      float TotalT = timeSecond1 - timeFirst1; // elapsed time
      Serial.print (TotalT);

      inTiming = false;
      Serial.println("\nGo Again!");
    }
  }
}

a7

added this to the bottom and it seems to be working. Thank you very much.

On another note, I was only able to do this with analog. Is there a way I can do the exact same thing but trigger the timer with any sort of break of the beam (aka high or low)?

Thank you

Yes. Both sketches read an analog port, and develop variously a logic value based on comparison to a threshold.

Since digitalRead() provides a logic value directly, it can be used in place of those expressions.

a7