Reverse Loop Controller

Revised 07-08-07

This controller will automatically reverse the polarity of the power to a main line so that a track powered engine can successfully navigate a reverse loop without stopping and without causing a short circuit in the track.

The controller reverses the polarity with a DPDT relay and senses the train's location within the reverse loop with a reed switch.

In addition the layout will support two engines running simultaneously.  They will pass one another through a pair of sidings.

Click here for the latest updates (7-8-07)

 

Overview:

A reversing loop is frequently used by model railroaders to reverse an engine's path on a single main line.  The problem with reversing loops is that they create a short circuit within the track as the loop connects the two rails of the main line.  This problem is addressed in a number of ways.  The simplest and most common is to completely isolate a section of the reversing loop from the main line.  This isolated section must be long enough to accommodate the engine and any cars that might have pickup wheels that feed power to the engine.  The isolated section is powered from the main line through a bridge rectifier.  This device supplies the same polarity of power regardless of the polarity that is fed into it.

When the train has fully entered the reversing loop a reed switch is tripped by a magnet under the engine triggering the controller which throws the DPDT relay reversing the power to the main line so that the train moves in the proper direction upon exiting the reversing loop.

 

 
Test Layout:

 
Schematic:

The schematic shows that the controller is based on a PIC 16F88 processor.  Two, identical units are used - one for the left side of the layout and one for the right.  The Bridge Rectifier is not on the same circuit board as the other components as it is simpler to place it near the start of the reversing loop.

 

The track in the crossing siding area is wired as below.  The two blocks are completely isolated from the main line except for the two diodes that connect one end of each block to the main line.

 

 

Program Operation:

Both engines start somewhere on the mainline other than an isolated section.  When an engine crosses a sensor on an isolated block in the reversing loop it triggers a DPDT relay and voltage is reversed.  The bridge rectifier keeps the engine moving forward until it clears the block.

When an engine enters its crossing siding it stops when it crosses the open gap in the track.  It also triggers its crossing block sensor.  When the circuit finds that both engines have returned to the crossing blocks the polarity of both relays is reversed and the engines continue on their way through the diodes at the other end of the crossing block.

Note that the system does not automatically accelerate or decelerate the engines when starting or stopping - this will be added in the next revision, I hope!

 

Video:

Click here for a short video in WMV format - may take a few minutes to download and play

Click here for the same video in MPG format - may take a few minutes to download and play

 

 

Update - Thursday, June 28, 2007

A good bit of experimentation over the last two days has resulted in a reverse loop controller and software that is improved in a number of ways.

  1. The two trains run as in the first videos (above) but now they both decelerate nicely before stopping when they enter the sidings utilizing PWM
  2. All starts (both at initial power up and in the sidings) are gradual, again with PWM control
  3. A set time or random delay can be implemented to keep the trains in the sidings
  4. Only two relays are employed.  These are used to reverse the track polarity to navigate the reverse loops and to restart the trains after both have entered the sidings.
  5. In order to keep the two independent controllers from short circuiting and to allow the smooth stops and starts an additional 4 diodes (a total of 8) are employed in the crossing sidings - no relays are used in the sidings
  6. Both trains are powered by a single power supply that is separate from the controller's power supply.  This allows the trains to be stopped but the controller to continue operating so that train position can be remembered.
Schematic:

Note that the controller is actually made up of two PIC16F88 processors, two relays, etc.  The Mosfet (Q1) is used to control the acceleration and deceleration of the trains.

It is most important that proper polarity be observed when supplying power to the circuit from the "Train Power Supply" - A meter must be used to determine + and - terminals and if the unit that is used has a Forward / Reverse switch it must be disabled or covered to prevent its being used.

The track sections at the bottom of the schematic show the diode placement in the crossing siding.

Video Update:

Click here for a short video in WMV format - may take a few minutes to download and play

Click here for the same video in MPG format - may take a few minutes to download and play

 
Controller:

The prototype controller is shown below - two identical PIC microcontrollers, relays, Mosfets, etc.  The reed relays connect just below the white boxes (relays).

Note that the reed relays must be connected by twisted pair cable.

Diodes:

