Model Electronic Railway Group

Leading Model Railway Electronics since 1967

Celebrating 50 years of Innovation: 1967-2017

TCC Resources Page

Last update: 20 July 2005

Howard Amos

Hardware interfacing

There are two fundamental ways you can interface a model railway to a computer: either direct connections, or indirect connections.

Direct connect means running a wire from where a signal originates to where that signal needs to go. Naturally this method uses a great deal of wire, but is easy to understand.

Advantages to direct connect:

  • No 'unnecessary' hardware required.
  • Simple to understand.
  • Cheap

Disadvantages of direct connect:

  • Large bundles of cables
  • Lots of inter-baseboard wires (for segmented, non permenent layouts)
  • Very suceptible to noise from track power picked up on other wires.

Indirect connect uses some kind of multiplexors between source and destination. For example all sensors on a baseboard are directly wired to a multiplexor and a single wire is run to the control panel where a demultiplexor feeds the lamps that the sensors needed to drive.

RPC is one example of an indirect connect implementation. For inputs, sensors and buttons connect to SRI4 modules and track circuiting is handled directly by FTC modules. The RPC stack is a shift register which multiplexes all the inputs onto a single wire and to some kind of demultiplexor which might be a PC, or perhaps an SRO4 module. Outputs from the control logic are multiplexed and sent to output modules on the RPC stack (SRO4, or DPR modules).

Advantages of indirect connect:

  • Most wiring (except track feeds) can be replaced with a single multiplexed line.
  • Tracing through faulty connections is simpler.
  • Rewiring (to reroute a singal to a different location) can be done in software or firmware.
  • Sending signals to multiple destinations, or performing some kind of logic on them (eg. anding two lines together) can all be done in a single programmable device.
  • Signals can be sent further without degradation or noise pickup.

Disadvantages of indirect connect:

  • Uses extra hardware.
  • Higher cost.

Suppliers of indirect connect interfacing hardware.

1. RPC

The kits Gordon supplies (through MERG) meet most of the railway interfacing requirements for most of us. The kits are relatively cheap, and physically compact.

The RPC system is based on a shift register design and adjacent modules are connected by four signals and power. These signals are transmit data, receive data, clock and load. These signals are TTL compatible (short distance only) and are used to interconnect and control the shift register. It is easy to design and build your own hardware (or software) to drive an RPC stack.

The following interfaces are available:

Inputs, for signals coming from sensors and buttons.

These are connected directly to CMOS input pins, with pull-up resistors to 5V. You can use any source that has TTL or 5V CMOS compatible outputs, or sources that are open-collector (such as buttons that pull the inputs to ground).

You should NOT use sources that drive the signals above 5V unless you add some kind of protection circuitry, preferably a resistor and transistor to turn the signal into an open-collector source.

The SRI4 module provides 32 such inputs.

Open-collector outputs.

These can drive LEDs (with series resistors), filament lamps, relays, motors etc provided that the current is within specification. One or two outputs could drive 500mA at the same time, or perhaps all 8 outputs on one chip could drive 250mA.  The loads can be any positive voltage normally found on a model railway (5V, 9V, 12V, 18V, 24V), but should never be negative or over the  maximum rating of the transistor package.

These outputs only pull to ground, they do not source any current.  With two BC177 transistors and two resistors you can drive a tortoise motor from two of these outputs.

The SRO4 module provides 32 of these outputs.

Relay outputs.

Where outputs are required to drive higher currents (up to 1A) the relay cards can be used. The DPR module provides 8 DPDT (double pole, double throw) relays (but does not include the relays), the QPR module provides 8 QPDT (quadruple pole, double throw) relays and relays with 24V coils are included.

These relays are suitable for feeding track power up to G scale, routing signal cables between hardware units and driving motors beyond the scope of the SRO4 modules.

Current detectors (track circuiting).

The FTC module provides 8 current detectors that can be wired in series with track feeds. The FTC inserts three diode drops and so you will lose 2V of power feed to the track. If you are using feedback throttles then connect a 1K resistor across the FTC pins to allow the feedback signal to reach the throttle.

RPC infrastructure (modules apart from basic input and output)

Remote Panel Interface (RPI) module.

These interface a single stack (of as many modules as you require) onto an RS232, RS485 and (soon to be available) USB. These modules (or equivalent) are required if you want to connect to a computer.

Point To Point (PTP)

This unit simply transfers data between two stacks. If, for example you have two stacks, each of which consist of an SRI4 and an SRO4 then when connected by a PTP the 32 inputs (on the SRI4) of one stack are sent to the 32 outputs (on the SRO4) of the other stack. This can be useful for implementing control panels without using the sort of massive wiring loom that would suit a battleship.

Remote Stack Extender (RSE)

These are simply buffer that allow you to physically split a single stack into two separate locations. With one RSE two physical stacks are  joined into one logical stack so an RPI or PTP will treat the two stacks as a single double-sized stack.

2. CTI electronics

