IR Photogate Interrupt

I have done some simple programs on the Uno and yet I keep coming up empty when trying to program something that seems so basic.

I have two IR photo-interruptors and I'm rolling a coin past them. I need the time between when the coin triggers gate 1 and gate 2. I have the signal from the gates in the interrupt pins (digital 2 & 3). I just need a serial display of the time it took for the coin to travel from gate 1 to gate 2.


Oh wow! That was so helpful!! I LOVE when people patronize me.

I clearly can't even come up with the proper pseudo code so I have no code to post.

I'm trying to figure out how interrupts work and I don't know how they apply here.

Once I use attachInterrupt(pin0, functionblah, CHANGE), what do I put in that function? How do I get to the next one?

mstxee: Oh wow! That was so helpful!! I LOVE when people patronize me.

You assume to know what was in my mind when I created that post. I can safely say that you failed the mind reading course.

I clearly can't even come up with the proper pseudo code so I have no code to post.

That was not clear to me from your post.

I'm trying to figure out how interrupts work and I don't know how they apply here.

There is no indication that you need interrupts. I suggest you first get the application working without using interrupts. If there are accuracy problems then introduce interrupts.

Comment deleted.,97455.0.html

Hello! I'm totally new to Arduino and the Forum, by the way I've implemented and tested the following system. I'm using 2 TSOP ir receiver at 38Khz, the 2 IR led are wired to pin TX and they blink at 38 Khz I'm assuming that the coin will roll in only one direction (from A beam to B beam) If you have any question I'll be glad to answer.

Try to adapt the following code to your circuit.

//pin definitions
#define RXA 12
#define RXB 10
#define TX 11


int timerA = 0;

boolean hitA = true;
boolean hitB = true;

boolean leave = false;

boolean transmitting_IR;
boolean receiving_IR;

void turn_off_IR ()
  // Instead of just adjusting the output on pin 11, this code also
  //   turns off the timer controlling the PWM output on pin 11
  TCCR2A = 0; // Disconnect PWM
  TCCR2B = 0; // Stops the timer
  OCR2A = 0;  // No timer top
  digitalWrite(11, LOW);  // Ensure output is off
  transmitting_IR = false;

void turn_on_IR ()
// Set up Timer2 (which can be connected to pins 3 and 11)
  // For full details, see:
  // The syntax here has me baffled, but the patterns of usage
  //   are clear if you look at the ATMega328 diagrams.
  //   _BV appears to stand for 'bit value'
  //   Different bits need to be set to control each timer
  //   Refer to diagrams for clarity

  TCCR2A = _BV(WGM21) | _BV(COM2A0); // This mode toggles output once per timer cycle
  TCCR2B = _BV(CS20);  // Do not scale the clock down - use 16 MHz timer rate.
  OCR2A = 210; // Divide sys. clock by 210, 1/2 cycle = 76 khz, 1 cycle = 38 khz
  // Output pin 11 should now be emitting a 38 khz signal.
  transmitting_IR = true;

void detectIR()
  // Determine if we are receiving an IR signal.
  //   if pin RXA is false = receiving
  //   if pin RXA is true = not receiving
    hitA = false;
    hitA = true;
    hitB = false;
    hitB = true;

void pulseIR(){
  //manage the IR transmitter
  if (transmitting_IR)
  if (!transmitting_IR)

void checkA(){
  //RX routine
  if(leave == false){ //
    if(hitA == false && hitB == true){ // if the RXA beam has been broken
   // The coin is rolling from A to B  
            leave = true; // set the passing flag 
            timerA=millis(); // start the timer

void checkB(){
  if(leave == true){ //if the coin is rolling from A to V
    if(hitB == false && hitA == true){ // and the coin break the B beam
            leave=false; // reset the rolling flag
            int now = millis();
            int time = now - timerA; //compute the time

void setup(){  
  pinMode(RXA, INPUT);
  pinMode(TX, OUTPUT);
  pinMode(RXB, INPUT);  

void loop(){
  pulseIR(); // transmit cycle
  detectIR(); // search for IR
  checkA(); // check A IR sensor
  checkB(); // check B IR sensor

For now i suggest you to look only at the checkA() and checkB() function, the pulseIR() and detectIR() are butchery function with the purpose of handling the sensor.

P.S. sorry for my english, I’m still learning! :wink:

Here a fritzing of my circuit

I think I got it working without interrupts. Is there any way to improve the accuracy?

Here is my current code:

unsigned long time1 = 0;
unsigned long time2 = 0;
unsigned long deltat = 0;
boolean flag1 = true; 
boolean flag2 = true;
boolean flag3 = false;
boolean done = true;
int gate1 = 2;
int gate2 = 3;

void setup()
  pinMode(gate1, INPUT);
  pinMode(gate2, INPUT);

void loop(void)
  if (digitalRead(gate1)== LOW && flag1 == true)
    flag1 = false;
    time1 = millis();
    Serial.print("\n\nGate 1 tripped at time: ");
   if (digitalRead(gate2)== LOW && flag2 == true)
    flag2 = false;
    time2 = millis();
    Serial.print("\n\nGate 2 tripped at time: ");
  if (flag1 == false && flag2==false & flag3 == false)
    deltat = time2-time1;
    Serial.print("\n\ndelta t = ");
    Serial.print(" ms.");
    flag3 = true;

What did you mean with "improve", are you observing some inaccuracy?

You could improve latency by not printing as soon as you detect, or at least shorten the print ( or bump up the line speed)