Intro to scripting

A TCL (Train Control Language) script defines exactly what you want tcc to do.

Each script begins with some declarations, which give names to memory variables and, inputs & outputs and where they are connected.

After the declarations the rest of the script is a set of statements. These statements are the body of the program and define the behaviour we want.

There are three types of statement, and these are all very similar:

WHEN
The standard when statement. When a condition becomes true the statement is executed once and once only. After the execution has finished the condition must become false and then true again for the statement to be executed again.

WHILE
Similar to the when statement except that it is executed continuously until the conditin is false. The execution rate depends upon the speed of the computer and any wait or pulse actions in the statement.

FOREVER
An extension to the while statement, except that it has no condition. The actions are executed continuously, as long as the script is running.

To take a really simple example, one that you might consider implementing with a few gates or a flip-flop: We want a train entering a hidden siding to stop automatically at the end of the siding. On this layout trains always run slowly when approaching the sidings and so we can safely stop them with a simple relay. We can detect their presence with some kind of detector, perhaps a light beam, an infra-red reflective unit like an IRDOT (from Heathcote electronics), a reed relay activated by a magnet on the train, an LDR (light dependant resistor) that changes resistance when light is obscured by a train, or whatever. We want the stationary train to depart again when a button on the control panel is pressed. (assume these are straight through sidings, and that the routes have been set somehow).

Suppose we have two inputs, called 'detector' (connected to whatever sensor we are using) and 'release' (connected to the button), and one output, called 'stop' (that is the relay that stops the train when energised).

We could define this behaviour with two instructions:



WHEN detector=1 DO relay=1      { stop train when detector is reached }

WHEN release=1 DO relay=0       { start train when called }

These two instructions are like edge-triggered set and reset lines on some kind of theoretical flip-flop.

Each instruction is executed once, when its condition becomes true, and then will not be executed again until the condition becomes false, and then true again.

The relay is only set to be energised when the front of the train is detected. After that the first statement is not executed again until the train has departed and another train arrives.

The relay is released when the button is first pressed. The two statements do not 'fight' to control the relay (unless the button is pressed at exactly the same moment that the rain arrives, in which case the button wins).

As another example suppose we were driving a three aspect signal, and we wanted it to be driven based upon track occupancy rather than the more complex route selection and interlocking rules.

We want the signal to show red when a train enters the section just after the signal, or when no train is approaching the signal.

We want yellow if the next section is clear, but the one after it is occupied.

And green if both following sections are clear.

OK, you might not like to drive signals that way, but it makes a simple example.

If the sections are called 'A' (before the signal), 'B' (just after the signal) and 'C' (the one after B, and we have inputs that come from an FTC module (Floating Track Circuit, or 8 track occupancy detectors) with the same names. Assume we also have outputs called red, yellow and green.

One possible script to do this (including the declarations this time) could be:



Constants:
Free=0, Occupied=1,     { define the polarity of our sensor inputs }
On=1, Off=0             { define polarity of our outputs }

Sensors:
A, B, C                 { current detectors attached to sections A, B & C }

Controls:
red, yellow, green      { outputs that drive our signal }

Actions:

WHEN A=Free                           { No train approaching }
OR   A=Occupied, B=Occupied           { Next section occupied }
DO red=On, yellow=Off, green=Off

WHEN A=Occupied, B=Free, C=Occupied
DO yellow=On, red=off, green=off      { Train may enter at caution }

WHEN A=Occupied, B=Free, C=Free
DO green=On, red=Off, yellow=Off      { Road ahead clear }

The text in brackets are just comments, so you can leave notes to remind you how your script works - Tcc ignores them completely.

The first few lines (headed 'Constants:') simply gives names to numbers, so that we can use On and Off to mean 1 and 0. This aids readability of the script.

The lines headed 'Sensors:' and 'Controls:' give names to the inputs and outputs that connect to the railway. these are the pins on the FTC and SRO4 modules (or whatever hardware you have chosen to interface to the layout).

After the heading 'Actions:' are the instructions telling Tcc exactly what to do. Each statement consists of the following items:



'WHEN' conditions 'DO' actions

The conditions are simple tests that are anded and or-ed together (the commas may be written 'AND', but a comma abbreviates things nicely).

The actions are things we want to happen when the conditions are true.

Note that a script is not really like a programming language - the statements are not executed in order. The script is more like a written version of logic gates and registers - all the 'WHEN' statements are in essence executing in parallel. The script would do exactly the same regardless of the ordering of the three WHEN statements shown here.

The script is largely compatible with the script used by the software that CTI supplies (free download from their web site http://www.cti-electronics.com) and that site has an excellent introduction to these scripts. Tcc adds some

advanced capabilities such as structured data and arrays, but does not yet support the ability to play audio files.


Back to index page.
List of actions available in scripts.