This project provides an Arduino sketch to control my model railway yard which consists of a number of parallel tracks where each track can consist of mutliple sections.
Trains should approach a preselected track and will be stopped using "Brake on DC" when they reach a contact at the head of the track. If a track with already occupied sections is approached, the incoming train is stopped at the head right behind.
Each track has a decoder address (MM2) assigned for control, pressing the green button on your control panel will release the train from the associated track and send it back on the track. If trains move out from tracks with multiple sections, trains from sections behind will be moved to the head of the track. The red button is currently used to reset the internal state based on the result of the contacts, it should not be required during normal operations.
- On startup / after reset the first block is in
detect
state, all other blocks are inforward
state. - On activation of the break contact of the first block, it changes to
brake
state and sends the brake signal to the track by switching the relay to on. - The successor block is informed on the state change
- If the blocks break contact is set, it changes state to
follow
and also turns on the brake relay - if the break contact is not set, the block switches to the
detect
state - In both cases the next block is informed which behaves in the same way
- If the blocks break contact is set, it changes state to
- On release (green button pressed), the front block switches to
moveout
and the track power is turned on.- For all following blocks with mode
follow
the track power is also released, the state flag is not changed!
- For all following blocks with mode
- When the break contact of the front block changes to
open
, its state is changed todetect
- Following blocks with open contacts are set to
forward
- The first following block with a closed contact will be changed to
moveout
- Following blocks with open contacts are set to
If reset (red button) is called, the state of each block is re-evaluated:
- Blocks with an open contact are put to
detect
with track power restored. - Blocks with a closed contact not in
follow
state are assumed to be inbreak
state. - Blocks with a closed contact in
follow
state are assumed orphaned and moved tobrake
if the parent block is indetect
To read from the digital control bus the sketch uses (a modified version of) the MaerklinMotorola library (https://www.arduino.cc/reference//en/libraries/maerklinmotorola/) and expects the Märklin signal on Pin D2
.
The track sensor for the first block is expected on A0
, the corresponding relay must be attached to port D3
- the following blocks use the subsequent ports. You have to defined the number of blocks and the layout with the heads address in the program code currently. The software does not make any limit on the number of blocks, it just counts up "by one" based on the literal names of the PINs so it might be easy to use more blocks with a larger Arduino or port extenders.
The inputs are read in analog mode and debounced in software (see DECAY settings). The internal PullUps are active, if you use A7/A8 on an Arduino Nano mind to add external PullUps! A LOW
signal is evaluated as "train on track".
To not waste I/O PINs I decided to use mono-stable relays for the breaks. The default setting is "brake" (output is LOW
), the relay control PIN goes to HIGH
to let the train pass.