Here is the matrix of diodes (no an breadboard, no less) that are used to control the crossing sidings.

 

Update - Monday, June 2, 2007

After a good bit of experimentation and testing some observations :

  • Track and engines must be in very good condition. 
    • Operation of the two independent sides of the layout depends on proper synchronization between them
    • a stalled engine on either side will likely lead to a collision or short circuit
    • shorts occur when a 2nd engine enters the same side of the layout and it bridges the cut in the track between the bridge rectifier section of the layout and the relay controlled part.
  • If one train returns to the crossing sidings before the other train hits the reed switch in its reverse loop the first train continues right through the crossing siding
    • This is because the reversed polarity of the 2nd half of the layout is what properly biases the diodes causing the train to stop in the siding
    • if this reversing has not happened by the time the train hits the siding the train does not stop.
  • A solution to this problem is being considered
    • it involves having each controller trip the polarity relay if its crossing sensor has been hit before the other train gets to the loop sensor
    • there may be other unforeseen consequences from this change
    • for example, the train that has not yet hit the reverse loop will immediately reverse - not sure if this is a better consequence than the short circuit that may occur!
  • On a more positive note the system works reliably and consistently as long as:
    • the electrical connection between sections of track is good
    • the speed is high enough to guarantee clearing the frogs
    • the engines are in good running condition with good electrical pickups on their wheels
    • the two engines run at about the same speed when the same voltage is applied

Update - Tuesday, July 3 --> Thursday, July 5, 2007

Glitches that appeared to be completely random seem to be due primarily to the use of one section of non-twisted pair wire to connect a reed switch to the controller.  When that was replaced the problems almost completely disappeared. 

The only other observation is that all track connections must be 100% solid - soldered or tightly attached with screws or rail clamps.

While on the trail to discovering the above I doubled up the loop reed switch sensors.  Two identical reed switches were soldered together side-by-side so that the chance of a missed magnet were lessened dramatically.  I am not sure if that made much difference but it is inexpensive insurance.

Later in the day...

The occasional glitches kept creeping in but may have been stomped upon with a software change.  I added a counter to each reed switch hit - the software now ignores single or even double hits of the reed switches - only after 3 or more hits are detected is a valid hit recorded and acted upon.  The multiple hits are not a problem for two reasons.  First of all the PIC processors are very fast and typically record 4 or more hits per pass.  In addition a second magnet was added to each engine.  I now get as many as 9 hits recorded on each reed switch each time an engine passes. (note: by hit, I mean consecutive time periods of several milliseconds where the reed switch is held closed - these are NOT open/close/open cycles)

Thursday

Another hardware change was made even though it may not have been needed.  The "pull down" resistors that had been used to hold the input pins on the PIC processor low until the reed switch was crossed momentarily pulling them high were changed from 10K to 1K.  The lower resistor value should make it harder for unintended pulses to cause false readings.  In addition a small (.1 mfd) capacitor was placed between each sensor pin and ground, again in hopes of filtering out noise.

The system ran flawlessly for a number of hours on Wednesday completing 832 "laps".  It continues to run equally well today with the resistor and capacitor changes.

Later in the day...

A request for a random delay within the reverse loop was made.  The software was modified so that each engine would come to a stop within a foot or so of the reed switch in the reverse loop.  Once stopped each engine pauses for a random period no less than 3 seconds and no more than 15 seconds.  Although not yet implemented, the maximum time will be adjustable by means of a potentiometer.

Note that the time in the crossing sidings is fixed and that one engine always exits a few seconds before the other.

A video is below:

Click here for a short video in WMV format - may take a few minutes to download and play

Click here for the same video in MPG format - may take a few minutes to download and play

 

Update - Sunday, July 8

Unit as Shipped
  • Circuit Board
  • 8 @ 3 amp diodes
  • wall wart power supply
  • 2 @ bridge rectifiers
  • 2 @ spare Darlington TIP102 transistors
