Laser Speed Calculation/millis() Help

I am working on a project trying to put together a laser speed trap, but with a deadline coming up and one of my 2 photo-resistors broken, I had to resort to making a laser pathway using a mirror in order to simulate 2 points of breaking the line of sight. For the life of me, I can't seem to get the code worked out, as the blue LED is constantly on, the red never turns on, neither alternate like I specified, and the calculations involving millis() provide really strange answers, all of which are a composition of ones and zeros, usually around 10 or so of them. I attempted to put in some place markers to get some output on the individual times too, but they also turn out just as weird. I've spent the last 2 days stumped. I haven't even attached the LCD display yet because the basis for its output isn't correct yet. Here is the entire code:

  #include <LiquidCrystal.h>
  #include <SoftwareSerial.h>

  int red = 8, blue = 12, green = 13, yellow = 7, photo = 0, toggle = 4;
  const double distance = 6, limit = 12, threshold = 270;
  bool reset;
  unsigned long time1 = 0, time2 = 0, timetotal;
  float velocity;
  LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  pinMode(red, OUTPUT);
  pinMode(blue, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(photo, INPUT);
  pinMode(toggle, INPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
}

void loop()
{
  
   velocity = 0;
   time1 = 0;
   time2 = 0;
   timetotal = 0;
   digitalWrite(red, LOW);
   digitalWrite(blue, LOW);
   digitalWrite(green, LOW);
   digitalWrite(yellow, LOW);
   reset = false;

   lcd.print(0, 2);
    
   while ( (analogRead(photo) <= threshold) && (reset == false) )
   {
     digitalWrite(yellow, HIGH);
     Serial.println("step1");
        
     while ( (digitalRead(yellow) == HIGH) && (digitalRead(toggle) == HIGH) )
     {   
       Serial.println("step2");
       while ( (analogRead(photo) > threshold) && (reset == false) )
       {
         Serial.println("step3");
         if (time1 == 0)
         {
           time1 = millis();
         }
          
         while ( (analogRead(photo) <= threshold) && (reset == false) )
         {
           Serial.println("step4");
           if (analogRead(photo) > threshold)
           {
             Serial.println("step5");
             time2 = millis();
             timetotal = time2 - time1;
             velocity = distance/timetotal;
             lcd.print(velocity, 2);
             Serial.println(time1, 2);
             Serial.println(time2, 2);
             Serial.println(velocity, 2);
              
             if (velocity > limit)
             {
               while (digitalRead(toggle) == HIGH)
               {
                 digitalWrite(red, HIGH);
                 digitalWrite(blue, LOW);
                 delay(50);
                 digitalWrite(red, LOW);
                 digitalWrite(blue, HIGH);
                 delay(50);
               }
             }
             else
             {
               digitalWrite(green, HIGH);
             }
              
             reset = true;
           }
         }
       }
     }
   }
}

I tested to see if millis() itself was off by using a very basic test code to get millis(), delay for 1 second, then get millis() again and subtract for elapsed time, which worked fine, always 999 or 1000 milliseconds, on the dot. The next step I took was removing all the fluff and testing a circuit and code that only has 1 LED indicator to show the laser is properly positioned onto it. The rest is just pure stages for if statements, yet it still pulls random assortments of ones and zeros for the 2 time values, and the speed calculation comes out just as weird. The code for that circuit is here:

 #include <SoftwareSerial.h>

  int yellow = 7, photo = 0, state = 0;
  const double distance = 6, threshold = 270;
  unsigned long time1 = 0, time2 = 0;
  float timetotal, velocity;

void setup()
{
  pinMode(yellow, OUTPUT);
  pinMode(photo, INPUT);
  Serial.begin(9600);
}

void loop()
{
   if (analogRead(photo) <= threshold)
   {
      digitalWrite(yellow, HIGH);
   }
   if (analogRead(photo) > threshold)
   {
      digitalWrite(yellow, LOW);
   }
   if (state == 0)
   {
      if (analogRead(photo) <= threshold)
      {
        time1 = millis();
        Serial.println(time1, 2);
        state = 1;
      }
   }
   else if (state == 1)
   {
      if (analogRead(photo) > threshold)
      {
        state = 2;
      }
   }
   else if (state == 2)
   {
      if (analogRead(photo) <= threshold)
      {
        time2 = millis();
        timetotal = time2 - time1;
        Serial.println(time2, 2);
        Serial.println(timetotal, 2);
        velocity = (distance/timetotal)/1000;
        Serial.println(velocity, 2);
        state = 0;
      }
   }
}

Any help would be greatly appreciated, at the very least on the front of getting the whole millis() situation sorted out, as that is supposed to be the main feature. The laser is fed by a pure power source, and not a pin, thus why it's not listed in the code.

So by changing the second code around a bit, I was finally able to get numbers, but I have no idea why they are showing up so oddly. How come only the first 2 numbers are perfect integers, when I have them set as unsigned long? The next two numbers are weird two, but that's because they are calculated using the previous 2 numbers. For reference, the first value is time1, second is time2, third is timetotal, and fourth is velocity. I'm confused as to why I'm getting perfect integers when I am using an analog input and swiping my hand across manually. The time measurements should be more exact, but I have no idea how to increase their accuracy for more solid results. Here is the new test code:

 #include <SoftwareSerial.h>

  int yellow = 7, photo = 0, state = 0;
  double distance = 15.24, threshold = 270;
  unsigned long time1 = 0, time2 = 0;
  float timetotal, velocity;

void setup()
{
  pinMode(yellow, OUTPUT);
  pinMode(photo, INPUT);
  Serial.begin(9600);
}

void loop()
{
   if (analogRead(photo) <= threshold)
   {
      digitalWrite(yellow, HIGH);
   }
   if (analogRead(photo) > threshold)
   {
      digitalWrite(yellow, LOW);
   }
   if (state == 0)
   {
      if (analogRead(photo) > threshold)
      {
        time1 = millis()/1000;
        Serial.println(time1);
        state = 1;
      }
   }
   else if (state == 1)
   {
      if (analogRead(photo) <= threshold)
      {
        state = 2;
      }
   }
   else if (state == 2)
   {
      if (analogRead(photo) > threshold)
      {
        time2 = millis()/1000;
        timetotal = time2 - time1;
        Serial.println(time2);
        Serial.println(timetotal);
        velocity = (distance/timetotal);
        Serial.println(velocity);
        state = 0;
        delay(1000);
      }
   }
}

And here are a few samples of output:

1
2
1.00
15.24

4
6
2.00
7.62

8
9
1.00
15.24

10
12
2.00
7.62

I forgot to mention earlier that the constant distance was 6 inches originally, but I changed it to 15.24 centimeters. Threshold was guesstimated through manual testing of the photo-resistor to get a value too high for ambient light to trigger but low enough for the laser.

You are reading one sensor for both times. Even if 16MHz isn't fast with todays standard, it is fast enough to read your sensor several times from only breaking the first laser beam.

You need to make sure photo resistor goes high after first reading before you read again.

Gabriel_swe:
You are reading one sensor for both times. Even if 16MHz isn't fast with todays standard, it is fast enough to read your sensor several times from only breaking the first laser beam.

You need to make sure photo resistor goes high after first reading before you read again.

I think the second code is beginning to work out. All of my LED displays are working correctly, and by utilizing states instead of all those if and while loops chained inside each other, it really cleaned up the results for the same reason you mentioned. I am still a little baffled with the numbers, as they are working now but still only giving integers for times. Regardless, it's close enough for now, all that's left is to find a way to integrate the LCD display into the code.