YAP - Yet Another Photogate

Hi to all.
I am offering this in the hope it is useful to some.
I wrote it for one of my students, who needed to measure the speed of a marble
falling through a tube.

It's primary (and huge, in practice) advantage over other circuits is it's ability to
self-tune its sensors, allowing quick setup in all sorts of light.

It uses very cheap Vishay TCRT5000L photosensors, which can be had for pennies,
and veroboard to achieve accurate spacing. It can capture speeds up to 23m/s.

Read the code, esp comments for tips,tricks for setting it up, and troubleshooting.

Do enjoy!
Cheers,
Harristotle

/* Arduino photogate
Version 0.51
by Leon Harris
 Sensor is based around two TCRT5000L sensors, broken up into
LED and phototransistor pairs. These have visible filters on 
them and are great for rejecting a lot of ambient light.


The circuit:

----------------------------------------------5v+
  |        |                    |       |
  V  ->   K                     V  ->   K
  _        \                    _        \
  |         |                   |         |
  |         |                   |         |
  \         o-------------------[---------[------ A0
  /         |                   |         |
  \68R       \                  |---------o------- A1
  /          / 15Kohm           \ 68R      /
  |          \                  /          \ 15K
  |          /                  \          /
  |          |                  |          |
  o----------o------------------o----------o-- GND
  
  
  The circuit is mounted on two veroboard strips, with 9 holes
  between the LED and photo diodes- this gives a gap of 23.35mm
  between the IR detectors centres.
  
  Use
  1.) Set up your photodetectors opposite your photodiodes
  2.) Roll something between the two to break the beam
  3.) monitor your serial monitor for results.
 Note that the autotuning of the sensors makes this photogate very robust, and work well in different lighting
conditions. 
  
  Troubleshooting
  1.) Check that your photodiodes and LEDs are aligned, with a 1cm gap or more between them
  2.) Check that you have the start and stop phototransistor around the right way.
       Do this by slowly and repeatedly passing a ruler or other light blockage through the photodetectors.
       If you get a fast speed and a slow speed, it means that the photodiode furtherest away from you
       is actually your start photodiode. Swap them, and all should be good.
  3.) Check that your infrared LEDs are actually working. Do this by photographing them with a phone camera -
       phones are sensitive to IR and you should see two glowing LEDs in your screen.
  */
  
  
  // Constants
  int startPin=A0;
  int stopPin=A1;
  int ledPin=13; //used to flash when we detect an event
  
  int startADC=0; // stores start detectors ADC reading
  int stopADC=0; // stores stop detectors ADC reading
  int inGate=0; // status flag to tell if gate is "in play"
  
  long startTime=0;
  long timeOfFlight=0; // calculated time in photogate
  
  
  
  // T U N A B L E      P A R A M E T E R S 
  float gap = 23.35; // distance between centres of detectors
  int startThreshold; //below this, we consider light to be blocked
  int stopThreshold;  // below this, we consider light to be blocked
  
  
  void setup() {
    pinMode(ledPin,OUTPUT);
    Serial.begin(9600);
    
    
    
    // Autotune routine for detectors 
    long AVG=0;
    for (int i=0; i < 9; i++) {
      startADC=analogRead(startPin);
      AVG +=startADC;
    }
    AVG=AVG/10;
    startThreshold=AVG; //threshold is 90% of average
    
    AVG=0;
    for (int i=0; i < 9; i++) {
      startADC=analogRead(stopPin);
      AVG +=startADC;
    }
    AVG=AVG/10; //threshold is 90% of average
    stopThreshold=AVG;
    
  }
  
  
  
  void loop() {
    
   
    
    startADC=analogRead(startPin);
    if (startADC <  startThreshold ) {
      startTime=millis();
      inGate=1;
      while  (inGate == 1) {
        stopADC=analogRead(stopPin);
        if (stopADC < stopThreshold) {
          timeOfFlight=millis() - startTime;
          
          Serial.println();
          Serial.print("gate time: ");
          Serial.print(timeOfFlight);
          Serial.print(" milliseconds ");
          Serial.print("velocity = ");
          Serial.print(gap/timeOfFlight); // mm/msec = m/s!
          Serial.println(" m/s");
          
          inGate=0;
        }
     
    
    
    
    
  }
    }
  }

Two corrections to the circuit, found by building another few units.

  1. The circuit diagram in the ascii art is incorrect: the A1 pin is connected to the emitter of the second photodiode, not the cathode of the LED. --FIXED, version changed to 0.51

  2. A nice fat 100uF capacitor across the LEDs helps the jitters where sometimes you get a phantom second reading after a marble has passed through the photogate.

Possible idea to test: Improve jitters (which are no longer really a problem) in the next version by swapping the resistors and the LED around. So that when there is a power interruption/dip on the 5v rail, the 100uF capacitor can discharge either into the rail via the 68 ohm resistor, or into the LED with no resistor, thus allowing the LED "preferential" use of the charge stored in the capacitor. In its present form, the capacitor will charge to the LED operating voltage, and its charge flows directly to the 5v supply or through the LED. In other words, you can use the 68 ohm resistor to slow the rate of discharge into the 5v line.

That concludes my playing with this circuit for this year -we have moved from motion in physics to heat.

The setup, on my desk, can be seen here

Photogate

Cheers,
H.