Track Setup
  • Construct track with two reverse loops and two crossing sidings as shown in the new layout diagram below.
  • I would suggest that the crossing sidings be at least 4 feet long with at least 3 feet in each insulated section
  • Note that the layout uses four spring loaded switches (I used LGB manual switches) and 16 track insulators
  • The track is cut twice within each reverse loop (both tracks) and twice within each siding (both tracks)
  • The diodes that are shown in the wiring schematic must be oriented as indicated.  The vertical bar at one of the diode is its cathode and can be identified on the diode itself as it is marked with a silver band.
  • A bridge rectifier is installed in each reversing loop.
    • It's input terminals (labeled with a ~) go to the rails that are fed by the controller.
    • The positive (+) output terminal goes to the inside rail on the insulated section of the reversing loop - the wiring is the same for the East and West loop
    • The negative (-) terminal goes to the outside rail on each loop
  • The controller's Primary output terminal #1 goes to the outside rail - #2 goes to the inside rail - the connection should be between the loop and the siding switch
  • The controller's Secondary output terminal #1 goes to the inside rail - #2 goes to the outside rail - the connection should be between the loop and the siding switch
  • Switch settings
    • the reverse loop switches need to be set so that the trains enter the East and West loops in a counter clockwise direction
    • the crossing siding switches are set so that the engines go straight into the sidings and exit through the curved part of each switch
Controller Setup
  • Two power supplies and four reed switches are connected to the controller. 
  • One Power Supply is a standard 12 volt wall wart power supply that powers the electronic circuitry. 
    • This plugs into the coaxial power plug on the circuit board
    • When connected the red power LED on the board lights
  • The second power supply provides power to the engines.
    • It can be a variable DC power supply providing up to 24 volts.
    • The polarity of the power supply must be constant.
    •  The supply's positive output goes to the terminal marked with a plus (+) sign. 
    • A diode is installed on the board to insure that a reverse connection does no harm. 
    • If the forward/reverse switch on the power supply is incorrectly set the diode will shut the engines down. 
    • Just reverse the switch to restore power.
    • When this is properly connected the green power LED on the board lights
  • A reed switch is located inside of each reversing loop
    • The loop reed switches are used to trigger polarity reversal and to mark the point where the engine will pause
    • The position of the switch in the loop should be at least a train length or two from the end of the loop where the insulators are located
    • The wires from these reed switches connect to the controller through the Primary and Secondary Loop terminals.  The West side of the layout is primary and the East side is secondary
  • Two additional reed switches are in the sidings
    • the train coming from the east goes into the inside siding.
    • the train coming from the west goes into the outside siding
    • the reed switches should be placed near the start of each siding a foot or so inside of the switches
    • The wires from these reed switches connect to the controller through the Primary and Secondary Siding terminals. The outside siding switch goes to the Secondary terminals and the inside siding switch goes to the Primary terminals.

 

Operation
  1. Place an engine on the center of each siding
  2. Adjust each of the delay time potentiometers to the full counter clockwise position.  This gives about a 3 second delay at the loop stops
  3. Connect the engine power supply to the controller - the green power LED should light
  4. Connect the wall wart power supply to the controller - the red power LED should light
  5. The outside siding engine will power up and exit the siding going East
  6. The inside siding engine will exit the siding going West
 
  
Board Connections
  • Sensors - The four reed switch connections go to the terminals in the lower left area of each side of the board.  They are marked "S" and "L" - the reed switch from the Primary Siding goes to the terminal on the Primary side marked "S" and the unmarked terminal to its left.  The two wires from the loop sensor on the Primary side go to the two terminals on the Primary side marked "L" and the unmarked terminal to its left.  The same is true for the Secondary terminals.  (Note - if you look closely you will see that the unmarked terminals actually have a small "+" on them - this is because they are connected to +5 volts.  The "S" and "L" terminals connect to the microcontrollers.)

 

In this close up you can see the four terminals -

  • Track Power Connections - The track power connections go to the terminals marked "Track" - there is one track connection on the Primary side and one on the Secondary side of the board.  One of terminals is marked "1" and the other is marked "2" - please wire them as shown in the latest track layout plan.  Primary #1 goes to the left (West) side of the track on the outside rail, #2 goes to the inside rail.  On the Secondary side of the layout (East or right side) #1 goes inside rail and #2 to the outside

 

  • Train Power Connection -    The train power goes to the two terminals marked "Train Power" on the Secondary side of the board.  Please note that the connection requires that "+" goes to "+" and "-" to "-".  If you connect the wires properly the green power LED near the connection will light.  If it does not light reverse the wires or change the Forward/Reverse setting on the supply.

  • Board Power Connection - The wall wart power supply plugs into the polarized connector on the Primary side of the board.  When it is plugged in the red power LED will light.

 

