measuring a delay

I am having a little problem with measuring the delay between two sensors.

So I have two sensors and about 2cm distance between them. When someone walks past the sensors one is activated a little sooner (probably miliseconds). I need to know which of the sensors was activated before the other. So what can I do? Probably use millis function and get the time of the activation and then compare it? That would probably be the logical step but I have a feeling that this wont work for some reason ::).

UNTESTED CODE

#define SENSOR1 10
#define SENSOR2 11

#define SENSOR_TRIGGER LOW

#define TIMEOUT 1000 //if a second has passed, stop looking for delay

unsigned long triggerTime = 0;
unsigned int sensorDelay = 0;

void setup(){
pinMode(SENSOR1,INPUT);
pinMode(SENSOR2,INPUT);
}

void loop(){
if (sensorDelay==0){ setTimeBetweenTriggers( SENSOR1 , SENSOR2 ); }
if (sensorDelay==0){ setTimeBetweenTriggers( SENSOR2 , SENSOR1 ); }
//do stuff with the reading
}

void setTimeBetweenTriggers( byte sensorPin1 , byte sensorPin2 ){
if ( digitalRead(sensorPin) == SENSOR_TRIGGER ){
triggerTime = millis();
while ( triggerTime+TIMEOUT > millis() ){
if( digitalRead(sensorPin2) == SENSOR_TRIGGER ){
sensorDelay = millis() - triggerTime;
}
}
}else{
sensorDelay=0;
}
}

Also untested code:

#define SENSOR1 10
#define SENSOR2 11

#define SENSOR_TRIGGER LOW

#define TIMEOUT 1000 //if a second has passed, stop looking for delay

unsigned long sensor1Time = 0;
unsigned int sensor2Time = 0;

void setup(){
 pinMode(SENSOR1,INPUT);
 pinMode(SENSOR2,INPUT);
 Serial.begin(9600);
}
 
void loop(){
  if( digitalRead(SENSOR1) == SENSOR_TRIGGER )
      sensor1Time = millis();
  if( digitalRead(SENSOR2) == SENSOR_TRIGGER )
      sensor2Time = millis();      
  if( sensor1Time > sensor2Time && sensor2Time > 0){
      Serial.print("sensor 2 triggerd first, time is: ");
      Serial.print( sensor1Time -  sensor2Time);
       sensor1Time =  sensor2Time = 0;
  }
  if( sensor2Time > sensor1Time && sensor1Time > 0){
      Serial.print("sensor 1 triggerd first, time is: ");
      Serial.print( sensor2Time -  sensor1Time);
       sensor1Time =  sensor2Time = 0;
  }
  if( (millis() > sensor1Time + TIMEOUT) || (millis() > sensor1Time + TIMEOUT) ){
    sensor1Time = sensor2Time = 0;
  } 
}

mem: Your code doesn't work. It works for first or second sensor - only one direction. If I change pins it works in different direction. And it works for first if it has been triggered first...

@AlphaBeta: I don't know how your code works. ;D

