Programing a "chronograph"

Hi there,

I hope this is the right section to post this question. I’m trying to assemble a chronograph with two lasers, and two LDR’s and my arduino.

The principle of function I would want is similar to this: The two lasers are pointing to the two LDR, giving them “light”. The two LDR’s are some distance apart from each other. When something passes through the first LDR (interrupting the light), micros() starts, then when laser two is interrupted, time is determined. This gives me the time variation. And with this time, I would like to calculate speed.

The problem is that I don’t know how to operate numbers on int with long, with float, etc.

The code I’ve think of was:

int LDR1 = 1;
int LDR2 = 2;
int LDR1val;
int LDR2val;
int v = 0;
int V = 0;
int t = 0;

int S = 1; //=>distance from LDR to LDR

unsigned long time;
unsigned long difference;

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

void loop(){
  LDR1val = analogRead(LDR1);
  LDR2val = analogRead(LDR2);

  if( (LDR2val < 500 ) && (LDR1val >= 500) ){

    difference = micros();
  }
  if( (LDR1val < 500) && (LDR2val >= 500) ){
    time = micros() - difference;
    
    t=time;
    Serial.print("t=");
    Serial.println(t, DEC);
   
    v=S/(t*10^(6)); //speed in m/s
    Serial.print(v, DEC);
    Serial.println(" m/s");
    V=(v*10^(-3))/(1/3600); //speed km/h
    Serial.print(V, DEC);
    Serial.println(" km/h");
    Serial.println("--------");
    delay(100);
}
}

I’m using LDR, because they’re the only sensors I have right now to fulfill my project (and I’m not expecting a extremely accurate value, for now), but when I put the code running right, I will try to find better light sensors.

Note: I’m new to programing (it’s not my area); I think I have to “link” the first if to the second one.
Sorry if it is confusing.

Thanks in advance for any help.

I think the code looks good. Make sure the 't' isn't more than 32,767. That's all an int can hold. Information on the data types is here: http://arduino.cc/en/Reference/HomePage

First of all, I think you should do some practice runs with certain assumptions to see whether your code is viable. Instead of reading values from sensors, just make assignment statements for the variables that represent start time and final time and go from there. Print out intermediate values of the results of your calculations and see if they agree with the values you expect from your input values. See footnote.

For example, your sensors are 1 meter apart. What velocities are you expecting to measure? A model car at 1 meter per second? (So it would be 1000000 microseconds from one sensor to the other? A (somewhat faster) model car at 10 meters/second? (So it would be 100000 microseconds from one sensor to the other? What? What if its velocity is 0.3 meters/second?

My recommendation is that you just plug in values for start and end time corresponding to the velocity that you expect to measure and see what your program will tell you.

Regardless of the logic involved in the calculations, here are a few glaring problems:

int v = 0; // NO!  it should be a floating point number, right?  you don't want to limit it to 1 or 2 or 3,...
int V = 0; // NO! It should be a floating point number.
int t = 0; // micros() returns an unsigned long integer.  The maximum value an int can hold is 32767.
           // An unsigned long can go up to 4294967295

Now, consider

int S = 1; //=>distance from LDR

Why not let it be a float? I mean an integer value of 1 will be represented exactly as a float, so it doesn't make much difference here, but eventually it will be a part of a floating point calculation, so... (And what if you decide to change the distance to 1.5 meters, for example?)

Finally, the following is just flat wrong:

    v=S/(t*10^(6)); //speed in m/s

No, no, no! If you want to multiply by 1000000, then you can multiply by 1000000.0, or by 1.0e6 In C and c++, the '^' operator is (integer) bit-by-bit exclusive-or. You want a floating point constant.

    V=(v*10^(-3))/(1/3600); //speed km/h

NO (again)! you can multiply by 0.001 or multiply by 1.0e-3 or divide by 1000.0 or divide by 1.0e3, but 10^(-3) does not compute!

Also, 1/3600 is integer division, so its value is zero. When doing floating point calculations I think you should get into the habit of writing all constants as floating point numbers. That way there will never be a question of integer division or integer overflow or other things that screw the pooch in evaluating floating point expressions. So: write (1.0/3600.0) instead of (1/3600)

Bottom line: As you run numbers through the program, think about how the actual numbers will be obtained from the sensor measurements. Then look at the logic that will trigger the calculations that you are performing. There is some head-scratching to do, but it won't mean a thing if the calculations are wrong.

Regards,

Dave Footnote: Before starting to write code, I think you should do some pencil-and-paper (gasp) calculations to see the sizes of the numbers that will be involved in your results. (I use the back of a cocktail napkin at my favorite watering hole for approximations, but a calculator is allowed if you really need it. The point is: Step away from the computer and think about the problem and its expected solution/numerical results.)

The following is just an opinion (my opinion). It's worth exactly what you want it to be worth:

[/begin Editorial Comment] I mean, just throwing some numbers at a program (let alone values obtained from physical measurements) without having some idea of the expected results (including sizes of all intermediate variables) is just plain silly (in my opinion). Always run a couple (or more) of test calculations to see what will be "reasonable" output values. After a dry run with pencil-and-paper, plug representative numbers into the calculations in the program itself before trying it with physical sensors. That's my recommendation. [/end Editorial Comment]

Thank you Big Oil :)

Dave, thank you very much for your opinion and help. I'm new to programing and I'm in the try/fail phase. I will follow your advices, starting with "processing" information on paper before moving to the physical material. I wanted to create a "speedometer" for a RC car (for studies of speed and behavior) that goes near 80 km/h or more. I think LDR's aren't that good for the purpose, but for a initial stage to understand the basics it'll do. The less distance between the LDRs, the better. And using float (as you've advised), I can manage to decrease distance, turning the measurements more accurate.

But first things first. I'll try to better understand programing. Plan; then move to the projects. Thanks again.

Best Regards, Luís