Software Version 4.1

' D. Bodnar 7-6-2007
' WORKS with 8 diodes & two processors and Mosfets V2.3
' toggles polarity to track when train hits sensor at either end of reverse loop
' working with two sensors
' This version has a Primary and a Secondary controller - the Primary decides
' when both trains are in the sidings so the power can reverse to start them
'Note: changed to need multiple hits on reed switches to trigger - this is
' designed to filter out glitches - seems better for now
' Random pause time in reverse loop added 7-5-07 V3.6
' Added pot to determine max pause time on pin 2 (porta.3 AN3)

Include "modedefs.bas"
OSCCON = %01100111 'MUST BE USED to set clock speed =$67
cmcon=7 'allows you to use pins as digital rather than analog
ansel=0 'allows you to use pins as digital rather than analog
adcon1=0
adcon1.7=1 'right justify 10 bit adc result - =0 for 8 bit
ansel=9
Define ADC_BITS 10
DEFINe ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

@ DEVICE PIC16F88, INTRC_OSC_NOCLKOUT, WDT_OFF, LVP_OFF, PWRT_ON, PROTECT_ON, BOD_ON
DEFINE OSC 8
OSCCON = $70
'S4_Status var porta.0 'pin 17-Input on primary - Output on sec
'Relay_OK var porta.1 'pin 18-Output on primary - Input on sec
Serial_out var porta.2 'pin 1
MaxDelayPot var porta.3 'pin 2 (AN3 so ADCIN 3, variable is used)
Stop_Relay var porta.4 'pin 3
' var porta.5 'pin 4
' var porta.6 'pin 15
' var porta.7 'pin 16

Motor con 0 'var portb.0 'pin 6
SensorLoop var portb.1 'pin 7
SensorSiding var portb.2 'pin 8
Relay var portb.3 'pin 9
S4_Status var portb.4 'pin 10 s=output p=input
Relay_OK var portb.5 'pin 11 s=input p=output
' var portb.6 'pin 12
' var portb.7 'pin 13

temp var word
temp2 var byte
Rndm var word
RndmTemp var word 'seed - note it is never zeroed and
' increments based on time to sensors
RndDelay var word
RndMax var word 'maximum random time delay
PRIMARY var bit
MotorTop var Word
MotorBottom var word
Freq con 14000 'for PWM
Loop var byte
D_Lay con 3
DecelFlag var bit
AccelFlag var bit
LapCounter var word
SensorLoopCount var byte
SensorSidingCount var byte

PauseMin con 3000
rndmax=10000
DecelFlag =0:accelflag=0
Motorbottom=100
motortop=255
temp=0:lapcounter=0

PRIMARY=1

if primary=1 then trisb=%00010110 'Primary
if primary=0 then trisb=%00100110 'Secondary
'trisb=%00000110
trisa=%00001000

