Objects - an Introduction
First we need the ‘objects’ that we will use for our automation sequences.
There are a number key objects that are important for creating sequences:
The process for creating these objects consists of:
Adding the hardware (not strictly applicable to the roster)
Configuring EX‑CommandStation by modifying ‘myAutomation.h’ so that it knows about the object
Re-uploading the software to the EX‑CommandStation
Note
COMMANDS are case sensitive. i.e. they must be in uppercase. Text parameters you provide (aliases, descriptions) are not
Adding a Roster
EX-RAIL has a ROSTER()
function to allow you to define all of your locomotives with a list of their defined functions which is advertised to WiThrottle applications, just like turnouts/points and routes.
The functions can simply be listed as “F” numbers, or you can provide a text description of the function. Prefacing the function with a “*” indicates it is momentary, meaning it is only activated while holding that function button down.
In a text editor (e.g. notepad) create a new text file named ‘myAutomation.h’. (Note the capital ‘A’ in the name. The case of all the characters is important.)
If you are already using EX‑RAIL and have a myAutomation.h, then just the add ROSTER(...)
lines near the top of the file.
Add a line that looks like:
ROSTER(999,"Loco Name","F0/F1/*F2/F3/F4/F5/F6/F7/F8")
Where:
999 - is the DCC address of your loco
My Loco Name - is anything you want to see as the name of this loco in the throttle apps
F0 F1 F3 … F27. - are the names that you want to see for the functions specific to this loco
*F2 - note that if the function is ‘momentary’ rather than ‘latching’ (On/Off) then start the function label with a asterisk (*). The most common example of this is the Horn/Whistle which is commonly on F2.
Some more realistic examples might look like:
ROSTER ( 3,"Eng 3", "F0/F1/*F2/*F3/F4/F5/F6/F7/Mute/F9//") // Address 3, Eng 3, Function keys F0-F10
ROSTER(1224,"PE 1224","") // Motor Only Decoder, But use Engine Driver 'Preferences >In Phone Loco 'Sound'
ROSTER(1225,"PE 1225","Lights/Bell/*Whistle/*Short Whistle/Steam/On-Time/FX6 Bell Whistle/Dim Light/Mute")
ROSTER(4468,"LNER 4468","//Snd On/*Whistle/*Whistle2/Brake/F5 Drain/Coal Shvl/Guard-Squeal/Loaded/Coastng/Injector/Shunt-Door ~Opn-Cls/Couplng/BrakeVlv/Sfty Vlv/Shunting/BrkSql Off/No Momentm/Aux3/Fade Out/F22 Res/F23/Res//Aux 5/Aux6/Aux7/Aux 8")
Note: Add additional ‘ROSTER(…)’ lines for all your locos
ROSTER(1506, "HUSA", "Light/Bell/*Horn")
A more complex example with generic functions for the same loco (note the momentary F2 for horn):
ROSTER(1506, "HUSA", "F0/F1/*F2/F3/F4/F5/F6/F7/F8/F9/F10/F11/F12/F13/F14/F15/F16/F17/F18/F19/F20/F21/F22/F23/F24/F25/F26/F27/F28")
The same again, with more text functions defined to represent a number of different sounds:
ROSTER(1506, "HUSA", "Lights/Bell/*Horn/Air/Brake/Coupling/Compressor/Sand/Mute/F9/F10/F11/F12/F13/F14/F15/F16/F17/F18/F19/F20/F21/F22/F23/F24/F25/F26/F27/F28")
Locos with Unavailable Functions
If a function is not available just leave the spot empty. (Don’t even have the space character.)
For example:
ROSTER(2825,"CN ES44AC","Headlight/Bell/*Horn/Coupler/Dynamic Brake///Flange Squeal/Startup & Shutdown")Note the two missing text labels for positions F5 and F6. Engine Driver will skip those buttons and not display them at all in the interface since they do nothing for that loco.
Example of loco without sound:
ROSTER(2405,"AT&SF 2-8-0 2405","Headlight")Note that it only has FO (the Headlight) and not following slashes.
Adding Turnouts/Points
Turnouts/Points can included on your layout in one of the
DCC turnouts/Points
Servo Turnouts/Points
Pin turnouts/Points
DCC Turnouts/Points
Adding the Hardware - DCC Turnouts/Points
If you have installed turnouts/points using DCC accessory decoders, you can config the EX‑CommandStation so that it knows about it and you can control in in your sequences.
TURNOUT( id, addr, sub_addr [, "description"] )
The TURNOUT
command defines DCC accessory decoder turnout/point in EX-RAIL, which will appear in wiThrottle Protocol apps, Engine Driver, and JMRI in addition to being defined as a turnout/point within the CommandStation.
Configure myAutomation.h - DCC Turnouts/Points
Pin Turnouts/Points
Adding the Hardware - Pin Turnouts/Points
If you have installed turnouts/points using simple pin control, you can config the EX‑RAIL so that it knows about it and you can control in in your sequences.
PIN_TURNOUT( id, vpin [, "description"] )
The PIN_TURNOUT
command defines a pin operated turnout/point in EX-RAIL, which will appear in wiThrottle Protocol apps, Engine Driver, and JMRI in addition to being defined as a turnout/point within the CommandStation.
When setting up a turnout/point where multiple pins are required for control, the VIRTUAL_TURNOUT
command should be used along with a control sequence. This is commonly used to configure solenoid-based turnout motors.
#define PULSE 10 // Set the duration of the pulse to 10ms
#define SINGLE_COIL_TURNOUT(t, p1, p2, p3, desc) \
VIRTUAL_TURNOUT(t, desc) \
DONE \
ONCLOSE(t) \
SET(p2) RESET(p3) \
SET(p1) DELAY(PULSE) RESET(p1) \
DONE
ONTHROW(t) \
RESET(p2) SET(p3) \
SET(p1) DELAY(PULSE) RESET(p1) \
DONE
SINGLE_COIL_TURNOUT(101, 22, 24, 26, "Turnout 101")
Configure myAutomation.h - Pin Turnouts/Points
Servo Turnouts/Points
Adding the Hardware - Servo Turnouts/Points
To connect a servo to EX‑CommandStation, you first need to get a module, based on the PCA9685 chip.
These are widely available from eBay, Amazon, etc. for a few dollars.
Note the pin connectors along the left side of the module - these are where you connect to the Arduino.
The 16 columns of three pins along the bottom of the module are where you connect the servos. The pins are arranged so that you can just plug a servo connector directly onto them, but be sure that the wire colours match the colours of the pins, i.e. yellow to yellow, red to red and black to black.
The servo module itself is powered from the Arduino, but the servos themselves contain motors that consume more current than the Arduino is able to supply, and so a separate 5V supply is required for the servos. This is connected to the green terminal block at the top of the module, with terminals labelled V+ and GND. The V+ terminal is connected to 5V and the GND to the 0V (ground) wire of the supply.
Connections to the Arduino are made with four jumper wires (Arduino: +5V, GND, SCL, SDA to servo module: VCC, GND, SCL, SDA), as shown on the following diagram:
In EX‑CommandStation, the drivers for the PCA9685 module is already installed, and made available to for use as pin numbers 100-115. A servo is shown in the diagram, connected to the first set of pins on the module. This will be accessed using pin number 100.
Once you’ve made all of the connections, apply power to the Arduino.
Then, in the Serial Monitor, enter the command <D SERVO 100 450>. The servo should move, as long as it isn’t (by some fluke) already in that position.
Enter <D SERVO 100 110> and this time it should definitely move. For the last parameter (servo position) you can use any value between about 105 and 490.
Try <D SERVO 100 450 3> and the servo should move slowly back.
You can use the servo to control turnouts/points, semaphore signals, engine shed doors, and other layout components, to make your layout more dynamic and exciting. In the picture below, you can see a servo mounted below the baseboard with a piece of wire passing through a slot cut in the baseboard, to operate a turnout/point.
And in the next picture you can see a servo that operates a semaphore signal. The signal, and its servo mounting bracket, were 3d-printed on a Creality Ender-3 printer.
Configure myAutomation.h - Servo Turnouts/Points
The myAutomation.h file needs to be altered so that the EX‑CommandStation knows about each Turnout/Point.
EX-RAIL supports three methods of controlling servos:
Controlling Servos for Turnouts/Points
The SERVO_TURNOUT
directive defines a servo based turnout/point in EX-RAIL, which will appear in wiThrottle Protocol apps, Engine Driver, and JMRI in addition to being defined as a turnout/point within the CommandStation.
As per the EX‑RAIL reference, turnouts/points are defined with the following syntax:
// Example
SERVO_TURNOUT(id, pin, active_angle, inactive_angle, profile [, "description"])
// Example
SERVO_TURNOUT(200, 101, 450, 110, Slow, "Example slow turnout/point definition")
/* An example definition for a servo connected to the second control pins of the first PCA9685 connected to the CommandStation, using the slow profile for prototypical operation: */The valid parameters are:
id = Unique ID within the CommandStation (note these are shared across turnouts/points, sensors, and outputs).
pin = The ID of the pin the servo is connected to, which would typically be the VPin ID of the PCA9685 controller board.
active_angle = The angle to which the servo will move when the turnout/point is thrown (refer below for further detailed information).
inactive_angle = The angle to which the servo will move when the turnout/point is closed (refer below for further detailed information).
profile = There are five profiles to choose from that determine the speed at which a turnout/point will move: Instant, Fast, Medium, Slow, and Bounce (note we don’t recommend Bounce for a turnout/point definition).
description = A human-friendly description of the turnout/point that will appear in WiThrottle apps and Engine Driver. Note that this must be enclosed in quotes “”.
Servos for Signals and Animations
See above for information on installing the servo hardware (it is the same as for a turnout/point).
Configure myAutomation.h - Servos for Signals an Animations
The myAutomation.h file needs to be altered so that the EX‑CommandStation knows about each servo.
EX-RAIL supports two methods of controlling servos that are not related to turnouts/points:
Servos for Signals
The SERVO_SIGNAL
directive defines a servo based signal in EX‑RAIL to drive semaphore type signals as part of sequences or routes, or simply be set via a signal or similar.
Similar to pin based signals, servo signals are controlled by the ID of the red pin only.
Unlike servo based turnouts/points, there is no ID or description (they don’t appear in throttles), and they use the “Bounce” profile with no other options available at the present time:
SERVO_SIGNAL(vpin, redpos, amberpos, greenpos)
// Example
SERVO_SIGNAL(102, 400, 250, 100)
/* A simple example using the third control pins of the first
PCA9685 connected to the CommandStation would be: */
vpin = The ID of the pin the servo is connected to, which would typically be the VPin ID of the PCA9685 controller board.
redpos = The angle to which the servo will move to for the red position.
amberpos = The angle to which the servo will move to for the amber position.
greenpos = The angle to which the servo will move to for the green position.
Servos for Animations
The SERVO
and SERVO2
directives allow for servos to be used in various automations within EX‑RAIL.
Note that unlike a SERVO_TURNOUT
these are not definitions that appear within WiThrottle apps, Engine Driver, or JMRI, but are instead actions designed to be used within EX‑RAIL automations.
As per the EX‑RAIL reference, these are defined with the following syntax:
SERVO(vpin, position, profile)
SERVO2(vpin, position, duration)
The valid parameters are:
vpin = The ID of the pin the servo is connected to, which would typically be the VPin ID of the PCA9685 controller board.
position = The angle to which the servo will move when the turnout/point is thrown (refer below for further detailed information).
profile = There are five profiles to choose from that determine the speed at which a servo will move: Instant, Fast, Medium, Slow, and Bounce.
duration = The time (in milliseconds (ms)) for the servo to be actively rotating.
// Example
AT(164)
SERVO(101, 400, Fast)
DONE
AFTER(164)
SERVO(101, 100, Slow)
DONE
/* As an example, consider a lineside worker that needs to be moved away
from the track when a train approaches, which is controlled by an infrared
sensor.
The SERVO is attached to VPin 101 (second control pin on first PCA9685),
with a sensor attached to VPin 164 (first pin on the first MCP23017):
This tells EX-RAIL that when the sensor at VPin 164 is activated, the
lineside worker moves quickly back from the track for safety, and then
after the sensor has been deactivated, he can leisurely move back to his
working position (no one wants to rush back to work right?). */
Adding Sensors
Adding the Hardware - Sensors
On the Mega2560 Processor board:
Place IR Infrared or Optical Sensor’s Output wire on Dpins 22, 23, 24 … 49. Plus one wire to GND and a third wire to 5v.
If you need more sensors then there are available pins on the Mega, you use one or more I2C GPIO Expander Modules
Todo
HIGH - Link here to recommended pin/vpin allocations etc.
Configure myAutomation.h - Sensors
You don’t actually require anything special to be added to myAutomation.h in advance of using them in an sequence.
Handling sensors in sequences is made easy because EX‑RAIL throws away the concept of interrupts (“oh… sensor 22 has been detected… which loco was that and whatever do I do now?”) and instead has the sequences work on the basis of “do nothing, maintain speed until sensor 22 triggers, and then carry on in the script”.
Sensor numbers are direct references to VPINs (virtual pin numbers) in the Hardware Abstraction Layer. For a Mega onboard GPIO pin, this is the same as the digital pin number. Other pin ranges refer to I/O expanders etc.
Note
Hall effect sensors work for some layouts, but beware of how you detect the back end of a train approaching the buffers in a siding, or knowing when the last car has cleared a crossing.
EX‑CommandStation allows for sensors that are Active Low or Active High. This is particularly important for IR sensors that have been converted to detect by broken beam, rather than reflection. By making the sensor number negative, the sensor state is inverted. e.g. AT(-22)
.
Sensors with ID’s 0 to 255 may be LATCHED/UNLATCHED in your script. If a sensor is latched on by the script, it can only be set off by the script… so AT(22) LATCH(22)
for example effectively latches the sensor 22 on when detected once.
Sensor polling by JMRI is independent of this, and may continue if <S>
commands are used. However there is now a way of defining JMRI sensors from within EXRAIL - see EXRAIL Command Reference - JMRI_SENSOR.
Adding Signals
Adding the Hardware - Signals
To connect a servo to EX‑CommandStation, you first need to get a module, based on the PCA9685 chip.
These are widely available from eBay, Amazon, etc. for a few dollars.
Note the pin connectors along the left side of the module - these are where you connect to the Arduino.
The 16 columns of three pins along the bottom of the module are where you connect the LEDs.
In EX‑CommandStation, the drivers for the PCA9685 module is already installed, and made available to for use as pin numbers 100-115.
On the PCA9685 Servo Signal Board:
Connect individual LEDs on vpins 101, 102 … 115 as needed
Only use the -Gnd and Output+ vpins, NOT the center 5v pin
Configure myAutomation.h - Signals
The myAutomation.h file needs to be altered so that the EX‑CommandStation knows about each Signal.
Signals setup on vpins 101, 102 … 115
For each signal add a line in myAutomation.h in the form:
SIGNAL(red_pin, amber_pin, green_pin)
// always use the first red_pin as the signal_id for All signal color changes)
SIGNAL(106, 0, 107) // Red, Amber, Green For turnout/point 1
Combine the two commands Servo_Turnout and Signal (New 4.1:)
New 4.1 SERVO_SIGNAL(vpin, redpos, amberpos, greenpos)
// Use the first Red vpin# as the signal_id for All Signal color changes
// Use this to Combine the two commands Servo_Turnout and Signal above into One Function
SERVO_SIGNAL(106, 400, 0, 205) // Red vpin 106 for turnout/point 1, Thrown=Red, Close = Green
Next Steps - Creating Sequences
See the Sequences - an Introduction page or click the ‘Next’ button to learn how to create automation sequences.