ISR's in photoswitch sensorgate's [RESTARTED]

Hi all,

for my project (dogsport timer) i'm trying to trap how long a passing dog interrupts a photoswitch sensorgate.

crossings & passings in our dogsport

as i'm fairly new to Arduino and C/C++, so i've made a little drawing about what my goal is to achieve.

we've got dogs running one after the other trough a sensorgate, where the "next" dog may not enter the lane before the "previous" dog has left the lane.

my goal is to "trap" the time a certain dog interrupts a photoswicht... my idea was that, maybe it's possible to use two of the provided methods in the interrupts on the arduino (AT Mega 2560 ADK) i use.

maybe i'm totally wrong on what is possible..i realy don't know that.

the idea is to try to write a routine that traps "millis()" on the rising edge of the curve (see attached picture) and also traps the "millis() on the falling edge of the curve... of the same sensor (and thus hardwired to the same arduino PIN)

just the millis() should do, because calculations and displaying would be done on another moment (when de controller has more time to do this sort of work).

I've read Nick Gammon's article about interrupts, but my knowledge for the moment is to small to get this thing to work on my own.

Anyone an idea if this is possible or not?

and above all, where should i start in programming such routine

as one can see in the video, in optimal conditions the time two dogs cross the sensor gate is about the lenght of one dog (in less accurate conditions, this could run up to x2 dogs lenght, without and state change in the lightbeam, in other conditions there maybe a small flat line in the signal before it goes up again...)

Grtz,
Yves

Anyone an idea if this is possible or not?

Sure it is. Set the interrupt to trigger on CHANGE. Then, in the ISR, determine of the change is to HIGH or is to LOW. Record the time in the appropriate variable depending on the cause of the interrupt.

Hi PaulS,

do you mean by the change method, that the "falling" edge and the "rising" edge is not possible to use in a routine?

I can be wrong (realy don't know that), but i thought that for my goal i would certainly be helped more with the edge detection, than with the change method, but of course that would mean to attatch 2 different routines to one interrupt...

i can have several more high and low signals coming realy fast one after another... would the "change" method be able to detect such high sequence of high's and low's after each other?

anyway thanks for the previous reply, that will help me anyway to try some things out...

Grtz,
Yves

Another option, if you can spare the pins, is to connect your sensor to Pin2 and Pin3 and set one interrupt for FALLING and the other for RISING.

...R

do you mean by the change method, that the "falling" edge and the "rising" edge is not possible to use in a routine?

You can use RISING as the type, if you are only interested in the rising edge.
You can use FALLING as the type, if you are only interested in the falling edge.
You can, as Robin2 suggests, use two interrupt pins and two interrupt handlers.
Or, you can use CHANGE as the type, and then determine for yourself, in the interrupt handler, whether it was triggered by a rising edge (since the pin is now HIGH) or be a falling edge (since the pin is now LOW).

Hi PaulS,

If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be ignored (turned off) until the current one is finished. as delay() and millis() both rely on interrupts, they will not work while an ISR is running.

Paul, will this mean I cannot use "millis()" in an interrupt routine, or does this just means all other calls to millis() will be ignored while in the ISR routine?

/*
I had something like this in mind...
*/

volatile long ISR_millis_High = 0;
volatile long ISR_millis_Low = 0;

byte PhotocelA = 2; // INT.0

void setup()
  {
     pinMode(PhotocelA, INPUT);
     attachInterrupt(0, ISR_TimeA, CHANGE);
     digitalWrite(PhotocelA,HIGH); // internal PULLUP active
   }

void loop()
{
do_something_with(ISR_millis_High);
do_something_with(ISR_millis_Low);

... rest of code

}

void ISR_TimeA()
  {
    if (digitalRead(PhotocelA) == HIGH)
       {
         ISR_millis_High = millis();
       } else {
         ISR_millis_Low = millis();
       }
  }

anyway, i would have to use 2X ISR's for my project (since two rows of 6 photosensors, 6inch apart).

but if i get one routine to work, i hope to get the second to work too.

Grtz,
Yves

Paul, will this mean I cannot use "millis()" in an interrupt routine, or does this just means all other calls to millis() will be ignored while in the ISR routine?

You can use millis() inside an ISR, it just won't increment. That doesn't matter if you are just recording the current time.

Calling millis() inside an ISR is very commonly done. Just as an example, a while back I wrote a sketch to time how long it takes a ball to pass a light on a ramp. Image the ball as a rather rotund dog, and you have the same general idea:

const byte LED = 12;
const byte photoTransistor = 2;

unsigned long startTime;
volatile unsigned long elapsedTime;
volatile boolean done;

void ballPasses ()
{
  // if low, ball is in front of light
  if (digitalRead (photoTransistor) == LOW)
    {
    startTime = micros (); 
    }
  else
    {
    elapsedTime = micros () - startTime;  
    done = true;
    }
    
  digitalWrite (LED, !digitalRead (LED));  
}


void setup ()
{
  Serial.begin (115200);
  Serial.println ("Timer sketch started.");  
  pinMode (LED, OUTPUT);
  attachInterrupt (0, ballPasses, CHANGE);
}

void loop ()
  {
  if (!done)
    return;
    
  Serial.print ("Time taken = ");
  Serial.print (elapsedTime);
  Serial.println (" uS");
  done = false;
  }

I used micros() rather than millis() for greater accuracy.

● You could "or" all the signals into one interrupt, then read the complete
PortA (D22-D29) into one byte in one read using direct port manipulation.
● Could use 2 arrays (PortA[6] and BeamDisruptMicros[6]).
● Then in each interrupt write to the next index of the arrays.
● In the main loop, it could easily be determined which sensor(s) triggered the interrupt.
● The RC time constant of the interupt's rising edge in this diagram is about 1µs.

EDIT: Please disregard ... not applicable

Hi guys,

i'll get back to this later, I just fried my first µCU :cry:

Thanks Nick & dlloyd (and the others too, of course) for the tips

@dlloyd :
my sensor gate consists of 2x 6 paralleled photosensors (to track dogs of different heights) => equivalent to 2x 1 photosensor 6inch apart from one another...

@Nick :
when my new toy has arrived, i'll certainly try out your sketch (even if it was to learn how to work with ISR's)