The modules that are available from CTI ( are similar to the RPC units in capability, but are ready build and naturally cost rather more.

The modules are connected in an RS232 loop. This has some advantages over the TTL signals used by RPC, especially that modules may be placed a fair distance apart (several metres). As a message circles around the loop each module receives one byte from the message, and relaces it with its input values (if it has any). As the CTI system uses RS232 (9600 baud standard) any hardware with an RS232 interface can be used to build your own modules. If you conform to the message protocol (fully documented on the web) the CTI application software (or my tcc application) will treat your hardware as if it were actually CTI modules.

The modules are all much bigger than the RPC equivalents, and cannot be stacked adjacent (for example the trainbrain module has connectors on three of its sides). They each need a separate power feed cable and links to the adjacent modules.

TrainBrain module - This is the basic interconnect module providing 4 inputs and 4 outputs.  The inputs are similar to the SRI4 module for RPC in that the signal connects directly to 5V logic (actually a PIC chip) with pull-up resistors. Three different plug-in pull-up resistors are supplied so you can chose the best for your sensors. This is useful with LDRs (Light Dependent Resistors) so you can match the resistor to your supply of LDR.

The outputs are SPDT (single pole double throw) relays capable of switching 10 amps. This makes them suitable for controlling solenoid motors (simply connect between a CDU and the motor).

Watchman - A module with 8 inputs and no outputs.

Dash-8 - A module with no inputs and 8 outputs.

Signalman - A module with 16 outputs to drive LED and filament lamps.

SmartCab - This is a computer controlled throttle which drives PWM at low speeds and plain DC at higher settings. This is actually a good module and recommended for those who want computer driven trains without having to build a throttle on breadboard.

3 - Digitrax DCC hardware:

Not having any real experience I cannot say much here, perhaps someone can give me the proper words.

Considering only the indirect connect I/O side, the system looks like this:

Output from the PC is mixed with the output from the hand-held controllers to produce the basic DCC signal. This may then be fed through boosters to generate sufficient current capacity for your layout. The boosted signal is fed through track circuit modules (BDL-16 ??) to feed the tracks. Accessory decoders are fed from the track to generate outputs to drive whatever hardware you have - turnout motors, signal lamps etc. The DCC signal is only used for outputs.

Inputs are handled over a separate network: 'LocoNet'. For example the BDL-16s (current detectors) connect to the PC via LocoNet and allow application software to receive the track circuiting information.

If you wanted to write software to interface to Digitrax DCC hardware you would need to write two, very different pieces of software: one to generate the data to send to the DCC hardware, and also one to send and receive packets on LocoNet. Although DCC is harder to connect to it does have the advantage that the throttles are migrated into the locos, and this does simplify track power feeds (even though you still need to section your track for track circuiting).

Power feed

There are many ways to feed power to your tracks. With classic switched control panels the natural method is to run wires from your throttle(s) to the switches on the control panel and then a wire from each power switch to its associated track section. This naturally uses a lot of wire, and makes lots of thick cable bundles to route around.

An alternative is to run a 'ring main' from each throttle around your layout and then route power as required to each track section with relays. If the wire from each throttle runs around the whole layout and then back to the throttle (if it makes sense in your installation) then you can use thinner wire because current can flow both ways around the loop. The relays are of course controlled from the switches on the control panel, but to save wiring you can use RPC modules, with either a PC or a ??? module to drive the relays from the switch settings. This way you have far less wiring, and if you want to add an extra track you only have to connect an extra relay to the appropriate ring main(s).

I will confess that I have my power switching relays next to the throttles and run wiring out to each track, but if I were starting again I would put a relay card under each baseboard area.

Cable types

Track power requires cables that will not drop too many volts. A drop of 1 volt is the maximum you should be prepared to accept, but there is little reason to demand as low as 0.25V. Aim at an average section dropping half a volt, but tolerate 1V on the longest runs with double headed trains.

The volt drop depends upon three parameters:

  1. 1. The current being drawn
  2. The length of the wire
  3. The thickness of the wire

The current varies a little between locos, and a little with speed, but mainly it is the scale you are using that defines current. Some starting point assumptions might look like:

Scale Slow speed Full speed Stalled
Z 80mA 250mA 400mA
N 100mA 300mA 600mA
00 150mA 400mA 800mA
G 400mA 800mA 1200mA

But these are all approximate and will vary between locos, track and throttles. You do NOT need to design for stall current, except to ensure that your wires will not melt - do not worry about this even ribbon cable will not melt on a stalled G scale loco.

The length of each run is obviously a function of your particular installation and I cannot give you any guidance at all on this one.

The other variable is obviously the thickness of the wire. Thicker wire costs more, is harder to install and make much bigger bundles. Think carefully before jumping in with wire that is thicker than you really need.

To calculate what thickness of wire you need:

V is the acceptable volt drop you are prepared to tolerate. Start with half a volt. If you don't know then try an experiment with a throttle, some thin wire (rated at less than your loco consumes), a loco and a voltmeter. See how much volt drop you can insert (by adding more and more thin wire) before loco behaviour degrades. Pick a volt drop perhaps half of the drop where you can actually notice a performance change.

I is the current you need to handle, in amps. Take the figure for full speed running (not the stall figure). Double it if you plan on double heading (but on the other hand does it matter if you get more volt drop with a double-headed train??) You could try measuring the running current taken by your lococs. Do NOT measure the motor resistance to calculate current - this does not work.

L is the length (in metres) of the average wire from throttle to track. Allow exceptionally long runs to have a little more volt drop than is ideal.

R is the maximum resistance of the cable run, calculated from: R = V/I
eg. 0.5V with 400mA (00 scale loco) gives R = 0.5/0.4 = 1.25 ohms

r is the resistivity (in ohms per meter) of the cable you need: r = R/L
eg. 10m cable gives r = 1.25/10 = 0.125 ohms per meter.

Now pick a cable or wire with that resistivity or less.

No of strands/diameter (type) AWG ohms per meter
1/0.52 24   0.094
1/0.55     0.070
7/0.1   0.055 0.384
7/0.13 (ribbon cable)   0.08 0.227
7/0.2 (ribbon cable)   0.22 0.092
19/0.127   0.25 0.0836
19/0.15   0.35 0.0561
19/0.19   0.5 0.0401
19/0.25   0.933 0.0212

I use ribbon cable on N scale and so I need 300mA and my runs are typically 6m.

Working the other way around my volt drop would be:

V = I*R = I * r * L = 0.3 * 0.227 * 6 = 0.4V

Which I consider perfectly acceptable.

Of course if you were to use a "ring-main" of ribbon cable, then you could clamp on a connector at any point to tap off power to a relay board. The resistance would then be halved (worst case). For example a layout in a room 3m by 4m might use a ring-main 14m long (the circumference of the room). The worst-case run from throttle to track is two 7m lengths in parallel. If you were using some double headed trains in 00 scale then the volt-drop would be:

V = I*2 * r * L/2 = 0.4*2 * 0.227 * 7/2 = 0.635V

which might be considered acceptable for the double headed trains.

Of course garden railways need much thicker cable. The currents are larger and the cable runs much longer. Suppose a typical length was 20m and we were double-heading and so wanted to supply 1.6A, but accepted a full 1V drop (G scale throttles have more volts to play with than OO throttles) then:

r = V / I / L = 1 / 1.6 / 20 = 0.031 ohms per meter

and so you might need a 19/0.25 or 32/0.2 wire.

3.1 - Power Routing

Having decided whether you are using switches or relays, and the type of wire you need you can consider what the circuit diagram might look like.

If each section is either on or off, then it is simple - the switch or relay is in series with the track.

If each section can be fed from several throttles, perhaps each operator has a throttle and some sections can be fed from any of two or three operators then you need to select which throttle feeds the track.

throttle 1 -------o
throttle 2 -------o <---o
                     |    <----- track
throttle 3 -------o <---o
                --o rl1   rl2

Operating together two relays rl1 and rl2 can route one of three throttles to the track, or disconnect the track. rl1 is a DPDT (double pole, double throw), rl2 needs to be only SPDT (single pole), but naturally you'll probably use a DPDT and ignore the second contacts.

Adding a QPDT relay you can extend the circuit to support 7 throttles.

A 'nice' user interface might be for an operator console to have a button and lamp against each track he can control. Pressing the button causes his power to be fed to the specified track, and the lamp is lit. Pressing it again disconnects power and the lamp goes out. If another operator selects the same track then either he 'takes over' that track, or is refused (according to your requirements). A simple computer script could handle this (for a single track section, using the circuit diagram above):


{ the three operators 'requesting' a given track }

button1, button2, button3


rl1, rl2 { the two relays }

lamp1, lamp2, lamp3 { power indicator lamp for each operator }


currentOp { 0=off, 1, 2, 3 = selected operator }


WHEN currentOp = 0 DO rl1=0, rl2=0 { switch off when not in use }

lamp1=0, lamp2=0, lamp3=0

WHEN currentOp = 1 DO rl1=1,rl2=1 { route power from operator 1 }

lamp1=1, lamp2=0, lamp3=0

WHEN currentOp = 2 DO rl1=0, rl2=1 { route power from operator 2 }

lamp1=0, lamp2=1, lamp3=0

WHEN currentOp = 3 DO rl1=1, rl2=0 { route power from operator 3 }

lamp1=0, lamp2=0, lamp3=1

WHEN button1=1, currentOp<>1 DO currentOp=1 { operator 1 requests }

WHEN button2=1, currentOp<>2 DO currentOp=2 { operator 2 requests }

WHEN button3=1, currentOp<>3 DO currentOp=3 { operator 3 requests }

WHEN button1=1, currentOp=1

OR button2=1, currentOp=2

OR button2=1, currentOp=2 DO currentOp=0  { disconnect power }

Of course you could combine the WHEN button statements with the WHEN currentOp statements (thus halving the program), but I prefer to segregate GUI input handling (monitoring buttons), from driving the layout because it allows you to add other automatic logic later to change currentOp without worrying about what it drives. For example an automatic train routing program could decide which sections are to be controlled by which operator and then route the power automatically (if the operator was available).

Doing this type of user interface in hardware is quite possible, but it requires some logic gates. If you do it in logic it is of course harder to add an extra console later, whereas it is of course extremely easy to add one if a computer were acting as intelligent logic gates.

If the system is computer driven then the same relay diagram shown above can be used to route power from compter controlled throttles. You can route all your throttles to each section of track (for pure cab control). If you have plans for growth however that might get very difficult, so I use zone control where each throttle feeds only a few adjacent sections, and each section is fed from two or three throttles and the computer changes throttle as the train goes around the layout.

If you want to mix DC and DCC then one of the throttle inputs could of course be a DCC feed. The computer would have to be told which trains are DCC and which are DC, and then route appropriate power for each train. This sort of control would be no harder than the zone control that I do, or regular cab control. The only difference is that all DCC trains can share the same throttle feed to the relays. Ideally it would be possible to automatically detect whether a loco is DC or DCC, but I don't know of a method to do that.

Manual fallback

If your computer breaks, if your software is buggy, or if you simply want to sometimes have a fully manual session then it is possible to build a system that supports both worlds.

Assuming that you have taken my advice and used RPC modules for all layout interfacing (power routing, turnout drive, signal drive, sensor inputs etc) then the RPC stack could be connected to either a control panel (using a PTP module) or to a computer (using an RPI or equivalent).

With a PTP, switches on the control panel could drive turnouts (the switch connects to an SRI4 input and its corresponding SRO4 output connects to a PMD module to drive the solenoid motor), switch power to tracks (the output is a relay on a DPR that actually switches the power), turns on lights (the SRO4 can drive lights directly) for example. Also sensors connected to SRI4 inputs under the layout can drive lights on the control panel by using an SRO4 on the panel.

OK, thats too simple I hear you say - I want three control panels to control different areas of the layout. Well you could have three RPC stacks linked to their respective control panels with separate PTP modules. When you want computer mode then you unplug the PTPs and plug in three RS485 RPIs.

Ah, but I want some parts of the layout to be controlled from two (or more) control panels - that is having an overlap between panels. OK thats harder, but its harder to do with any non-computer assisted system. The best bet here is to have an intelligent multi-way PTP that can take inputs from several control panels (possibly linked by RSEs) and can apply some logical expressions to the inputs and route these outputs to the layout as required. Sorry such a module does not yet exist - but its easy to implement with a PC.

The great thing about this possibility is that you can have your cake and eat it. In fact the hardware gives you three modes of operation:

  1. Full PC assist. The computer controls whatever you program it to control.
  2. Intelligent panel routing. the computer controls nothing but simply acts as an intelligent signal router, allowing overlap and interworkiing between control panels.
  3. Non computer mode. Rip out the RPIs and replace with PTPs. If all your computers explode you can quickly drop back to the 'old' way of working.

I suggest that with these options, such an RPC-based layout is ideal for many clubs as it allows everybody to have their way. You can have different evenings for different interests without having to do any rewiring of the layout. Once a layout is equipped with RPC modules (or any equivalent, such as CTI for that matter) then you open up the operating horizons and I suspect that there are other possibilities I have not thought about yet.

Device Driver Software

First of all, what is a device driver and why are people interested in them?

Basically a device driver is a separate program that can communicate with any application that supports the appropriate programming interface.

The most common device driver is probably a printer driver. Each operating system provides a set of application services related to printing (such as list available printers, open a printer connection, send data etc). That is the application side of printing and has no relationship to the print drivers themselves. The OS also defines a standard way for the print driver programs to register themselves and receive the data that an application wants to print.

At startup all the available printer drivers make themselves known to the operating system (well, actually its really the other way around, but thats not important here). The OS therefore compiles a list of available printers (it assumes that each print driver has a physical printer attached). When a user selects 'print setup...' from the menu the list of printer is made available for the user to select which printer to use, and what settings to give it. The application knows nothing about the individual printers - the different printer configuration GUIs are displayed by the printer drivers themselves when the application asks the OS to handle the 'printer setup...' function.

As the interface between a printer driver and the OS (and hence the application) is well defined for any given operating system, anyone could write their own print driver if they felt so inclined.

For model railway interfacing there is of course no operating system defined standard, and the link would be directly between application and device driver. Such an interface is called an 'API' (Application Programming Interface) and defines a set of subroutines that the device driver must support, and the mechanism by which it connects to the application.

One mechanism is the 'MRAPI' (Model Railway API) that Graham Plowman uses in his SSI software. Whether this proves to be a generic API suitable for use between various applications and railway hardware remains to be seen as SSI is the only software implementing MRAPI. The mechanism Graham uses to link the device driver to the application is the Windows DLL system. This of course ties MRAPI to only the windows environment.

Most model railway software (commercial and private) doesn't use dynamically linked device drivers at all, but proprietary software built into the application. This makes the software a little easier to develop, but it means that the software cannot be extended by other people (by adding for example support for RPC hardware).

There are many mechanisms that can be used to link device drivers and applications, among them are:

  1. Statically linked (code built-in at compile/link time)
  2. Dynamically linked (Windows DLL, Unix shared libraries)
  3. Java Beans (similar to dynamic linking, but more flexible)
  4. Networked socket connections

The network socket connection mechanism warrants special consideration. The other three methods all assume that the hardware is connected to the one machine that the application is running on. If, however the various parts of the application all communicate with network (ie. ethernet) sockets then your application is much more adaptable.

The various 'parts' I refer to would be:

  1. Serial ports, USB etc, and associated device driver.
  2. Application core
  3. Each individual window that makes up the GUI

With such an arrangement you could use the screens of several computers (probably to display mimic panels for each operator), and even split the interface hardware between the different machines. Although this sounds really advanced, it can actually be quite simple to program.

Performance needn't suffer, in fact it could easily improve as serial port devices, and GUIs are both significant CPU consumers.

With more advanced application cores the processing couls also be distributed among the various systems, further increasing performance, and reducing the problems should one computer break down - you simply move its interface cable to a spare port on another machine, and move that portion of processing also. Such distributed railway control applications are some way in the future though, so don't hold your breath.

The significant message of this section is: if an application supports external (non statically-linked) device drivers, and the interface is published then it is possible for you to adapt that application for your own hardware if you can write a device driver that conforms to the published specification.

If you want to use an application that doesn't support external device drivers with a published interface and you want to use hardware they don't currently support then you only have three choices:

  1. Be happy with the hardware they already support.
  2. Build yourself an adaptor from the interface standard they do support, to the one you want. This can be difficult if the interface they support isn't documented either.
  3. Write yourself an application that does all the functions you require, possible mimicing your chosen commercial software, but supporting the hardware you want to use.
  4. The fourth option (hastle the software authors to add your hardware choice) isn't really a viable option - hence the list of only three options.

I followed this route at first by making an adaptor from the CTI serial interface loop to an RPC stack. Unfortunately adding this adaptor had a noticable performance degradation, but at least it allowed me to use hardware that I could afford. The only way I could break free from using such an adaptor was to write my own software that duplicated all the functions I wanted of the software I had chosen.


Interlocking, named from the mechanical interlocks on older signal boxes is the process of ensuring that turnouts and signals cannot be set in a manner that permits collisions (assuming of course that the train drivers can see the signals and that they also obey the signals).

In the early days of interlocking the signalman functioned as the local controller. He was the 'computer' following a pre-defined multi-threaded 'program' (the timetable). He acted on sensor input (his eyes, possibly track-based detectors, and messages from adjacent controllers). Having processed the inputs in accordance with the program the signalman generated outputs in the form of setting levers and sending messages to other signalmen.

Ok, I accept that this description makes the signalman's job sound like an automaton, but thats exactly what it was - only it required a lot more intelligence and training than most factory workers because the signalmans program was multi-threaded (one thread for each train approaching his area, in his area, or departing his area) whereas a factory workers task were (and are) often single threaded (follows a single set of instructions from start to finish, then starts again).

Modern signal boxes are no different really. Sure the levers have turned into tiny switches, and then have turned into touch sensitive computer screens. The mechanical interlocking is now just data in a computer. The signalman can now be a true automaton - he can let the computer handle everything. The signalman only takes over if he wants something to do, or if things get a bit hectic for the computer to handle (like last minute rescheduling or some other excitement).

A model railway can (and should) immitate this interlocking in some way. You can of course build mechanical interlocking into a miniature set of levers that control turnouts and signals, but that is a skill way beyond most of us. Most model railways are interlocked purely by human overseers, but then of course they are restricted to only having a couple of trains moving at a time.

These notes, however are targeted at assisted layouts where some kind of inanimate computer plays some role which probably includes interlocking. Interlocking is just one layer in a multilayer jungle and the implementation of interlocking depends upon what other layers are being automated.

Interlocking requires input from higher layers (the timetable, or equivalent) and from lower layers (the track sensors). It might even have input from peers (other interlock systems handling different parts of the layout). The outputs obviously have to control turnouts and signals and might also control train speeds, where trains stop and isolate sections of track to prevent errors. A purist would say that the interlocker only controls the signals, and the signals control trains stopping and dead sections. Well that's true, but if you haven't got any signals and you have interlocking controlling virtual signals that control the track, then is there any difference. In a timetabled and route-planned system (such as the prototype) the required routes and timings are known in advance and typically the system will reserve several blocks of track for a moving train. In a non timetabled system where train movements are decided as the train moves around the track the interlocking will cover the smallest possible movement and pass the train onto the next section.

So in short the higher layer input into the interlocking software could come from one or more of three sources:

  1. A timetable (prototypical)
  2. Local track routing decisions (random decision maker)
  3. Human interface (on-the-spot decisions where to send your trains)

And of course each local control area (what used to be a local signalbox) can take input from different sources if you wish.

Internally, an interlocking function needs to keep track of which track sections are in use, for which trains, and exactly where those trains are. Knowing where the trains are is the task of the train follower (section 7) and this knowledge is the input we need from the lower levels.

There are of course many ways of keeping track of which sections are in use for each train, where each train is going etc, but the way I choose to do it is as follows:

Each section of track has a state, and is associated with one train. The train association is described in section 7 - the train follower.

When the track section is not in use, and is not expecting a train its state is 'Free'.

When a section needs to be be reserved for a train expected soon, then the state is set to 'Booked'.

Further states depends upon what sensors you are using and whether the computer is driving the trains. The following list may seem to be more states than absolutely necessary, but they all help ensure that collisions are avoided.

When a train is detected entering a section, preferably with an optical sensor then the section is said to be 'Arriving'. When a section enters the arriving state we need to ensure that the next section down the line can be booked for us, otherwise the train will have to start decellerating and stop before the end of the section.

When a train is wholly within a section, and not overlapping either adjacent section then the section can be 'Occupied'. This indicates to the previous section that the train has safely departed and that previous section is now Free for use by another train.

When a train has started leaving the section, and also is no longer entering, it can be labelled 'Departing'. Departing, like Occupied tells the previous section it is now free. If a train that is longer than the track section passes, then the track section will go from Arriving to Departing without ever entering Occupied state because the train was never wholly within the section. I accept that this behaviour is utterly non-prototypical (or at least I assume it is), because on a model the track is foreshortened much more than the trains are, and so it is usually impractical to ensure that trains fit within all track sections.

You can simplify this whole state machine to just Free and Booked if you only use track circuiting and have conductive axles. If the computer is driving the trains then you need to keep a whole track section free between trains, and train must slow down and stop as soon as they are detected entering a section.

I have not separated the train following code from the collision avoidance/interlocking code, but if you only want one or the other the two functions are separable.

Although I appreciate that nearly everybody has different ideas, requirements and procedures for a model railway I believe that representing the functions you require in the script language I use can give you a real insight into how you actually want your layout to behave.

Quad Throttle


The QTU is a throttle circuit to function as four throttles. The four circuits can be linked or independent.

They can be:

  1. Plain voltage controlled.
  2. Feedback controlled.
  3. Fully manually controlled as a conventional throttle.
  4. Semi-manual or autonomous like BloNg/SuperBloc/BC3
  5. Fully autonomous, including auto route setting.
  6. Computer controlled.
  7. Any mixture of the above.

The circuit uses a microcontroller to provide the required intelligence, and this replaces some of the normal analogue circuitry found in feedbackthrottles.

The microcontroller used is an Atmel AVR 90S8535 that runs at 8MHz and provides 8 MIPS (million intructions per second).

Controls can arrive from any of the following:

  1. Local potentiometers connected to any of the 8 user-defined analogue input lines. These can be used as speed control, inertia setting or station stop controls.
  2. Local switches connected to any of the 32 input lines. These can act as brake, reversing, or any function that can be configured within the unit.
  3. Link wires from adjacent units (BloNg-like) on the same input lines.
  4. Data received over any of the 8 serial comms lines from adjacent units (this function not implemented in firmware yet).
  5. Data received from a computer on RS232, RS485 or uplink RPC stack.
  6. Data received from a control panel via RPC PTP.
  7. Decisions made using the internal user-defined logic functions.

Circuit Description

Page 1: 8535 (download .pdf diagram)

Obviously the main component on this page is the microcontroller. It has an 8MHz resonator attached, and drives three LEDs. These LEDs are used to indicate:

LED1: An error has occurred, most likely in decoding a message from RS232, RS485 or the uplink RPC stack.

LED2: Each time a message is correctly received this LED changes state. So when the unit is controlled by a computer or some RPC stack master the LED should flash continuously.

LED3: This LED changes state each time all of the configurable equations have been executed.

PL3/IC3 connect 8 user-defined analogue inputs to the ADC (Analogue to Digital Converter) in the processor.

PL4 and the attached resistors are the 8 bi-directional serial links for connecting adjacent units together in a system that can pass train speed settings from throttle to throttle.

IC6 (optional) extends the space available for the user-defined equations. The processor has a 512 byte EEPROM.

SW1 defines the RS485 address that the QTU responds to.

PL1 is the upstream (towards the computer, RPI or PTP) RPC stack interface.

PL2 is the downstream RPC stack interface. It can have any other RPC modules attached, including other QTUs.

ISP1 allows the microcontroller to be reprogrammed without removing it from the board.

Q1 functions a a brown-out detector and resets the controller when power is applied, or if the power level drops unexpectedly.

IC7, IC8 and SK1-SK3 are the RS-485 interface. Three connectors are provided to allow very flexible interconnect. Typically you might have a chain of QTU units around a layout, but the third socket allows some to be mounted as spurs off the main chain.

IC9 and SK7 are the optional RS232 connection. Typically only one of these is required in a computer controlled layout, other QTUs being connected over RS485 and more QTUs and/or other RPC modules being connected to the downstream stack of the others.

Note that AC power is connected to two of the three RS485 connectors. This is NOT intended to imply that main track power is distributed over RJ45 connectors, this is not the case. This power feed is only intended to support single wire control panels.

Page 2: Input/Output (download .pdf diagram)

PL5, 6, 7, 8 and IC19, 20, 21, 22 are in essense an SRI4 module that provide 32 general purpose input lines. These are polled every millisecond by the microcontroller and are used as inputs to the user-defined equations.

IC11 to IC16 are three quarters of an SRO4-like circuit. These 24 lines are general purpose outputs. The other 8 lines are on page 3.

Two or four of the 24 lines may be used to drive one or two Tortoise turnout motors directly. Q2 and Q3 (and the second copy of this circuit) turn the open-collector outputs into full push-pull outputs to provide full reversing of the drive motor, but are current limited (by the 180K resistor and the transistor gain).

Page 3: Power supply and throttle output. (download .pdf diagram)

CN1 is the main 15V AC power feed. From this the following supplies are derived:

BR1 generates a rectified but unsmoothed DC which is the main loco power.

D1, C1 produce the main smoothed power, around 22V DC. IC23 regulates this down to 12V for the relays and off-board DPR modules. If you prefer 24V relays then omit IC23 and link its pin1 to pin3.

IC24 produces a regulated 5V for the logic chips and attached RPC stack modules.

C22, C23, D2, D3 are a voltage doubler, then Q6 regulates this down to V+ plus around 3V, to feed the op-amps. The idea is to feed the op-amps a few volts higher than the peak output voltage. This is because the op-amp output is limited to its supply minus 2V. Also the output transistor further reduces the possible track voltage by its Vbe (another 1.2V).

D4, C24 produce a suitable +ve bias for any attached FTC modules.

D5, D6, C25, C26 (another voltage doubler) produce a -ve bias for FTC modules.

D7, D8 produce a separate rectified AC that is fed into a comparator in the microcontroller, and the output is used as a zero-crossing interrupt to synchronise the output circuits.

PL13 makes all the above power supplies available to off-board modules.

IC17, 18 are the last 8 bits of the on-board SRO4. 4 bits are used as reversing relay drivers, and the other 4 bits drive user-accessible relays. In other words the QTU contains half a DPR module.

IC10 is a four-channel DAC (Digital to Analogue Converter). The four output voltages drive four identical throttle output circuits:

IC25a and TR100 are a simple throttle output circuit. The output voltage (after R105) is fed back to the op-amp which maintains the output voltage to the level set by the DAC.

R105 and Q101 form a conventional current limiter. R105 is chosen to suit the current used by your locos. The unit should suit any scale from Z to G.

The attenuated track voltage is fed to IC2 (an analogue multiplexor) so that the micro can sample the track voltage to measure feedback volts.

R101 measures the track current. The voltage dropped across R101 is duplicated across R102 by IC25b. The current through R102 is the same as the current through R103. Therefore the voltage across R103 is proportional to the current fed to the track. This allows the micro to monitor current consumption - to both detect current flow and provide foldback protection if a motor stalls. Note that this current detector is before the throttle output transistor and therefore inserts no voltage drop to the track (unlike an FTC module which drops over 3V).

Modular Control

You can download the following files described in this section:

Disclaimer: The following text is just a memory-dump. It has not been reviewed, checked or tested. It may appear to be designed to instill maximum confusion but I can assure you that the second neuron was offline when I wrote this and so sufficient organisation to deliberately create chaos was unavailable.

Warranty: None. This software has been used on my layout, but nowhere else yet. It is not finished, tested or whatever. It does however operate, and for me it does not crash. For you it will crash even quicker than windows - for that is the nature of alpha testing software. If it crashes the error output should be in stderr.txt - I would welcome such crash dumps and will try to fix the problems.

Support: No guarantees. I wrote this software for my own use and currently have no plans for any kind of commercial exploitation, but am happy for others to benefit from my labours. I will try to fix any problems you may find or add new facilities that strike me as interesting.

Compatibility: Currently the set of CTI modules are supported, though I've only tested TrainBrain and SmartCab modules. Merg (RPC) modules are supported if connected through a simplified RPI that uses no message types or checksum. I can send you code if you want to make one. MERG modules will be supported using Gordons RPIs when I can get around to adding the extra message header and checksum. The following merg modules are understood: FTC, DPR, SRO4, SRI4. QPRs are the same as DPRs as far as the stack is concerned - so select DPR. SRO4s are split into four 8-bit bytes (just as the board is). Each byte can be either 8 individual outputs, an 8-bit throttle (with direction connected elsewhere) or a 7-bit throttle and bit7 selecting reverse. If I have sufficient motivation, or should anyone else want to have a go then other message protocols can easily be added - its just a matter of creating a new subclass of serial interface and a set of tree nodes for the GUI. Tcc does not yet implement software intertia on throttles - that's coming soon.


tcc.jar is a java archive of tcc, my Train Control Centre application software.

To run it you'll need JRE1.3 (5.3Mbyte)( and Java communication API (270K) (

And then run the application: java -jar tcc.jar ha1.tcl

The file ha1.tcl is the script I am using on my layout (for a diagram see merg1.sdt [star-office] or MERG1.ppt [powerpoint, but much larger file]).

This presentation also explains the basic philosophy adopted by ha1.tcl, and the states used by tracks sections, and how they inter-relate. Note that this is merely how I chose to use the scripting language - you can make much simpler and completely different setups according to your needs and skills.

tcc should open a desktop window with several other windows opening automatically. This window configuration is saved in ha1.tcp when tcc exits.

The menu bar:

  • File/Open: Currently only extracts saved CTC data. This does NOT open .tcl scripts yet.
  • File/Save: Saves an extra copy of the CTC windows to the named file. CTC contents are saved automatically to file.tcp when tcc exits.
  • File/Exit: Same as closing the desktop window: Save configuration to tcc.tcp, file.tcp and exit.
  • Edit: Not used
  • View/Variables,Sensors,Control,Throttles,CTC,Tracks,Log: opens windows listed below.
  • Configure/Hardware: Opens the serial port and stack hardware configuration window.
  • Configure/Log: Define what script tracing to use.
  • Reset: Clear all variables. Script will start again as if tcc was exited and re-entered. Leaves serial ports running (but of course all control outputs will be zero). Clears dynamic CTC contents.
  • Run: Start running the script. This is a button, not a menu.
  • Stop: (alternates with run) Stops the running script.
  • Step: Execute a single pass through the script.

The windows:

  • Variables: A table of the variables used in the .tcl script. They are grouped into rows according to instructions in GROUP: statements in the .tcl script. See below for a discussion of variable names, and how they are arranged in groups. Variable names and column headings are not editable, other values are. Plain integer values are displayed as numbers. Colours, addresses, constants, times etc are shown symbolically. Values can only be set to numeric values, by entering a new value in the appropriate cell.
  • Sensors: A table of all sensor inputs received from the hardware. When the serial ports are not running you can click on the boxes to set sensor data manually.
  • Controls: A table of all control outputs available to be sent to the hardware. You can click on the boxes to set values. This works whether or not the script is running, and whether or not the serial ports are running (though naturally the values are not actually sent if the ports are offline).
  • Thottles: One row for each throttle, containing name, speed, direction, brake and momentum. Speed and momentum are currently plain integer fields.
  • CTC panels: A grid of cells that can show layout plans or other information.
  • Tracks: The pallette for editing CTC panels (when the script is stopped). Symbols for straight and curved track, left and right turnouts, and crossings are available. Click on the cell in the pallette and then on a cell in a CTC panel. The orientation of the symbol placed in the CTC panel depends upon where you click in that cell. The top-left corner of the pallette symbol is oriented in whichever corner or side you click in. Experiment and all will become clear. The "abc" pallette entry allows fixed text to be placed on the CTC panel. The "B" entry allows track segments to be formed into groups for the $COLOR BLOCK statement. The blank pallette allows tracks to be deleted.
  • Log: Error messages and debug output. This window is copied to tcc.txt.
  • Log Config: Determines whether to trace the running of the .tcl script, and what level of detail to produce.

  • Qkeys: An auto-arranging collection of buttons that can be monitored by the script.
  • Hardware: A tree (similar to windows explorer) showing the serial port configuration.
  • Top level: the tree root - ignore this.
  • Level 2: Interfaces - one entry per serial port being driven. The NewInterface cell is a pop-up menu to define new interfaces
  • Level 3: Interface state, port parameters, module stacks on that interface
  • Stack module level: Each CTI or MERG module connected to the port.
  • Signal level: The name of the signal connected to each pin of the module.

Many nodes are pop-ups to change their values.

Some nodes can be deleted with the del key.

Some nodes can be dragged to reseqence them.

Apart from the delete key, no keyboard interaction is possible with this window.

CTC panels used by ha1.tcl

  • CTC1: The main track layout. Track sections become coloured to show occupancy and state. The first segment of a section is coloured for train arriving, all segments for occupied, or stopped. The last segment for train departing.
  • CTC2: The train state display. Each train gets a line on the panel. The straight line is coloured to show which colour this train uses on CTC1. (this uses the standard resistor colour coding scheme). Immediately to the right of the line is shown the train type - but at startup these are all blank. Click in one of the four cells to the right of the line to set train types. Next is shown the throttle settings for slow (min speed) and full speed. Left click reduces and right click increases these values.
  • CTC3: Shows momentum settings to be used for acceleration and braking. The next line shows error messages from the script (such as sensor missed when a train enters a section). The last line shows messages from the train speed auto-recalibration code. Certain sections measure the speed of the train and determine whether the train is going too fast or too slow for its particular type (express trains are expected to go faster than goods trains etc).

Variable naming

The group function allows related variables (or sensors or controls) to be shown on a single line of the variables window. Such variables must be named according to the following rules:

  • Name = <prefix> <suffix>
  • Prefix = function of the variable
  • Suffix = code module or track section the variable applies to

For example I use prefix="s" for status variables, "t" for train numbers.

Suffix "L9" refers to track section L9. So sL9 is the status of track section L9. All the *L9 variables are on one line, *L10 on another line and so on.

The prefixes are listed along the top of the variables window, the suffixes down the side.

Running a script without having any hardware connected: You can run a script without hardware (or simply by having the serial ports disabled) to debug your script. Simply control the sensor data in the sensor window by clicking on the boxes.

Sample session with ha1.tcl: Reading the presentation (merg1.sdp or MERG1.ppt) will help understand this.

  • Select CurL9 and OptOL9. Click run.
  • You will see rcL9 activate (feeding power to that track section), also rcL8 (the next section prepares to receive the train). Throttle 6 will begin increasing speed, in reverse direction (the train has stopped at the end of the section, covering the exit sensor OptOL9 and is reversing until the sensor is clear).
  • Clear OptOL9 to signify that the train has started moving. The throttle will stop, brake, and change to forward. (Also note the brown colouring on CTC1 illustrating the location of train 1.)
  • The throttle setting when OptOL9 went clear is shown on CTC2 as the min speed for train 1. Full speed is set 5 higher.
  • Do the following:
  • OptOL9 on: The train reaches the end of L9. sL9 changes to departing.
  • OptL8 on: The train enters L8. sL8 changes from Booked to Arriving.
  • CurL9 off, OptOL9 off, CurL8 on: The train is moving into L8
  • OptL8 off: The train is fully in L8, sL8 becomes Occupied.
  • Repeat the sensor changes as the train traverses L8, L7, and enters L6.

Note that TI4 has become booked for the train and is shown set straight on the CTC.

When the train enters L5 note that TO3 has selected which route the train will take next, and either L3 or L4 will be booked. Take care to click the correct entry sensor, or else you will get an error message in CTC3.

If you managed to get a single train around the loop then try it with two or three trains. It gets fun (read confusing) to do that manually.

The script is currently configured to support upto 6 trains - because that's really the operation limit for the layout as it currently stands. If you want many more then the biggest problem is having enough easily recognised colours for the CTC panel.

The .tdl file

ha1.tdl is the file I actually create manually. It defines the connectivity between track sections, which stacks sensors and controls are connected to, how long the tracks are, which throttles are wired to them and where on the CTC panels the tracks are displayed. I have a collection of scripts which run on a unix box that helps me make the .tcl file for the style of operation I use. They will not run on Windoze. They are also very large and relatively incomprehensible. If you want to use the same style of full computer control then you are welcome to send me a .tdl file and I'll send you back a .tcl file that implements your specified layout.

Naturally I'll have to create a formal .tdl definition first.

Modular scripting

In concept, my scripts tie together modules of code for each type of track section and build a .tcl script automatically. In reality the scripts and the modules are all intertwined and inseparable. They are only useable for the full automation, dual optical detection mechanism philosophy I have adopted.

If anyone is interested in making a generic script builder that can be used for any operating style then I can certainly recommend an approach that would permit different sets of modules to be used for different operating styles, but use the same script builder and same application code. Note that you cannot see separated 'modules' within ha1.tcl because I have grouped similar function together to improve readability.

Of course there's nothing wrong with writing .tcl script manually, as documented by CTI for TrainBrain.

Differences between tcc .tcl and TrainBrain .tcl, tcc does not yet support:

  1. icons on CTC panels
  2. sounds
  3. probably some odd functions I have never used.

I have not tested signal outputs. For CTI hardware signals go to special hardware and I do not have any. For merg modules there is no fundamental difference between controls and signals - but I will add support for multi-bit signals sometime (like when I get around to adding signals to my layout!).

Additional in tcc .tcl scripts:

  1. Group statements for arranging data in variables windows.
  2. Constants - to avoid using unnamed literals everywhere.

Planned additions

  1. Arrays. You will see a lot of constructs like: s=&tc1, s=-, s=tL9+, *s=1 I want to change this into: tc[tL9]=1
  2. Sounds from WAV files and CD tracks (that can play through relays routing the signal to loadspeakers hidden under tracks or in tunnels).
  3. Inertia for MERG throttles (computer controlled throttles connected to SRO4 modules - see TB G16/51)
  4. Loading and editing .tcl scripts within tcc. Currently if you want to edit the script you have to quit, edit the file and start up again.

TCC Software

Download the main application software here



Tcc.CTC.problem.txt - 05 Dec 2004 -Rodney Hills M1301  Re:{MERG] Tcc V1.4 Save-CTC issue

This document has two parts:

Part 1 - Warning- as per MERG e-group posting.

Part 2 - Workarounds - Tcc Usage recommendations.

Part 1 - Warning

This is aimed at the subset of members that are actually using Howard Amos's Tcc software.

By now you have likely migrated from earlier versions to the V1.4 "general release version" that was loaded to the MERG yahoo-group site. As per various postings dated 18,19,20 Oct 2004 this is in fact the "released" V1.4, following beta testing.

Unfortunately a particular V1.4 weakness was NOT picked up by the beta testing. This relates to the ability to save CTC panel data as text (.ctc file). In particular, any track sections that are part of a "block" are omitted from the saved .ctc file.

This will probably only be noticed should you choose to re-input CTC data from a saved .ctc file.

Most people are probably content having their CTC data automatically saved, from one Tcc run to the next, in the standard binary .tcp file.

Unless, like me, you want to fine-tune CTC parameters (e.g. gridcolour, size, title, etc), you won't realise that the problem exists. That is, until some point in the future, when you will HAVE to "export" all your Tcc data (CTCs, network-defs, etc) in order to migrate to the next Tcc version. This will be required because the binary .tcp file will not be forward-portable, see Howard A's "Futures" topic in the Tcc V1.4 Help menu, History page.

This problem is still under investigation, but all users of Tcc should review the following PART 2 information for important Tcc usage recommendations that can be adopted NOW and will hopefully minimise the impact of this problem on individual Tcc users and will protect their investments in Tcc data.

Part 2 - Workarounds

Within the context of only V1.4 being available to the user (a likely situation), "prevention is better than cure", i.e. there is a simple way of "priming" Tcc V1.4 so that it will produce correct .ctc/.tcg files, by initially opening a "primer" .ctc file (which contains one block in each CTc panel) as input. Once that's done, said blocks can be deleted, but the in-Tcc environment still remains "reset".

If the user "primes" Tcc before investing much work in creating elaborate CTC panels, he/she will be able to save .ctc/.tcg correctly subsequently.


If there is already track block investment locked into existing .tcp files( e.g. ha1.tcp):

  1. Correct .ctc/.tcg files can be generated by utilising  Tcc V1.3 one-off. These can then be opened into V1.4. Subsequent save .ctc/.tcg under V1.4 will be correct.  Essentially the same as the "primer" approach, but with a "custom" .ctc file as input; OR
  2. Correct .ctc/.tcg files can be generated by utilising a second V1.4 code modification that I have written; OR
  3. Manually key the BLOCK B items into an incomplete .ctc file and then open it back into Tcc - assuming you can find out the format of BLOCK B entries in the .ctc file!

Option a. does sound like it's the most straightforward.

As there are probably only a relative few Tcc users affected, I'm sure that Howard Amos or myself could, if neccessary, help by carrying out the necessary v1.3 "generate(s)" of complete "custom" .ctc files from the user's V1.4 .tcp file.

If starting afresh....

Below is the listing of a tested primer.ctc (one vertical track element in 1,1 of each CTC1-4 panel, each of which is in a block)

Extract it to a file and open it before starting work creating your own CTc panel data.

CTC panel size will be reset to 10x10 cells, expand again as necessary.

WARNING - Any existing CTC panel data will be lost.

Check all is OK by trying Save as of .ctc after you have removed the primer track elements and have added some of your own.

NOTE:To remove a track element from a block: (e.g. those defined by "primer" .ctc file)

  • To start with, track element will be black
  • Select Track / "B"
  • Click on Title bar of CTCx panel
  • All track elements in blocks go blue
  • Click on track element, should go red
  • Click same element again, should go black
  • You have now removed element from block
  • Repeat for other element(s), other panels
  • Next, remove element(s) from panel:
  • Holding down Shift, left-click on element
  • Repeat for other element(s),other panels
  • Can check all is "clean" by Save As .ctc
  • Should have no elements or blocks.
  • Next, add some elements and blocks or your own and Save As .ctc and inspect the file.

At end of session all CTC data, blocks will be "checkpointed" in the standard associated .tcp file and will be picked up at the next Tcc session.  Save As .ctc should continue to work correctly as further panel mods are made.

Save lines below as: primer.ctc

CTC 1 "CTC1"
FONT small 0 Arial
FONT medium 0 Arial 0.25
FONT large 0 Arial 0.3333333333333333
BLOCK null
CELL 1,1 LINE 22
CTC 2 "CTC2"
FONT small 0 Arial 0.16666666666666666
FONT medium 0 Arial 0.25
FONT large 0 Arial 0.3333333333333333
size 10,10
BLOCK null
CELL 1,1 LINE 22
CTC 3 "CTC3"
FONT small 0 Arial 0.16666666666666666
FONT medium 0 Arial 0.25
FONT large 0 Arial 0.3333333333333333
size 10,10
BLOCK null
CELL 1,1 LINE 22
CTC 4 "CTC4"
FONT small 0 Arial 0.16666666666666666
FONT medium 0 Arial 0.25
FONT large 0 Arial 0.3333333333333333
size 10,10
BLOCK null
CELL 1,1 LINE 22

Contact Information

If you want to follow up any item on this page please contact the MERG webmaster who looks after these pages.

Copyright to all information on these pages is held by the Authors identified.