I do not even know if it works :-[

But as far as I can tell this should print to console the length of a detected delay.

#define SENSOR1 10
#define SENSOR2 11

#define SENSOR_TRIGGER LOW

#define TIMEOUT 1000 //if a second has passed, stop looking for delay

unsigned long triggerTime = 0;
unsigned int sensorDelay = 0;

void setup(){
pinMode(SENSOR1,INPUT);
pinMode(SENSOR2,INPUT);
Serial.begin(9600);
}

void loop(){
if (sensorDelay==0){ setTimeBetweenTriggers( SENSOR1 , SENSOR2 ); }
if (sensorDelay==0){ setTimeBetweenTriggers( SENSOR2 , SENSOR1 ); }
//do stuff with the reading
if(sensorDelay!=0){
Serial.print("Sensory delay ");
Serial.println(sensorDelay);
}
}

void setTimeBetweenTriggers( byte sensorPin1 , byte sensorPin2 ){
if ( digitalRead(sensorPin) == SENSOR_TRIGGER ){
triggerTime = millis();
while ( triggerTime+TIMEOUT > millis() ){
if( digitalRead(sensorPin2) == SENSOR_TRIGGER ){
sensorDelay = millis() - triggerTime;
}
}
}else{
sensorDelay=0;
}
}

Aaa! I figured out what your code does. It prints the delay between sensor activations. It is realy not what I want - i just need to know which of sensors was triggered first. But English is not my primary language so I have little problems telling people what I want. ;D

roli, do you want help getting the code to work? If so, look at the serial output and see if you can see what is not working. Feel free to add more print statements to see how the variables change when the sensors are triggered. If you get stuck, post the serial output along with a description of how the sensors were triggered.

i just need to know which of sensors was triggered first.

Maybe it could be done this way: [pseudocode]
if a sensorpin is high && its been some time since last reading
set that pin as first sensor
log time

I just added a piece of code that prints which sensor was activated (I put it where the time of sensor trigger is recorded) and found out that the thing records the time many times but prints which was activated first only once or it doesn't print that at all. So for one pass sensor gets activated (and time recorded) many times. So I added delay of 10 and wawed in one direction and in second direction and this is the result:

Sensor 1 active

Sensor 2 active

sensor 1 triggerd first, time is: 72

Sensor 2 active

Sensor 2 active

Something is wrong here. They work normaly with LEDs (I created little code that blinks when sensor is activaed). If I wawe the LEDs blink just once and in right order. But they don't here.

What are you using as sensors, I wonder if you are getting bounce.
There are many articles on dealing with switch bounce including this one:Arduino Playground - SoftwareDebounce

I am using IR sensors (one side has IR emmiter and IR reciever, and second one has the same). IR reciever sees IR diode from one side and the same for the other side. Sensor gets HIGH when the IR diode isn't in range. If I plug them into the analog port I get a value to about 120 when the sensor isn't triggered and about a 500 when it is. So it is possible that the sensor doesn't go well with digital in?

So it is possible that the sensor doesn't go well with digital in?

That is quite possible. A 500 count analog reading converts to about 2.4vdc, which is not a valid digital high voltage value. Can you supply a drawing on how you are wiring the emitters and receivers and can you give the device part numbers to see if data sheets can be located.

Lefty

I just tryed it again with analog input - I was correct when it is HIGH it is around 500 (most of the time) but it can go up to 700 max.

The whole sensor design is originaly from Grumpy_Mike that gave me link to the sensor in this topic:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236816264
But I modified it a little. Here is actual schematic:

The transistors used are: BC547B (don't know who made them)
And the photodiode is (in the schematic it is shown as normal diode): Vishay BPV10NF

EDIT: tryed with analog in and value of 250 for trigger. And I have no idea why it is not working:

Sensor 1 activated

Sensor 1 activated

Sensor 2 activated

sensor 1 triggerd first, time is: 46

Sensor 2 activated

Sensor 2 activated

Sensor 1 activated

Why the hell doesn't it say that sensor 2 was triggered first? The output is the same.

I tested the code and the timeout logic may have been a problem. I modified the timeout check and it tests ok for me using switches as sensors (it bounces a little but the logic works)

#define SENSOR1 10
#define SENSOR2 11

#define SENSOR_TRIGGER LOW

#define TIMEOUT 1000 //stop looking for delay after this many ms

unsigned long sensor1Time = 0;
unsigned long sensor2Time = 0; // this should be an unsigned long
unsigned long timeout;

void setup(){
 pinMode(SENSOR1,INPUT);
 pinMode(SENSOR2,INPUT);
 Serial.begin(9600);
}

void loop(){
  if( digitalRead(SENSOR1) == SENSOR_TRIGGER ){
       sensor1Time = millis();
       timeout = sensor1Time+ TIMEOUT; 
  }
  if( digitalRead(SENSOR2) == SENSOR_TRIGGER ){
        sensor2Time = millis();
        timeout = sensor2Time + TIMEOUT;
  }
  if( sensor1Time > sensor2Time && sensor2Time > 0){
      Serial.print("sensor 2 triggerd first, time is: ");
      Serial.println( sensor1Time -  sensor2Time);
       sensor1Time =  sensor2Time = 0;
  }
  if( sensor2Time > sensor1Time && sensor1Time > 0){
      Serial.print("sensor 1 triggerd first, time is: ");
      Serial.println( sensor2Time -  sensor1Time);
       sensor1Time =  sensor2Time = 0;
  }
  if( (millis() > timeout)  && ( sensor1Time || sensor2Time) ){
    sensor1Time = sensor2Time = 0;
  }
}

the output was:
sensor 2 triggerd first, time is: 97
sensor 1 triggerd first, time is: 235
sensor 1 triggerd first, time is: 273
sensor 2 triggerd first, time is: 449

Great! It works perfectly!

EDIT: It works with fast movement but if you move a little slower it duplicates the result. Problem is that I can't have duplicated results because this is acualy some kind of a counter.

I'm not positive but it seems to me that in your drawing the cathode of the photodiode should be wired to +5vdc instead of wiring to the analog input pin. ?

Lefty

it works with fast movement but if you move a little slower it duplicates the result

how slow? Do you need to increase the timeout period?

A little slower - I think still less than 1 second. But I did increase the timeout to 2 seconds just to be sure. But it didn't help.

I'm not positive but it seems to me that in your drawing the cathode of the photodiode should be wired to +5vdc instead of wiring to the analog input pin. ?

That way I get a nice little warning from my mac - "USB overcurrent notice....".

I edited the code, Sensor2Time wants to be an unsigned long, try it with that change.

with the timeout set to 3000 i got these readings when triggering slowly:

sensor 2 triggerd first, time is: 1205
sensor 1 triggerd first, time is: 2393
sensor 2 triggerd first, time is: 1368
sensor 1 triggerd first, time is: 1631
sensor 2 triggerd first, time is: 1364

Better! But I still get a random reading sometimes. Strange is that then the time is reset back to 1...5 when that happens.