The attached should have gone to the list and not just to Ralph.
--- Begin Message ---
On 01/05/2026 10:43, Ralph Corderoy wrote:
The Sensor output is low when there is no train in front of it and
rises when there is.

Actually that statement is wrong,  I've had some problem trying to get my head round what happens; not least because the sensor documentation is pretty vague.  What we do know is that the sensor output is an open-collector transistor (but they don't say if the transistor is NPN or PNP).  They give diagrams that say how to connect the output to an LED, and from those we've determined that the transistor is PNP and since the terminal is pulled up to 12 V the output is normally high and is low when there is a train triggering it.   To add to the complexity, the recommended method of using this sensor is to bury the sensor and the IR LED in the trackbed and the sensor is triggered when the train passes over it.  This is the way these sensors worked for the initial several years of use.

At the beginning of last year, a new train was bought, but we had problems with the new setup even then, because the reflectivity of the underside of the train made detection variable.   Over last winter the sensors were mounted track-side, with the LED on one side of the tracks and the sensor on the other.  In this scenario, the sensor outputs were all pulled up as described, so a high was measured on all the sensors /except/ when the train was in front of it.  So the statement  above should be:

/  The Sensor output is high when there is no train in front of it and falls when there is./

So having said all that my code needs to do nothing when the the Sensor output is high and break out of the loop when it is low.

By polling for a high input, there's the chance it might be missed
depending on timings.  Have you checked:

- How long the train takes to pass the sensor, i.e. how long the sensor
   remains high.
The train is four carriages long and it takes several seconds for the whole train to pass the sensor.
- How often your while loop runs given it's part of a larger body of
   code which may be busy, or even tied up, elsewhere.
:-)  This is spaghetti code  :-)  The program is doing nothing else once the train has reached full speed.
- The value of sensor_pause_time, and that it is in seconds as
   time.sleep() wants.
50 ms.
Also double-check more simple things:

- GPIO configured as input.
- Any Pi-configured pull-up/pull-down is correct.
Check.

I'd debug with print().  So taking your last version, make it:

     print('sensor b: test start')
     for i in range(sensor_test_loops_out):
         if GPIO.input(sensor_b):
             print('sensor b: train', i)
             break

         print('z ', end='', flush=True)
         time.sleep(sensor_pause_time)
     else:
         print('sensor b: test end, no train')

- The old code went around the while-loop sensor_test_loops_out+1 times.
   range() makes that easy to avoid.

- The first code was correct: stop waiting for the train when
   GPIO.input() returns true meaning the GPIO is high.

- Observe the speed of polling by the stream of ‘z z z...’ showing the
   time.sleep()s.
I'll try all of those things.
Can you slow the train so the sensor should be high for longer on each
passing?
We can stop the train in front of the sensor, simply by dragging it along the track when it is not powered.  All the voltages are as expected.
Polling is often not the ideal way to do it.  There are better ways,
like event_detected().  But don't switch to those without getting the
current method working; that would just be adding another layer of murk
to obscure.  Fully understand the current behaviour first.
https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs
As you say, I'll try to work out what is going on in the code before I do anything more exotic.

--
Terry Coles


--- End Message ---
-- 
  Next meeting: Online, Jitsi, Tuesday, 2026-05-05 20:00
  Check to whom you are replying
  Meetings, mailing list, IRC, ...  https://dorset.lug.org.uk
  New thread, don't hijack:  mailto:[email protected]

Reply via email to