IR Tripwire Not Working

I'm trying to build an infrared tripwire to detect when a HO scale model train passes, using this module:

I have de-soldered the transmitter led and the three pin receiver, and re soldered them to leads. Then I have placed each part (transmitter led and receiver) on separate sides of the track. Last night, I tested the output pin of the module and it always outputs ~0.5 volts, whether the IR led is on or off. I have made sure that the led is focused directly on the receiver, but that doesn't change anything. It doesn't work. It does not detect whether a train or anything else has passed through the beam.

This is my code:

[code]
#include "U8glib.h"

U8GLIB_ST7920_128X64_4X u8g(10);

uint8_t draw_state = 0;

#define SENSOR_DISTANCE  200000 // [um] measured distance between the two IR beams
#define INIT_TRAIN_LENGTH    20 // [cm] New measurement only starts when train fully passed
// Loco Length can be changed via keyboard input
#define SENSOR_L_PIN 6
#define SENSOR_R_PIN 7

byte l_r, state;
byte scale, scale_old;
byte units, units_old = 99; // 0=MPH, 1=km/hr, 99=startup dummy
int train_length, serialread;
unsigned long start_us, stop_us, measured_us, waittime;
float m_per_s;
float km_per_hr;
float mi_per_hr;

void read_write_scale() {
  if (Serial.available()) {
    serialread = Serial.parseInt();
    if (serialread) train_length == serialread;
    Serial.print(F("Train length set to: "));
    Serial.print(train_length);
    Serial.println(F(" cm"));
    Serial.println(F("Waiting for train ..."));
    Serial.println();
  }
  scale = 87;                        // scale HO
  if (!digitalRead(14)) scale = 45;  // scale O
  if (!digitalRead(15)) scale = 76;  // scale OO
  if (!digitalRead(16)) scale = 120; // scale TT
  if (!digitalRead(17)) scale = 160; // scale N
  if (scale != scale_old ) {
    scale_old = scale;
    Serial.print(F("Scale set to: 1/"));
    Serial.println(scale);
  }
  units = digitalRead(8); // 0=MPH, 1=km/hr
  if (units != units_old ) {
    units_old = units;
    Serial.print(F("Units set to: "));
    if (units) Serial.println(F("km/hr"));
    else      Serial.println(F("MPH"));
    Serial.println(F("Waiting for train..."));
  }
}

void setup() {
  pinMode(13, OUTPUT);
  pinMode(SENSOR_L_PIN, INPUT_PULLUP);
  pinMode(SENSOR_R_PIN, INPUT_PULLUP);
  pinMode( 8, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(16, INPUT_PULLUP);
  pinMode(17, INPUT_PULLUP);
  pinMode(18, INPUT_PULLUP);
  Serial.begin(9600);
  train_length = INIT_TRAIN_LENGTH; // [cm]
  Serial.println();
  Serial.print(F("Train length is set to "));
  Serial.print(train_length);
  Serial.println(F(" cm "));
  Serial.println(F("For longer trains change this by typing"));
  Serial.println(F("in the input field above and hit ENTER"));
  //  Serial.println(F("For auto measurement with Traincontroller:"));
  //  Serial.println(F("1: Open TC Speed Profiling Tab"));
  //  Serial.println(F("2: Start AutoHotKey"));
  Serial.println();
  read_write_scale();
  digitalWrite(13, HIGH); // LED on means ready for measurement
}

void loop() {
  read_write_scale();

  switch (state) {
    case 0: // initial state, ready to start measuring
      if (digitalRead(SENSOR_L_PIN)) {
        start_us = micros();
        l_r = 0;
        state = 1;
      }
      if (digitalRead(SENSOR_R_PIN)) {
        start_us = micros();
        l_r = 1;
        state = 1;
      }
      break;

    case 1: // wait for the other sensor to be triggered
      digitalWrite(13, LOW);
      if (!l_r) {
        Serial.println(F("L >>> R"));
        while (!digitalRead(SENSOR_R_PIN)) {} // loop here until sensor R is triggered
      }
      else {
        Serial.println(F("L <<< R"));
        while (!digitalRead(SENSOR_L_PIN)) {} // loop here until sensor L is triggered
      }
      stop_us = micros();
      state = 2;
      break;

    case 2: // calculate and show speed values
      measured_us = stop_us - start_us - 10UL; // -10 to compensate for code delay
      m_per_s = float(scale) * float(SENSOR_DISTANCE) / float(measured_us);
      km_per_hr = 3.6 * m_per_s;
      mi_per_hr = 2.23694 * m_per_s;
      if (!units) {
        Serial.print(mi_per_hr);
        Serial.println(F(" MPH"));
      }
      else        {
        Serial.print(km_per_hr);
        Serial.println(F(" km/hr"));
      }
      Serial.println();
      waittime = (int)(10UL * measured_us * (unsigned long)train_length / (unsigned long)SENSOR_DISTANCE + 1000UL); // [ms]
      // measured_us is needed for a move of SENSOR_DISTANCE um
      // measured_us * train_length / SENSOR_DISTANCE) time is needed for train_length to pass
      Serial.print(F("Wait "));
      Serial.print(waittime);
      Serial.println(F(" ms"));
      // delay(waittime);
      digitalWrite(13, HIGH); //Next measurement can start when LED is on
      Serial.println(F("Waiting for train..."));
      state = 0;
      break;
  }
}
[/code]

The code and basic idea for this project come from an online tutorial:

Are you shielding the sensor from ALL other IR light in the room?

@Paul_KD7HB
As much as is possible.

Transmitter LED:


Receiver:

Both are lined up.

They are "embedded" in timber, exactly lined up, I can't really "shield" them any more than that without blocking the trains path. They are better shielded than in the original module.

Sure you can. Add paper tubes right up to where the train will hit them. OR better, yet, for a test add a tube on the sensor but allow room for you to use a piece of card board to stop the light. If that works, then you need to design a different system.

1 Like

Or tunnel

Ok, I just tried that with this code:

void setup() {
  Serial.begin(9600);
  pinMode(7, INPUT_PULLUP);
}
void loop() {
  Serial.println(digitalRead(7));
  delay(10);
}

The serial monitor says "0". It doesn't ever go to a one, whether the cardboard covers the holes in the tube or not.

I would use a laser tripwire (I've had success with those before)except that the railway owner doesn't want to see a red dot on his train at every crossing and at the speedometer. Are there any other invisible tripwires I could use?

You need to tell us how you went about adjusting the level control on the sensor.

You mean the pots? If so, I've tried fiddling with both of them, together and separate, and I tried with and without the jumper.

Yes, the pots. One is for the IR LED frequency and the other is for the IR LED intensity. Did you test the sensor both before you disassembled it and after you put it back together and before you added the parts to the RR track?

1 Like

The pots didn't make any difference, except one of them when turned completely anti-clockwise would make the serial monitor output random numbers, both one and zero.

They didn't really get a thorough test before I disassembled them (I have two), but I did check the second one before I disassembled it, and it did work as a "motion detector" when I put something in front of it.

Likely to be the frequency, so that was working. But the intensity pot did nothing to change the sensitivity.

Currently if you turn the frequency to lowest value, what happens to the received pin?

It doesn't change. It still displays zeros. I did actually stick a dmm on that pin, and it sticks at ~0.5 volt continually. It never actually moves up or down from that, whether I move the pots or I block the IR beam.

The LED is switched on and off at some frequency, so the receive should also show that frequency, but a DMM will average the signal, so gives no useful information.. Time for your oscilloscope!

1 Like

I'll probably have to go with a laser tripwire. I don't understand why this doesn't work, but this is the third IR project where the IR failed, so I'm going to not use IR from now on wherever possible.

PS. I'm not rich enough to buy an oscilloscope.

Don’t you think that if you can never get the receiver to turn off that the problem does not lie in the illumination source?

1 Like

I would've thought so.

There’s not much information on the data sheets I saw but it looks like the receiver uses a common IR receiver module that is only sensitive to IR at a particular frequency, e.g. 38kHz.
The ones I’ve used didn’t have any problem being “off” when they were not Illuminated by a pulsed IR source. It’s a pity you didn’t spend longer experimenting with them before you took them apart.
I know you have set your digital inputs with pull-ups enabled but have you tried adding a physical pull-up resistor, say 10K, to see if you get a different result?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.