Low relay
if primary=1 then low relay_ok
if primary=0 then low s4_status
pause 300
serout serial_out,n9600,[10,13,"Very Top v4.1 ",#rndmtemp," Random Seed",10,13,10,13,10,13]

high stop_relay
sensorloopcount=0
pause 2000
Gosub accelerate 'start with engine running

if primary=0 then TOP_SECONDARY

TOP_PRIMARY:
random rndmtemp 'random seed
if sensorloop=1 then
serout serial_out,n9600,[10,13,"@ Loop=1 Primary ",#sensorloopcount]
sensorloopcount=sensorloopcount+1
if sensorloopcount>2 then
high relay
serout serial_out,n9600,[10,13,"High Relay"]
pause 30:gosub decelerate2:
'moved line to here for version 4.1
'low relay_ok:decelflag=0:accelflag=0:sensorloopcount=0:SensorSidingCount=0
gosub GetRandom2:
'moved line to here for version 4.1
low relay_ok:decelflag=0:accelflag=0:sensorloopcount=0:SensorSidingCount=0
pause rndmtemp' Pause PauseMin:pause RndDelay
gosub accelerate2
endif
endif

if sensorsiding=1 then
serout serial_out,n9600,[10,13,"@ Siding=1 Primary ",#SensorSidingCount]
SensorSidingCount=SensorSidingCount+1
if SensorSidingCount > 2 then
if decelflag=0 then
gosub decelerate
low Stop_Relay
SensorSidingCount=0
endif
endif
endif
if S4_Status = 1 and decelflag=1 then
serout serial_out,n9600,[10,13,"@ Pause"]
pause 4000 'total pause in crossings
lapcounter=lapcounter+1
serout serial_out,n9600,[10,13,"Laps = ", #lapcounter ]
high relay_ok
Low Relay
if accelflag=0 then
High stop_relay
pause 2000 'arbitrary pause so one goes out first
gosub accelerate
endif
decelflag=0:accelflag=0
goto TOP_PRIMARY
endif
goto TOP_PRIMARY

TOP_SECONDARY:
random rndmtemp 'random seed
if sensorloop=1 then
serout serial_out,n9600,[10,13,"@ Loop=1 Secondary ",#sensorloopcount]
sensorloopcount=sensorloopcount+1
if sensorloopcount>2 then
high relay
serout serial_out,n9600,[10,13,"High Relay"]
low s4_status:accelflag=0:decelflag=0:sensorloopcount=0
pause 30:gosub decelerate2:
gosub GetRandom2:pause rndmtemp' Pause PauseMin:pause RndDelay
gosub accelerate2
endif
endif

if sensorsiding=1 then
serout serial_out,n9600,[10,13,"@ Siding=1 Secondary ",#sensorsidingcount]
SensorSidingCount=SensorSidingCount+1
if SensorSidingCount > 2 then
if decelflag=0 then
gosub decelerate
low stop_relay
sensorsidingcount=0
endif
endif
high s4_status
endif
if relay_ok = 1 and decelflag=1 then
serout serial_out,n9600,[10,13,"Relay_OK=1 and DecelFlag=1 "]
Low Relay
lapcounter=lapcounter+1
serout serial_out,n9600,[10,13,"Laps = ", #lapcounter ]
if accelflag=0 then
high stop_relay
gosub accelerate
endif
decelflag=0 :accelflag=0
goto TOP_SECONDARY
endif
goto TOP_SECONDARY

Decelerate:
serout serial_out,n9600,[10,13,"@ Decelerate ",10,13]
for loop=motortop to motorbottom step -1
hpwm motor, loop, freq
pause d_lay
next loop
hpwm motor ,0,0
decelflag=1 :sensorsidingcount=0
return

Accelerate:
serout serial_out,n9600,[10,13,"@ Accelerate ",10,13]
for loop=Motorbottom to motortop
hpwm motor, loop, freq
pause d_lay:pause d_lay:pause d_lay
next loop
accelflag=1
sensorloopcount=0 :sensorsidingcount=0
return

Decelerate2:
serout serial_out,n9600,[10,13,"@ Decelerate2 ",10,13]
for loop=motortop to motorbottom step -1
hpwm motor, loop, freq
pause d_lay
next loop
hpwm motor ,0,0
return

Accelerate2:
serout serial_out,n9600,[10,13,"@ Accelerate2 ",10,13]
for loop=Motorbottom to motortop
hpwm motor, loop, freq
pause d_lay:pause d_lay:pause d_lay
next loop
return

GetRandom:
random rndm
serout serial_out,n9600,[" R ",#rndm," X ",#rndmax]
if rndm> rndmax then GetRandom:
rnddelay=rndm
return

GetRandom2:
random rndmtemp 'reset seed

adcin 3, RndMax
rndmax=1023-rndmax 'change to adjust for pot wiring
rndmax=rndmax*20+500
if rndmtemp>rndmax then getrandom2:
rndmTemp=RndmTemp+3000
serout serial_out,n9600,[10,13,"random ", #rndmtemp]

return