Loading...
Pages: [1]   Go Down
Author Topic: YAP - Yet Another Photogate  (Read 308 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Arduino Science
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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



Code:
/* Arduino photogate
Version 0.5
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;
        }
     
   
   
   
   
  }
    }
  }
 
Logged

Pages: [1]   Go Up
Print
 
Jump to: