Abstract: This project tests the performance of an Infrared detector with a Model Train. The design uses a commercial IR circuit module.
Keywords: IR, Infrared detector, ESP8266, false exits, Model Train Detection
Future projects involve monitoring Model Trains. For example detect trains and control trains entering from either end of a single section of track. One solution is to use IR detectors to monitor the trains. This page is concerned with evaluating the performance/limitations of the IR detector module.
Since future projects may use WiFi the ESP8266 was the chosen micro-controller although an Arduino UNO or NANO could be used,
The test circuit uses an IR Line Tracking Sensor Module as shown above. The Infrared transmitter and receiver are mounted between the sleepers with their tops level with the railway tracks. As shown the tracks had to be elevated by approximately 8mm to make room for the IR PCB below the tracks.
The IR Sensor Module contains two LEDs - a red to indicate it is receiving power and a green to indicate an object has been detected. (In anticipation of a coming project two sensor modules were fitted on the test board. It turned out this second module must have come from a different source as it contained two green LEDs!)
Since the module contained a LED to indicate if an object was present, in theory the design could be visually tested by observing the green LED. However the status will be read on Pin D1 of the ESP8266 as a starting point for the firmware of future projects.
While the sensors did operate correctly in my train layout they were continuously triggered at my desk when a desk lamp was on so operation should be confirmed in the final environment. They will not operate in sunlight.
The test layout included the IR sensors fitted to the model railway tracks. Using the output LED on sensor module the performance of the IR detector could be evaluated.
Note the sensors would detect an open hand 50mm (2 inches) above.
A pair of railway wagons were then moved across the sensor and the status of the LED observed.
1. The sensors did not detect anything when the wagon couplings were above the IR transmitter and receiver. This was not a surprise but the LED turning on and off when the wagons were over the sensor was a surprise. This was considered to be due to the black under surface of the wagon and its height above the track. See photo below.
The wagons included small manufacturing dimples that may or maynot have had some impact on the result.
2. Adding a white strip of plastic to the base resulted in a good solid ON LED while the wagons were over the sensor. A second solution was to add a white label to the wagon base.
The instructions for the module recommend not changing the setting on the variable resistor. However, in my case by turning it clockwise about 45 degrees the output LED turned on. The screw was then turned anti-clockwwise about 15 degrees to turn the LED off. (Overall the screw has been turned 30 degrees clockwise). I found that the sensor now appeared to detect both the wagons with their black underside and the couplings as they passed over the sensor.
Looking at the response on a Mixed Channel Oscilloscope gave the following results when two coupled wagons crossed the sensor. There were spikes at both ends and in the middle which may be assumed to be when the couplings were passing over the IR detector. There was one other for which I have no explanation.
As shown the signal is not a solid low. The signal will indicate when the train arrives. However due to the numerous pulses there is no unique transition (other than the "last" one) that defines when the train has passed.
The next step is to develop a test program to determine exactly what the micro-controller sees.
The project code is developed using the Arduino Integrated Development Environment (IDE).
In my example the LOIN(WEMOS) D1 Mini Lite was chosen from the Tools : Board Manager option in the IDE.
The initial test program will read digital voltage every 100 ms and display the results to the screen using the serial monitor.
The train will be moved across the LDR to observe the serial monitor output.
The digital output will be "1" for IR in the open (no train) and "0" for the IR covered (train detected)
The initial code is given below:
#define FLASH_ON digitalWrite(BLUE_LED,LOW); //note negative logic#define FLASH_OFF digitalWrite(BLUE_LED,HIGH);int BLUE_LED = D4; //use for debugging/evaluating performanceIn anticipation that in future the on board blue LED may be useful in observing the program operation at this point it is flashed every loop.
The program gave the following results:
A single wagon was moved by hand across the IR module and the readings captured every 100ms. Initially the readings were a logic '1' indicating no train present, they oscillated between '1' and '0' as the wagon crossed the sensor and returned to '1' 26 samples or 2600 ms later when the wagon cleared the sensor.
For later reference the wagon is approximately 72 mm (3 in) long from coupling to coupling so in the test the wagon was moving at 28mm/sec (~1in/sec) or 1.6 metres/minute or 0.1 Kph (~300ft/hr).
The previous program read the digital voltage every 100 ms and used the Arduino serial monitor to display the results.
This section will divide the program into two :
1. Before the train is detected - defined by the state "wait4train"
2. After the train is detected - defined by state "wait4end".
The additional/modified code becomes:
The code will now loop waiting for the train to go over the sensor. Once the train is detected the BLUE LED on pin D4 of the ESP8266 will turn on and the sensor status will be displayed on the serial monitor.
Detecting an arriving train is quite straight forward as shown by the line if (digitalRead(D1) ==0). The more difficult problem is detecting the end of the train.
As shown by both the timing analyser trace and the serial printout the end of the train is defined by the last of many positive transitions in the waveform.
The end application will determine the final code. Some applications will not need to capture the end of the train, for others the accuracy or precision is not important while for some it might be necessary to stop the train at a defined point so accuracy/precision will be important.
The new code is shown below.
......enum state {wait4train, wait4end} train_state;int delay_count;#define delay4false 10 //false exits due to couplings - no reflectionvoid setup( ){ Serial.begin(115200); //baud rate serial monitor Serial.print("\Testing IR Sensor as a train detector"); pinMode(BLUE_LED,OUTPUT); train_state = wait4train; FLASH_OFF}void loop() { if (millis( ) -start_time > DELTA_TIME){ switch (train_state) { case wait4train : if (digitalRead(D1) ==0) //wait for train to arrive { FLASH_ON train_state = wait4end; delay_count = 0; } break; case wait4end : //Serial.print(digitalRead(D1)); //profile train delay_count++; Serial.print(delay_count); Serial.print(','); //test exit if (digitalRead(D1) == 0) //detected train so restart loop { delay_count = 0;} else if (delay_count >= delay4false) { train_state = wait4train; //ready for next train delay_count = 0; FLASH_OFF //train passed } break; default : Serial.print('?'); //error } start_time = millis( ); } }The variable delay_count is used as a counter. On each count the sensor will be checked - if it indicates a train is present delay_count will be reset. If there is no train it will be incremented until it reaches delay4false In the example delay4false is set to 10 so it is assumed that if there are 10 consecutive readings of no train there is really no train. (See earlier printout where there are 5 false readings)
Running a wagon over the sensor gave the following readings:
The printout indicates many immediate restarts (consecutive 1's) - a couple of false starts where the count reached '3" and one event where the count almost timed out.
The following profile observed on the Arduino Serial Monitor of a single wagon moving across an IR sensor are repeated below. Ideally the results should give a solid signal. That is 11110000000000000111111 - a solid "1" for no train, a solid "0" while the train was above the sensor and a solid "1" after the train has left. . As shown below there is a lot of "noise" or false readings indicating no train when there is in fact a train.
The previous discussion indicated the arrival of a train when the sensor became "0".
However due to false readings (exits) the presence of a train over the sensor or the train leaving was not uniquely defined. The discussion presented code that checked a number of times for false exits resetting the counter each time a train was found to be present.