Grtz,
Yves

i'll get back to this later, I just fried my first µCU :cry:

Do you have the details of the sensors (model#/datasheet)?
Also do you have the desired or required connections / sample schematic / image(s) you could show us?

my sensor gate consists of 2x 6 paralleled photosensors (to track dogs of different heights) => equivalent to 2x 1 photosensor 6inch apart from one another...

I see.

Just some thoughts:

One port (byte) for upper sensors, a second port (byte) for lower sensors.

It would be possible to "OR" all 12 signals to one interrupt.

All the interrupt routine does is record the micros() timer and set a flag that an interrupt occurred.

The main loop detects the set flag and reads the byte(s) status. Nothing will be missed here because the turn-off time of the sensor(s) will take a while.

After the race, the timing will be known for every dog, even if they all break the beam at exactly the same time.

[u][color=navy]Interrupt routine[/color][/u]

Interrupt count: 5
Microseconds: 10231495

[u][color=navy]Main loop[/color][/u]

Lane:                 6   5   4   3   2   1
Upper Byte:   x   x   1   1   1   0   0   0
Lower Byte:   x   x   1   0   1   0   1   1

[u]Lane[/u]  [u]Status[/u]
1     small dog
2     small dog
3     lane clear
4     large dog
5     dog leaping / upper body
6     large dog

Hi dlloyd,

Do you have the details of the sensors (model#/datasheet)?
Also do you have the desired or required connections / sample schematic / image(s) you could show us?

i use these ones (NPN NO but a 5volt model - 3 wires)
connected to the ADK Mega 2560 to pins 21-22 (each time 6 sensors - paralleled)
on the pins 21-22
i've activated the internal pull-up resistor (because otherwise i did not have a reading - and due to this the signals goes from HIGH to LOW when the beam is broken by a dog ...
Photoswitch sensor

i've got a link of what the dogsport is about, if you look close to the video, one can see the two rows of 6 vertical sensors mounted on the standards in front of our coach. one must think of it as a 4x 100 meters run but then for 4 dogs (and only 45foot long)
the goal is to get the fastest time possible with as less as possible timeloss on the passings...
flyball passings

the most tricky thing for me is when two dogs cross the sensors at the same moment (so to the µCU it looks like a very large or very slow dog passing the sensors, no one achieved a method so far to detect that :wink: - in that case i can't find a way to calculate (even approximatly) a time for the dogs going in and out

I'm well interested in the manner you would handle this project, because you approach it from a different point of view (completly new to me I must say :slight_smile: )

I have already a whole bunch of code i tried to make (and that does work in some way for me, but i still miss a lot of things to be made)

AND most of all i'm a newbie to the arduino world and surrely no programmer or ingineer :-*
so my code is full of beginners mistake's i think

Grtz,
Yves

Is that like a spherical cow?

Hi all,

Finally my new toys have arrived :wink:

now i would really like to try with the interupts, to get my goal.

in previous post, i wrote that I use two rows of 6 photosensors, but in fact my code is made for two different sensors (vertically 15cm apart from one another), and the 2x5 sensors are paralell to those 2 rows...

i had to use the internal pull-up resistor for making the sensors work properly (so i think when i would start with the ISR's, i would have to make that a hardware pull-up outside the MCU then?)

so my goal is :

when a dog crosses the first sensor, so this one "changes", to take the time (in micros), the dog moves on and crosses the second sensor, i would like to take that time too in micros, on a certain moment, the end of that dogs body will exit the first sensor, this time i would like to take also (but meanwhile the second sensor is still active due to the front part of the dogs body, eventualy the back of the dog will also exit the second sensor, that time i would like to take too...

i think that for my project it is important to know how long a dog takes to cross the first, both of them and the second sensor.

i've found out that, it is not wise to do calculation on timing when the sensors are active, so i have to store this data, to put i out to an LCD display a bit later on (approx. 1,5sec later)

normally it takes approx. 4 seconds for a dog to go through the sensor, grab the ball and come back through the sensors. but in the best case scenario, the next dog that goes to grab a ball, will be only a few inches away from the sensors, when the first dog runs out them.

i could post the complete code i've made so far here, but it's a really long piece of code, and there is no fun in making others do all the work for me, but on the other hand I think i'm really in need of some good hardware and programming advice...

another problem for me is, that i use time in floats (long) now, but when an excellent passing of two dogs happens, i need to write "OK" instead of any time measurements.
so on the display something like this must be possible also:

Dog Laptime Passing

Dog1 : 4,002s X 0,012s (=> this is the time since the green lamp went to "ON")
Dog2 : 3,901s X OK (=> the 1st dog and the 2nd dog did pass the sensors together)
Dog3 : 4,100s X 0,060s (=> this means that the 3rd dog was 0,06 to late to have an "OK")
Dog4 : 3,973s X OK (=> another "perfect passing")

anyone any suggestions on how to handle all this?

Grtz,
Yves

anyone any suggestions on how to handle all this?

How fast are the dogs moving? It si VERY unlikely that you NEED interrupts.

I think he said the sensors are 6 inches apart and it takes four seconds for a dog to pass if that helps you to work out the dog's speed.

Personally I'd be a bit worried about fluffy dogs giving incorrect readings.

I think he said the sensors are 6 inches apart and it takes four seconds for a dog to pass if that helps you to work out the dog's speed.

No, it takes the dogs about 4 seconds to run 31 meters (102 ft)

You have two dogs running at full tilt from opposite directions at two lines of sensors a few inches apart and they are concerned with sub millisecond accuracy as to which one crosses first to determine fouls . I think interrupts are entirely appropriate.

You can use pin change interrupts to detect level changes on multiple pins.

It's all very well using microsecond accuracy, but my personal concern would be that different parts of the dog (eg. the nose) might trigger the sensor for one dog but the leg might trigger the other one. Your array of 6 sensors might solve that.

Still not sure what type of sensor is being used ... through-beam, retro-reflective or diffused-reflective. The full part number is needed in order to determine the sensor's exact specifications.

in previous post, i wrote that I use two rows of 6 photosensors, but in fact my code is made for two different sensors (vertically 15cm apart from one another), and the 2x5 sensors are paralell to those 2 rows...

Can each row detect a separate dog (diffuse-reflective sensor type?), or is one row for "sender" devices and one row for "receiver" devices?

Does this image show a typical sensor array with one row on the left and one row on the right?
Looks like this shows the most difficult scenario of timing 2 dogs crossing at the same time.

Could you provide a sketch or image of the sensor array layout and connection scheme?

YvesD:
Hi all,

for my project (dogsport timer) i'm trying to trap how long a passing dog interrupts a photoswitch sensorgate.

crossings & passings in our dogsport

::::SNIP::::

YvesD,
it looks like you have a solution for your "project". I have one questions. How did you get the humans to cooperate? :wink:

Jesse

@YvesD, I had the impression from your original description that there would NEVER be more than one dog within the sensor gate. But in Reply #12 you say that the objective is to have 2 dogs at the exact same time.

That will be a great deal more complex - even without worrying about whether it is a nose, an ear or a leg that trips the sensor.

I think you need to think very clearly, with diagrams (and maybe photos of typical dog movements) just to figure things out for a single dog.

I suspect that, without a camera and complex software, it would not be possible to detect two overlapping dogs unless you can get them to run through two separate gates. And a camera immediately rules out an Arduino.

...R