The System 2 Route Processor is a CAN-bus based event-sequencer for model railways. It watches inputs from block-detection nodes, fires timed output sequences on servo and relay nodes, and gates each sequence on logical conditions over the live state of the bus.
This document walks through two fully-worked configurations that exercise most of the Route Processor's features:
Each example gives you the complete vPort numbering, block-group definitions, route configurations (mocked-up exactly as you will see them in the router's web interface), and a time-based walkthrough of what happens on the bus during a typical operating cycle.
The Route Processor is the brain. Everything else — the block detectors, points, signals and brake relays — lives on other System 2 nodes that share the CAN bus. The following parts cover both worked examples in this document.
| Product | Qty | Function | Capacity per board |
|---|---|---|---|
| S2-Route — Route Processor | 1 | The brain. Holds up to 100 routes, 32 block groups, runs the trigger / condition / chain / schedule engine. | One per layout. |
| S2-IN32 — 32-input panel node | 1–2 | Block occupancy detection. Each input is one vPort that goes 1 when its track block is occupied, 0 when clear. | 32 inputs/board. |
| S2-serv8 — 8-channel servo driver | 2–3 | Drives point motors (one channel each) and semaphore signals (one channel each, with mechanical bounce on the up-quadrant swing). | 8 servos/board. |
| S2-Relay8 — 8-channel relay driver | 1–2 | Energises ABC brake sections. Coil de-energised = brake engaged (failsafe wiring). The relay's NO contact feeds the brake-section's DC offset. | 8 relays/board. |
| S2-Panel or S2-Mini (optional) | 0–1 | Operator console: physical buttons that act as trigger vPorts ("send the next train to road 4", "depart from road 4"). Not strictly required — the same triggers can be fired from the Route Processor's web page. | Up to 32 buttons. |
A vPort is a numbered virtual address on the CAN bus. Inputs (block detectors) write 1 to a vPort when occupied and 0 when clear. Outputs (servos, relays) listen for writes to their vPort and animate accordingly. You pick the numbering — vPorts run 1–60000 and never collide unless you assign the same number to two physical channels.
Convention in this document:
100s to 1900s, organised by area.200s and 2000s.300s and 2100s.400s and 2200s.3000s.This is just a convention; the firmware does not care.
A route is a sequence of up to 16 timed vPort writes (the slots). Each slot specifies a vPort to write, the value to write (0 or 1), and a delay after the write before the next slot fires.
The route can have:
3) while the route is playing and set to 0 on completion. Useful for "route is active" indicators. Note: because the live value is 3 (not 1), a condition that tests a feedback vPort for "is SET" or "is CLEAR" will never match while it is active — don't gate a route on another route's feedback vPort state.A block group names a range of input vPorts. The group is OCCUPIED if any vPort in the range is set, CLEAR if every vPort is known and clear, UNKNOWN if none of them have been observed since boot. Up to 32 groups, configured on the Route Processor's Block Groups page.
Groups let route conditions ask "is South Yard occupied?" without having to list the 22 vPorts that make up the yard.
Between the trigger and the slot sequence sit five gating features:
HH:MM–HH:MM window in local time. Routes outside their window are dropped at trigger time.The route page also shows a dry-run preview: a client-side "what would happen now?" against the live block-group state. Use it while authoring — it'll catch off-by-one vPort numbers and condition typos without you having to send a real train.
In addition to the enable, feedback and RFID triggers covered above, a route can fire itself on a clock without any input change at all. Two flavours, set on the same route alongside any other trigger:
HH:MM. Fires when the layout clock first reaches that time, at most once per real day (the "already fired" latch is cleared at real midnight — see the fast-clock note below). Useful for the "morning station opening sequence", "lights on at dusk" or the operator wanting a specific scheduled departure even when nothing is moving on the bus.N seconds (60 s minimum, up to 65535 s ≈ 18 h). Fires every N seconds for as long as the route's schedule window is open. Useful for animated scenics that should cycle on a heartbeat — a level crossing demo every 3 minutes, a factory whistle every 15 minutes.Both timed triggers respect the schedule window (3.4): an interval timer that fires while the route is out of its window does not enqueue the sequence, and the interval clock pauses while the window is closed so it counts from the moment the window reopens instead of dropping back-logged fires.
Both triggers also respect conditions — you can build a "fire every 90 s, but only if South Yard is clear" sequence by combining the interval timer with a block-group condition. The condition is evaluated at fire time, not at the moment the timer is set, so the bus's current state always controls.
08:00 fires when the layout clock reads 08:00. But the once-a-day latch that stops it re-firing is cleared at real midnight, not layout midnight, so on a 10× fast clock the route still fires once per real day (the first time the layout clock passes 08:00), not on each of the ~10 layout days that elapse in 24 real hours.
The slot editor shows up to 16 slots per route. Two layouts are available, swappable from the top of the route page:
The preference is stored per-board, so the layout you set is what every browser session sees until you change it. The toggle animates between layouts so you can keep your eye on a slot while it moves.
Once you've spent an evening dialling in delays and conditions, you do not want to lose them. The Route Processor keeps two independent backup paths:
The Backup button on the route editor downloads every route as a JSON file (<hostname>-routes-YYYY-MM-DD.json). The file is a complete, lossless snapshot — trigger gating, schedules, chains, timers, the lot. Save it somewhere safe (or check it into a layout-config git repo).
The Restore button reads the file back. Both the new .json format and older colon-string .txt backups are accepted — the browser converts legacy files on the fly. Routes are sent to the device in small batches so even a full 100-route restore is reliable and incremental: you can see "Sending 25 / 100 routes…" in the progress overlay rather than staring at a frozen page.
If the router has been registered (one-time email/name handshake), the Cloud Backup link opens a panel showing every backup ever uploaded for this board. Locked backups are preserved indefinitely; unlocked backups rotate after five. From the same panel you can press Backup Now to push the current settings to the cloud, or pick any previous snapshot and Restore it.
The router also auto-backs-up after most settings changes and after every OTA firmware upgrade. The backup runs through your browser's TLS stack (not the device's), so big route sets ship reliably without making the board appear to freeze.
Mega Loop is a two-platform crossing station on a single-track main line. East-bound trains take Platform 1 (upper); west-bound trains take Platform 2 (lower). The system is fully automatic — no buttons, no operator, no manual controls. The Route Processor:
The interlock that makes it work is a single condition on the depart routes: the opposite platform detector must already read OCCUPIED. A second, internal flag (vP 500) guards the departure so the leaving trains aren't read as arrivals. Eight small routes and four block detectors are enough to run the whole station.
The numbered circles are block detector vPorts (1–4). A single-track main line enters from the west, opens through the West points into a two-track loop, and recombines through the East points to continue east. Each platform has a 4–6 cm-long ABC brake section in the middle of its block.
Four System 2 nodes share the CAN bus. Every part is off-the-shelf — no custom wiring, no operator panel.
| Node | Qty | Channels used | Role |
|---|---|---|---|
| S2-Route | 1 | — | The brain. Holds the eight routes and the interlock conditions. |
| S2-Mini Panel (8 inputs + 8 outputs) | 1 | 4 of 8 inputs | Block-occupancy detection on each of the four track sections. Eight spare outputs are available for future indicators or panel LEDs. |
| S2-serv8 (8-channel servo driver) | 1 | 2 of 8 servos | Drives the West and East point motors. |
| S2-Relay8 (8-channel relay driver) | 1 | 2 of 8 relays | Switches the ABC brake section feed for each platform. |
Block detectors get the low single-digit vPorts (matching the numbered circles on the track plan). Points and brake relays use the same numbering convention as elsewhere in this document (200s for points, 400s for brakes, 500s for internal interlock flags).
| vPort | Function | Device | Semantics |
|---|---|---|---|
| 1 | Block 1 — West approach | S2-Mini Panel | 1 = occupied, 0 = clear |
| 2 | Block 2 — Platform 1 (upper, east-bound) | S2-Mini Panel | 1 = occupied, 0 = clear |
| 3 | Block 3 — East approach | S2-Mini Panel | 1 = occupied, 0 = clear |
| 4 | Block 4 — Platform 2 (lower, west-bound) | S2-Mini Panel | 1 = occupied, 0 = clear |
| 200 | West points | S2-serv8 | 0 = routes to Platform 1 (upper), 1 = routes to Platform 2 (lower) |
| 201 | East points | S2-serv8 | 0 = routes to Platform 1 (upper), 1 = routes to Platform 2 (lower) |
| 400 | Platform 1 ABC brake relay | S2-Relay8 | 0 = brake ENGAGED (coil off, train stops), 1 = brake RELEASED |
| 401 | Platform 2 ABC brake relay | S2-Relay8 | 0 = brake ENGAGED, 1 = brake RELEASED |
| 500 | Departure interlock (loop busy) | — internal flag | 1 = a departure is in progress; 0 (and never-written = UNKNOWN) = idle. No hardware behind it — written by routes only, read as a condition by R1/R2. |
Eight routes run the entire station. Every route is fired by a block-detector edge — there are no panel buttons, no operator inputs, no manual overrides. Two routes throw the entry points on arrival, two routes throw the exit points and release both brakes when the interlock is satisfied, two routes re-engage each brake after departure, and two routes clear the departure interlock once both trains are clear of the loop.
Route 3 (and its mirror Route 4) is where the interlock lives: the route is triggered when a train arrives at one platform, but its condition checks that the other platform is also occupied. If the other platform is empty, the route is deferred — it sits in the queue and re-evaluates every time the bus state changes. When the second train arrives the condition flips to TRUE and the depart sequence fires.
There is a second, subtler interlock at departure. The two approach detectors (vP 1 and vP 3) are shared: a train heading out of the loop crosses the very same block a train heading in would. A bare occupancy detector reports presence, not direction, so without a guard the departing trains would re-trigger the approach routes (R1/R2) and throw the entry points — potentially under the train still crossing them. The fix is an internal flag, vP 500 (“loop busy”): the depart routes set it as their first slot, R1/R2 carry a condition that lets them fire only while it is not set (on fail: drop), and two falling-edge routes (R7/R8) clear it once both trains have left the approach blocks. It is the same direction-memory technique used by the bi-directional platform in the next example.
One wrinkle worth calling out: an internal flag reads UNKNOWN until something first writes it, and — unlike a block detector — a hardware-less vPort can't be “seeded” by briefly occupying a block (see §9.3). A plain is CLEAR condition fails on UNKNOWN, which would drop R1/R2 on the very first arrival after every power-on. So R1/R2 test vP 500 is CLEAR OR is UNKNOWN (a two-condition OR): only a known-SET flag — a departure genuinely under way — suppresses them, and the station comes up working from a cold boot.
Here is Route 3 (the “EB train arrives last” case) shown in the router's web editor:
| Route | Default Delay ms |
Enable vPort |
Feedback vPort |
RFID vPort |
Route Name |
|---|---|---|---|---|---|
| 3▲▼ | 500 | 2 | Both ready (EB) |
| Slot | vPort | On/Off | Move | Delay ms |
|---|---|---|---|---|
| 1 | 500 | ▼🗑 | 0 | |
| 2 | 200 | ▲▼🗑 | 1500 | |
| 3 | 201 | ▲▼🗑 | 1500 | |
| 4 | 400 | ▲▼🗑 | 500 | |
| 5 | 401 | ▲🗑 | 0 | |
| … slots 6–16 empty | ||||
| 1. | vPort | 4 | is SET | × |
| 2. | vPort | is SET | × | |
| 3. | vPort | is SET | × | |
| 4. | vPort | is SET | × |
The dry-run preview shows the route would defer right now because Platform 2 is still empty in the live bus state. The route sits in the deferred queue (capacity 8) and re-evaluates whenever any vPort changes — the moment the west-bound train rolls into Platform 2, the condition flips to SET and the slots fire.
Each route has 1–5 slots and (where applicable) one or two conditions. There are no chains, no schedules, no feedback or RFID vPorts — the bus state is the only input.
| # | Name | Enable vP | Edge | Condition | Defer TTL | Slots (vP = val, delay ms) |
|---|---|---|---|---|---|---|
| 1 | EB approach — set West points | 1 | SET | vP 500 is CLEAR or UNKNOWN | drop | 200 = 0, 1500 |
| 2 | WB approach — set East points | 3 | SET | vP 500 is CLEAR or UNKNOWN | drop | 201 = 1, 1500 |
| 3 | Both ready (EB arrived last) | 2 | SET | vP 4 is SET | 60 s | 500 = 1, 0 · 200 = 1, 1500 · 201 = 0, 1500 · 400 = 1, 500 · 401 = 1, 0 |
| 4 | Both ready (WB arrived last) | 4 | SET | vP 2 is SET | 60 s | 500 = 1, 0 · 200 = 1, 1500 · 201 = 0, 1500 · 400 = 1, 500 · 401 = 1, 0 |
| 5 | EB departed — re-arm brake | 2 | CLEAR | — | — | 400 = 0, 0 |
| 6 | WB departed — re-arm brake | 4 | CLEAR | — | — | 401 = 0, 0 |
| 7 | Departure complete — clear interlock | 1 | CLEAR | vP 3 is CLEAR | drop | 500 = 0, 0 |
| 8 | Departure complete — clear interlock (mirror) | 3 | CLEAR | vP 1 is CLEAR | drop | 500 = 0, 0 |
A complete cycle from idle, through both trains arriving in opposite orders, the simultaneous departure, and back to idle. Initial state: both platforms empty, both brakes engaged (vP 400 = 0, vP 401 = 0), points wherever they were last left.
| Time | Event | Route fired | Result on the bus |
|---|---|---|---|
| t=0 | WB train enters East block (vP 3 SET) | R2 “WB approach” | Interlock not raised (vP 500 reads UNKNOWN on a cold start, CLEAR thereafter — either way R2's guard passes), so R2 runs: East points throw to lower (vP 201 = 1). Servo settles in 1.5 s. |
| t≈4 | WB train rolls past East points into Platform 2 (vP 4 SET) | R4 “Both ready (WB)” fires → defers | Condition vP 2 is SET fails (Platform 1 still empty). Route enters deferred queue with 60 s TTL. |
| t≈5 | Brake engaged (was already on); WB train coasts to a stop in the brake section. | — | — |
| t≈12 | EB train enters West block (vP 1 SET) | R1 “EB approach” | Interlock still down, so R1 runs: West points throw to upper (vP 200 = 0). Servo settles. |
| t≈16 | EB train rolls past West points into Platform 1 (vP 2 SET) | R3 “Both ready (EB)” fires; deferred R4 also re-evaluates. | R3 condition vP 4 is SET now passes. Slot sequence begins. |
| t≈16.0 | R3 slot 1: raise the departure interlock | R3 | vP 500 = 1. The loop is now “busy”; R1 and R2 are suppressed until it clears. |
| t≈16.0 | R3 slot 2: West points throw to lower | R3 | vP 200 = 1. Servo swings 1.5 s (clears the path for WB to depart west). |
| t≈17.5 | R3 slot 3: East points throw to upper | R3 | vP 201 = 0. Servo swings 1.5 s (clears the path for EB to depart east). |
| t≈19.0 | R3 slot 4: Platform 1 brake released | R3 | vP 400 = 1. Relay clicks. EB loco starts to accelerate. |
| t≈19.5 | R3 slot 5: Platform 2 brake released | R3 | vP 401 = 1. WB loco starts to accelerate. Both trains glide out simultaneously. |
| t≈22 | EB train clears Platform 1 (vP 2 CLEAR) | R5 “EB departed” | vP 400 = 0. Platform 1 brake re-armed for the next cycle. |
| t≈23 | WB train clears Platform 2 (vP 4 CLEAR) | R6 “WB departed” | vP 401 = 0. Platform 2 brake re-armed. |
| t≈23.5 | Departing EB train rolls east into the East block (vP 3 SET) | R2 evaluated → dropped | Without the guard this would read as a fresh WB arrival. Condition vP 500 is CLEAR fails, so R2 is dropped — the East points are left exactly where the depart sequence set them. |
| t≈24 | Departing WB train rolls west into the West block (vP 1 SET) | R1 evaluated → dropped | The mirror case: vP 500 is CLEAR fails, so R1 is dropped. The West points stay at lower (vP 200 = 1) — never thrown under the train still crossing them. |
| t≈25.5 | EB train clears the East block (vP 3 CLEAR) | R8 evaluated → holds | Condition vP 1 is CLEAR still fails (WB not yet clear of the West block), so the interlock stays up. |
| t≈26 | WB train clears the West block (vP 1 CLEAR) | R7 “Departure complete” | Condition vP 3 is CLEAR now passes. vP 500 = 0 — interlock dropped, R1/R2 re-armed. |
| t≈26 | Both trains have left the loop; the interlock is clear. | — | System idle, ready for the next pair of trains. |
201 = 0) from 1500 ms to 10000 ms. Once both points have settled, the trains sit for 10 seconds with brakes still engaged before the releases fire — a satisfying realistic pause for the viewer.400 = 1) delay to 2000 ms: Platform 1's brake drops, then 2 s later Platform 2's. EB rolls out first, WB follows. Useful if your locos accelerate differently and you don't want them meeting mid-loop.Route N blocked by schedule). Trains arriving overnight wait in their platforms until 06:00 and depart at first light.vP 4 is SET AND vP 6 is SET. Up to four conditions per route gives you a four-platform interlock without any other changes.vP 500 only when both trains have left the approach blocks. As with any edge-triggered logic, a lost CAN frame on a busy bus could leave the flag set and lock out new arrivals (the status log shows R1/R2 dropping on the vP 500 condition). Recovery is automatic on a power cycle — vP 500 resets to UNKNOWN, which the cold-start guard treats as clear — or, to avoid the reboot, add a panel “reset” button that writes vP 500 = 0 unconditionally, exactly like the bi-directional platform's all-clear button (§5.8). Do not use a timed or platform-clear auto-reset here: the platforms clear mid-departure, before the leaving trains cross their approach blocks, so any such reset risks dropping the guard while a train is still on the points.A three-platform through-station where Platform 1 serves only east-bound traffic, Platform 3 serves only west-bound traffic, and the middle Platform 2 is bi-directional — it can be used by a train heading in either direction. The operator picks the platform; the router enforces the interlock that makes the shared platform safe.
A bi-directional middle platform doubles the station's effective capacity without doubling its footprint. Common reasons to design one in:
Bi-directional working is the classic case where manual interlocking gets you into trouble. The router solves three problems for you:
vP 500 = “P2 is EB” and vP 501 = “P2 is WB”). They are written by the arrival routes and cleared on departure, giving you a stateful record of which way the platform is currently “facing” without any extra hardware.The single-track main line enters from each end and fans out through a two-point ladder (one S2-serv8 channel per point). Each platform has its own block detector and an ABC brake section centred on the platform. Direction arrows show single-direction running on P1 (east-bound only) and P3 (west-bound only); the middle Platform 2 is bi-directional.
One Route Processor, one Mini Panel (block detection plus four operator buttons), one S2-serv8 driving all four point motors, and one S2-Relay8 driving the three ABC brake sections. Eight CAN nodes from the System 2 family share the bus; nothing more is needed.
| Node | Qty | Channels used | Role |
|---|---|---|---|
| S2-Route | 1 | — | The brain. Holds the 13 routes, the two direction-flag vPorts and the interlock conditions. |
| S2-Mini Panel (8 inputs + 8 outputs) | 1 | 5 of 8 inputs, 8 of 8 outputs (optional) | 5 block detectors (West approach, P1, P2, P3, East approach). 8 outputs can drive panel LEDs for “platform occupied” / “P2 EB-locked” / “P2 WB-locked”. |
| S2-Panel (32 buttons) | 1 | 8 of 32 inputs | 4 “send-to” buttons (EB→P1, EB→P2, WB→P3, WB→P2) plus 4 “depart” buttons. The same triggers can be fired from the router's web page if you don't want a hardware console. |
| S2-serv8 (8-channel servo driver) | 1 | 4 of 8 servos | Drives the four point motors: W-A, W-B, E-A, E-B. |
| S2-Relay8 (8-channel relay driver) | 1 | 3 of 8 relays | Switches the ABC brake-section feed for each of the three platforms. |
Block detectors keep the single-digit/teens vPorts to mirror the numbered circles on the track plan. Points use the 220s, brake relays the 420s, and the two internal direction flags sit in the 500s. Operator buttons follow the document's convention in the 3000s.
| vPort | Function | Device | Semantics |
|---|---|---|---|
| 10 | Block 10 — West approach | S2-Mini Panel | 1 = occupied, 0 = clear |
| 11 | Block 11 — Platform 1 (EB only) | S2-Mini Panel | 1 = occupied, 0 = clear |
| 12 | Block 12 — Platform 2 (bi-directional) | S2-Mini Panel | 1 = occupied, 0 = clear |
| 13 | Block 13 — Platform 3 (WB only) | S2-Mini Panel | 1 = occupied, 0 = clear |
| 14 | Block 14 — East approach | S2-Mini Panel | 1 = occupied, 0 = clear |
| 220 | W-A point (West throat, upper) | S2-serv8 | 0 = through (toward W-B), 1 = diverge UP to P1 |
| 221 | W-B point (West throat, lower) | S2-serv8 | 0 = straight (toward P2), 1 = diverge DOWN to P3 |
| 222 | E-A point (East throat, upper) | S2-serv8 | 0 = through (toward E-B), 1 = diverge UP to P1 |
| 223 | E-B point (East throat, lower) | S2-serv8 | 0 = straight (toward P2), 1 = diverge DOWN to P3 |
| 420 | P1 ABC brake relay | S2-Relay8 | 0 = brake ENGAGED (coil off, train stops), 1 = brake RELEASED |
| 421 | P2 ABC brake relay | S2-Relay8 | 0 = brake ENGAGED, 1 = brake RELEASED |
| 422 | P3 ABC brake relay | S2-Relay8 | 0 = brake ENGAGED, 1 = brake RELEASED |
| 500 | Internal flag — P2 reserved for east-bound | (none — router state) | 1 = an EB train is in or approaching P2; cleared on departure or when P2 next reads CLEAR. |
| 501 | Internal flag — P2 reserved for west-bound | (none — router state) | 1 = a WB train is in or approaching P2; cleared on departure or when P2 next reads CLEAR. |
| 3000 | Panel button — “Send EB to P1” | S2-Panel | Rising edge fires R1. |
| 3001 | Panel button — “Send EB to P2” | S2-Panel | Rising edge fires R2 (blocked if P2 is reserved for WB). |
| 3002 | Panel button — “Send WB to P3” | S2-Panel | Rising edge fires R3. |
| 3003 | Panel button — “Send WB to P2” | S2-Panel | Rising edge fires R4 (blocked if P2 is reserved for EB). |
| 3010 | Panel button — “Depart P1 east” | S2-Panel | Rising edge fires R10. |
| 3011 | Panel button — “Depart P2 east” | S2-Panel | Rising edge fires R11 (requires vP 500 SET). |
| 3012 | Panel button — “Depart P3 west” | S2-Panel | Rising edge fires R12. |
| 3013 | Panel button — “Depart P2 west” | S2-Panel | Rising edge fires R13 (requires vP 501 SET). |
The interlock that makes the shared platform safe lives on the two P2 approach routes (R2 and R4) and the two P2 departure routes (R11 and R13). Here is Route 2 (“Send EB to P2”) shown in the router's web editor — the route that throws the West throat for an east-bound train heading into the middle platform.
| Route | Default Delay ms |
Enable vPort |
Feedback vPort |
RFID vPort |
Route Name |
|---|---|---|---|---|---|
| 2▲▼ | 500 | 3001 | Send EB to P2 |
| Slot | vPort | On/Off | Move | Delay ms |
|---|---|---|---|---|
| 1 | 220 | ▼🗑 | 1500 | |
| 2 | 221 | ▲▼🗑 | 1500 | |
| 3 | 500 | ▲🗑 | 0 | |
| … slots 4–16 empty | ||||
| 1. | vPort | 12 | is CLEAR | × |
| 2. | vPort | 501 | is CLEAR | × |
| 3. | vPort | is SET | × | |
| 4. | vPort | is SET | × |
Three slots, two conditions, one button. Slot 1 sets W-A through (so the train rolls past it without being diverted to P1). Slot 2 sets W-B straight (so the train continues into P2 rather than diverging down to P3). Slot 3 writes vP 500 = 1 — the “P2 is EB” flag — with zero delay because it's the last action of the route.
The conditions are the interesting bit. Both must be true for the slots to fire:
vP 12 is CLEAR — Platform 2 must currently be empty. Sending a second train into an occupied platform is always wrong.vP 501 is CLEAR — the “P2 is WB” flag must be off. If a west-bound train is already approaching P2 from the East throat, P2's flag will be SET to 1 by R4 even though vP 12 itself hasn't gone occupied yet. Without this condition, you could route an EB and a WB train into the same platform from opposite ends at the same time.The On condition fail = Drop setting is deliberate: if the operator presses the button at the wrong moment we want the action dropped immediately with a status-log line. Defer would invite a stale press to fire seconds later when the original intent is gone. The status log gets Route 2 dropped: condition 2 (vPort 501 is CLEAR) failed — the operator sees instantly why nothing happened.
Thirteen routes run the whole station: four reception (R1–R4), three brake re-arm (R5–R7) and six departure (R10–R13 plus two mirrored brake re-arms). Numbering is grouped by purpose with gaps so you can insert a starter-signal route per platform later without renumbering.
| # | Name | Enable vP | Edge | Conditions | Defer TTL | Slots (vP = val, delay ms) |
|---|---|---|---|---|---|---|
| 1 | Send EB to P1 | 3000 | SET | vP 11 is CLEAR | Drop | 220 = 1, 1500 · 221 = 0, 0 |
| 2 | Send EB to P2 | 3001 | SET | vP 12 is CLEAR AND vP 501 is CLEAR | Drop | 220 = 0, 1500 · 221 = 0, 1500 · 500 = 1, 0 |
| 3 | Send WB to P3 | 3002 | SET | vP 13 is CLEAR | Drop | 222 = 0, 1500 · 223 = 1, 0 |
| 4 | Send WB to P2 | 3003 | SET | vP 12 is CLEAR AND vP 500 is CLEAR | Drop | 222 = 0, 1500 · 223 = 0, 1500 · 501 = 1, 0 |
| 5 | P1 cleared — re-arm brake | 11 | CLEAR | — | — | 420 = 0, 0 |
| 6 | P2 cleared — re-arm brake & clear flags | 12 | CLEAR | — | — | 421 = 0, 100 · 500 = 0, 0 · 501 = 0, 0 |
| 7 | P3 cleared — re-arm brake | 13 | CLEAR | — | — | 422 = 0, 0 |
| 10 | Depart P1 east | 3010 | SET | vP 11 is SET AND vP 14 is CLEAR | Drop | 222 = 1, 1500 · 420 = 1, 0 |
| 11 | Depart P2 east | 3011 | SET | vP 12 is SET AND vP 500 is SET AND vP 14 is CLEAR | Drop | 222 = 0, 1500 · 223 = 0, 1500 · 421 = 1, 0 |
| 12 | Depart P3 west | 3012 | SET | vP 13 is SET AND vP 10 is CLEAR | Drop | 220 = 0, 1500 · 221 = 1, 1500 · 422 = 1, 0 |
| 13 | Depart P2 west | 3013 | SET | vP 12 is SET AND vP 501 is SET AND vP 10 is CLEAR | Drop | 220 = 0, 1500 · 221 = 0, 1500 · 421 = 1, 0 |
An east-bound parcels train is routed into P2 (the middle road). While it sits there a west-bound stopper arrives and is correctly diverted to P3 because P2 is locked east-bound. Both trains depart, P2 clears, and the station resets. Status-log lines shown verbatim where the router emits them.
| Time | Event | Route fired | Result on the bus / status log |
|---|---|---|---|
| t=0.0 | EB parcels enters West approach (vP 10 SET). Operator presses “Send EB to P2” (vP 3001). | R2 “Send EB to P2” | Route 2: P2 free and not WB-locked — throwing throat for east-bound to P2. |
| t=0.0 | R2 slot 1: W-A through. 1.5 s wait. | R2 | vP 220 = 0. Servo swings. |
| t=1.5 | R2 slot 2: W-B straight. 1.5 s wait. | R2 | vP 221 = 0. Servo swings. |
| t=3.0 | R2 slot 3: P2 EB flag SET. | R2 | vP 500 = 1. Status log: P2 reserved EB. |
| t≈8 | EB parcels rolls past W-B into Platform 2 (vP 12 SET). ABC brake already engaged from boot; loco coasts to a stop on the brake section, dead-centre of P2. | — | — |
| t≈30 | WB stopper enters East approach (vP 14 SET). Operator presses “Send WB to P2” (vP 3003). | R4 attempts to fire | Route 4 dropped: condition 2 (vPort 500 is CLEAR) failed. |
| t≈31 | Operator sees the diagnostic, presses “Send WB to P3” (vP 3002) instead. | R3 “Send WB to P3” | Route 3: P3 free — throwing throat for west-bound to P3. |
| t=31 | R3 slot 1: E-A through. 1.5 s. | R3 | vP 222 = 0. |
| t=32.5 | R3 slot 2: E-B diverge down. | R3 | vP 223 = 1. |
| t≈38 | WB stopper rolls into P3 (vP 13 SET). Brake holds it on the brake section. | — | — |
| — both trains parked, station is full — | |||
| t=120 | Operator dispatches the parcels east: “Depart P2 east” (vP 3011). | R11 “Depart P2 east” | Route 11: P2 EB and east approach clear — releasing east-bound from P2. |
| t=120 | R11 slot 1: E-A through. 1.5 s. | R11 | vP 222 = 0. |
| t=121.5 | R11 slot 2: E-B straight. 1.5 s. | R11 | vP 223 = 0. |
| t=123 | R11 slot 3: P2 brake released. Parcels accelerates east. | R11 | vP 421 = 1. |
| t≈128 | Parcels clears P2 (vP 12 CLEAR). R6 fires. | R6 “P2 cleared” | vP 421 = 0 (brake re-armed); vP 500 = 0; vP 501 = 0. Status log: P2 cleared — flags reset. |
| t≈145 | Operator dispatches the stopper west: “Depart P3 west” (vP 3012). | R12 “Depart P3 west” | West throat thrown for P3 exit, P3 brake released. |
| t≈152 | Stopper clears P3. R7 re-arms P3 brake. | R7 | vP 422 = 0. |
| t≈160 | Both trains have cleared the approach blocks. Station idle, P2 free for the next move from either direction. | — | — |
vP 12 is CLEAR wouldn't catch it because the EB train hasn't reached P2 yet (it's still on the approach at t≈1–5). Two trains would converge on the same platform from opposite directions. The flag vPort closes exactly this race.
Mega Sidings is an 8-road through fiddle yard with a mainline entering at each end: 8 parallel roads, 5 detection blocks each, accessed through a matching points ladder at both the west and east ends. Trains can:
The brake-release-on-departure is the same primitive used in the passing loop, but applied per-road. We'll add the option of disabling the brake when the next train is cleared to leave — useful when a non-stop train should sail through the yard from one mainline to the other.
The points-ladder is a binary tree: three "levels" of points get any incoming train onto one of eight roads with three servo movements. Buffer ends are on the far right. The last block on each road has an ABC brake section.
| Node | Qty | Channels used |
|---|---|---|
| S2-Route | 1 | The brain. |
| S2-IN32 (block detection) | 2 | 48 inputs: 4 west mainline + 4 east mainline + 40 road blocks. First board covers mainlines + roads 1–5; second covers roads 6–8 plus 11 spare. |
| S2-serv8 (points, west ladder) | 1 | 7 servos for the 7 west-ladder points (P1L, P2La, P2Lb, P3La, P3Lb, P3Lc, P3Ld) + 1 spare for the west home signal. |
| S2-serv8 (points, east ladder) | 1 | 7 servos for the east-ladder points (P1R, P2Ra, P2Rb, P3Ra–d) + 1 spare for the east home signal. |
| S2-serv8 (starter signals) | 2 | 16 servos for the per-road starter signals (8 west-facing + 8 east-facing). |
| S2-Relay8 (ABC brakes) | 1 | 8 relays: one per road. Brake section sits in the middle block (B3) so the train can stop here whether arriving from the west or the east. |
| S2-Panel (optional) | 0–1 | Operator console: 32 buttons (8 receive-from-west, 8 receive-from-east, 8 depart-to-west, 8 depart-to-east) plus one "override brake" latch. |
| vPort | Function | Device |
|---|---|---|
| 1001–1004 | West mainline approach blocks W1–W4 (W1 = far, W4 = at west home signal) | S2-IN32 #1 |
| 1005–1008 | East mainline approach blocks E1–E4 (E1 = at east home signal, E4 = far) | S2-IN32 #1 |
| 1101–1105 | Road 1 blocks B1–B5 (B1 = west end, B3 = brake section, B5 = east end) | S2-IN32 #1 |
| 1201–1205 | Road 2 blocks | S2-IN32 #1 |
| 1301–1305 | Road 3 blocks | S2-IN32 #1 |
| 1401–1405 | Road 4 blocks | S2-IN32 #1 |
| 1501–1505 | Road 5 blocks | S2-IN32 #1 (33 inputs used) |
| 1601–1605 | Road 6 blocks | S2-IN32 #2 |
| 1701–1705 | Road 7 blocks | S2-IN32 #2 |
| 1801–1805 | Road 8 blocks | S2-IN32 #2 |
| 2000 | West ladder P1L (Roads 1–4 vs 5–8) | S2-serv8 #1 ch 1 |
| 2001 | P2La (Roads 1–2 vs 3–4) | S2-serv8 #1 ch 2 |
| 2002 | P2Lb (Roads 5–6 vs 7–8) | S2-serv8 #1 ch 3 |
| 2003–2006 | P3La–P3Ld (final pair-selectors west ladder) | S2-serv8 #1 ch 4–7 |
| 2010 | East ladder P1R (Roads 1–4 vs 5–8) | S2-serv8 #2 ch 1 |
| 2011 | P2Ra (Roads 1–2 vs 3–4) | S2-serv8 #2 ch 2 |
| 2012 | P2Rb (Roads 5–6 vs 7–8) | S2-serv8 #2 ch 3 |
| 2013–2016 | P3Ra–P3Rd (final pair-selectors east ladder) | S2-serv8 #2 ch 4–7 |
| 2100 | West home signal (protects the west throat; faces eastbound trains entering) | S2-serv8 #1 ch 8 |
| 2110 | East home signal (protects the east throat; faces westbound trains entering) | S2-serv8 #2 ch 8 |
| 2101–2108 | West-facing starter signals Road N (allows train on Road N to depart westward; one per road) | S2-serv8 #3 ch 1–8 |
| 2111–2118 | East-facing starter signals Road N (allows train on Road N to depart eastward; one per road) | S2-serv8 #4 ch 1–8 |
| 2200–2207 | Road N brake relay (B3 ABC brake section) | S2-Relay8 ch 1–8 |
| 3010–3017 | Operator button "Receive from west into Road N" | Panel button OR web UI |
| 3018–3025 | Operator button "Receive from east into Road N" | Panel button OR web UI |
| 3030–3037 | Operator button "Depart from Road N to the west" | Panel button OR web UI |
| 3038–3045 | Operator button "Depart from Road N to the east" | Panel button OR web UI |
| 3050 | "Disable brake on next departure" override toggle | Panel button (latching) |
Each "into / out of Road N" requires three points thrown on the relevant ladder. The binary index of the road, mapped to (P1, P2L/P2R, P3a/b/c/d), is identical for the west and east sides — same bit pattern, different physical servos.
| Road | P1 | P2(a) | P2(b) | P3a | P3b | P3c | P3d |
|---|---|---|---|---|---|---|---|
| Road 1 | 0 | 0 | — | 0 | — | — | — |
| Road 2 | 0 | 0 | — | 1 | — | — | — |
| Road 3 | 0 | 1 | — | — | 0 | — | — |
| Road 4 | 0 | 1 | — | — | 1 | — | — |
| Road 5 | 1 | — | 0 | — | — | 0 | — |
| Road 6 | 1 | — | 0 | — | — | 1 | — |
| Road 7 | 1 | — | 1 | — | — | — | 0 |
| Road 8 | 1 | — | 1 | — | — | — | 1 |
Ten groups: one per road plus one for each mainline approach. The mainline-approach groups are dual-purpose — "is there a train waiting to come in?" (SET test) and "is the path clear for departure?" (CLEAR test).
| # | Name | Range | Status | |
|---|---|---|---|---|
| 1 | West Approach | 1001–1004 | ● CLEAR | edit |
| 2 | East Approach | 1005–1008 | ● CLEAR | edit |
| 3 | Road 1 | 1101–1105 | ◐ OCCUP. | edit |
| 4 | Road 2 | 1201–1205 | ● CLEAR | edit |
| 5 | Road 3 | 1301–1305 | ◐ OCCUP. | edit |
| 6 | Road 4 | 1401–1405 | ● CLEAR | edit |
| 7 | Road 5 | 1501–1505 | ● CLEAR | edit |
| 8 | Road 6 | 1601–1605 | ◐ OCCUP. | edit |
| 9 | Road 7 | 1701–1705 | ● CLEAR | edit |
| 10 | Road 8 | 1801–1805 | ● CLEAR | edit |
With symmetric entry/exit there are five route classes per road:
That's 5 × 8 = 40 routes for the basic yard, well under the 100-route limit. We'll detail the Road 1 set; copy the pattern for roads 2–8 with the substitution table below.
Operator presses the "Receive from west into Road 1" panel button (vP 3010). Conditions check that Road 1 is empty and the west approach actually has a train waiting. Slots throw the three west-ladder points to route into Road 1, then clear the west home signal.
| Route | Default Delay ms |
Enable vPort |
Feedback vPort |
RFID vPort |
Route Name |
|---|---|---|---|---|---|
| 1▲▼ | 2000 | 3010 | Receive from west to R1 |
| Slot | vPort | On/Off | Move | Delay ms |
|---|---|---|---|---|
| 1 | 2000 | ▼🗑 | 2000 | |
| 2 | 2001 | ▲▼🗑 | 2000 | |
| 3 | 2003 | ▲▼🗑 | 2000 | |
| 4 | 2100 | ▲▼🗑 | 100 | |
| 5 | ▲🗑 | |||
| … slots 6–16 empty | ||||
| 1. | Group | 3 | is CLEAR | × |
| 2. | Group | 1 | is SET | × |
| 3. | vPort | is SET | × | |
| 4. | vPort | is SET | × |
Mirror of R1, but for an eastbound train arriving at the east throat. Uses the east-ladder points (P1R, P2Ra, P3Ra) and the east home signal.
| Route | Default Delay ms |
Enable vPort |
Feedback vPort |
RFID vPort |
Route Name |
|---|---|---|---|---|---|
| 2▲▼ | 2000 | 3018 | Receive from east to R1 |
| Slot | vPort | On/Off | Move | Delay ms |
|---|---|---|---|---|
| 1 | 2010 | ▼🗑 | 2000 | |
| 2 | 2011 | ▲▼🗑 | 2000 | |
| 3 | 2013 | ▲▼🗑 | 2000 | |
| 4 | 2110 | ▲▼🗑 | 100 | |
| 5 | ▲🗑 | |||
| … slots 6–16 empty | ||||
| 1. | Group | 3 | is CLEAR | × |
| 2. | Group | 2 | is SET | × |
| 3. | vPort | is SET | × | |
| 4. | vPort | is SET | × |
Auto-fires when the middle block of Road 1 (B3 = vP 1103) goes SET. The brake snaps on, stopping the train mid-road. Direction-agnostic: works whether the train arrived from the west or the east, because B3 is detected the same way either way.
Both home signals are stamped back to RED — the throat is no longer "cleared" for this incoming train, so neither side accidentally accepts another arrival down the same road.
| Route | Default Delay ms |
Enable vPort |
Feedback vPort |
RFID vPort |
Route Name |
|---|---|---|---|---|---|
| 3▲▼ | 100 | 1103 | R1 brake on at B3 |
| Slot | vPort | On/Off | Move | Delay ms |
|---|---|---|---|---|
| 1 | 2200 | ▼🗑 | 100 | |
| 2 | 2100 | ▲▼🗑 | 100 | |
| 3 | 2110 | ▲▼🗑 | 100 | |
| 4 | ▲🗑 | |||
| … slots 5–16 empty | ||||
| 1. | vPort | is SET | × | |
| 2. | vPort | is SET | × | |
| 3. | vPort | is SET | × | |
| 4. | vPort | is SET | × |
Operator presses "Depart Road 1 westbound" (vP 3030). Conditions: a train must be present on Road 1 (group SET) and the west approach must be clear (no incoming train using the throat). Slots throw the west ladder back out to Road 1, clear the west-facing starter signal, release the brake.
| Route | Default Delay ms |
Enable vPort |
Feedback vPort |
RFID vPort |
Route Name |
|---|---|---|---|---|---|
| 4▲▼ | 2000 | 3030 | R1 depart westbound |
| Slot | vPort | On/Off | Move | Delay ms |
|---|---|---|---|---|
| 1 | 2000 | ▼🗑 | 2000 | |
| 2 | 2001 | ▲▼🗑 | 2000 | |
| 3 | 2003 | ▲▼🗑 | 2000 | |
| 4 | 2101 | ▲▼🗑 | 2000 | |
| 5 | 2200 | ▲▼🗑 | 100 | |
| 6 | ▲🗑 | |||
| … slots 7–16 empty | ||||
| 1. | Group | 3 | is SET | × |
| 2. | Group | 1 | is CLEAR | × |
| 3. | vPort | is SET | × | |
| 4. | vPort | is SET | × |
Mirror of R4 for an eastbound departure. Uses the east ladder and the east-facing starter signal.
Same five routes per road (40 routes total for the basic yard), with these substitutions for road N:
| What changes | Road 1 (template) | Road N (substitution) |
|---|---|---|
| Arrival button (from west) | 3010 | 3010 + (N−1) |
| Arrival button (from east) | 3018 | 3018 + (N−1) |
| Departure button (to west) | 3030 | 3030 + (N−1) |
| Departure button (to east) | 3038 | 3038 + (N−1) |
| Mid-block (B3, engage brake trigger) | 1103 | (1000 + N×100) + 3 |
| West-facing starter | 2101 | 2101 + (N−1) |
| East-facing starter | 2111 | 2111 + (N−1) |
| Brake relay | 2200 | 2200 + (N−1) |
| Road group | #3 | #(N+2) |
| West-ladder points (slots 1-3 of R1/R4) | P1L=0, P2La=0, P3La=0 | see binary table in §6.4 |
| East-ladder points (slots 1-3 of R2/R5) | P1R=0, P2Ra=0, P3Ra=0 | see binary table in §6.4 |
By default the brake engages the moment a train hits B3, stopping it dead-centre of the road. That's what most operators want — the yard parks the train cleanly for storage. But with the symmetric layout it's natural to also use the yard as a through-running route: a non-stop train enters from one side, sails through a chosen road, exits the other side, never stops.
For that we use the same "Disable brake on next departure" pattern, applied at the moment the train reaches B3 rather than at departure time. Set the panel toggle vP 3050 BEFORE the train arrives; the train enters B3, the auto-brake route (R3) is shadowed by an override route (R6) that fires concurrently:
| Route | Default Delay ms |
Enable vPort |
Feedback vPort |
RFID vPort |
Route Name |
|---|---|---|---|---|---|
| 6▲▼ | 100 | 1103 | R1 brake-disable override |
| Slot | vPort | On/Off | Move | Delay ms |
|---|---|---|---|---|
| 1 | 3050 | ▼🗑 | 100 | |
| 2 | 2200 | ▲▼🗑 | 100 | |
| 3 | ▲🗑 | |||
| … slots 4–16 empty | ||||
| 1. | vPort | 3050 | is SET | × |
| 2. | vPort | is SET | × | |
| 3. | vPort | is SET | × | |
| 4. | vPort | is SET | × |
1 (released). The router fires routes in numerical order, so set R6 to a HIGHER number than R3 — R6's brake-release write lands AFTER R3's brake-engage write, so the net effect is "released". If you reverse the order, the train will stop on B3 anyway.
22:00–06:00) so the override activates after hours without anyone touching a button. Trains arriving in B3 outside the window engage the brake normally; arrivals inside the window sail through.
An eastbound train approaches the west throat. Operator picks Road 4 (it's empty). After a session break, the train is dispatched onwards to the east. Status-log lines shown verbatim.
| Time | Event | What fires | Status log line |
|---|---|---|---|
| t=0.0 | Eastbound train enters W1 (vP 1001) | nothing (west home already RED) | — |
| t≈3.0 | Train at W3, slowing. Operator presses "Receive from west to R4" (vP 3013). | R31 "Receive from west to R4" fires. | Route 31: West ladder set for Road 4; clear west home. |
| t=3.0 | R31 slot 1: P1L OFF (Roads 1–4). 2 s wait. | vP 2000 = 0 | — |
| t≈5.0 | R31 slot 2: P2La ON (Roads 3–4). 2 s. | vP 2001 = 1 | — |
| t≈7.0 | R31 slot 3: P3Lb ON (Road 4). 2 s. | vP 2004 = 1 | — |
| t≈9.0 | R31 slot 4: West home CLEAR. Train accelerates. | vP 2100 = 1 | — |
| t≈12.0 | Train clears W4, enters B1 of Road 4 (vP 1401). | — | — |
| t≈14.0 | Train enters B2 (vP 1402). | — | — |
| t≈15.5 | Train enters B3 (vP 1403). R33 auto-fires. | R33 "R4 brake on at B3" | Route 33: brake engaged, both homes red. |
| t≈16.0 | Loco brakes to a stand on the ABC section, dead-centre of Road 4. | — | Train parks mid-road. |
| — session break, train sits parked for 20 min — | |||
| t=1200 | Operator decides to dispatch eastbound. Presses "Depart R4 to east" (vP 3041). | R35 "R4 depart eastbound" | Route 35: East ladder set; east starter clear; brake release. |
| t=1200 | R35 slot 1: P1R OFF. 2 s. | vP 2010 = 0 | — |
| t=1202 | R35 slot 2: P2Ra ON. 2 s. | vP 2011 = 1 | — |
| t=1204 | R35 slot 3: P3Rb ON. 2 s. | vP 2014 = 1 | — |
| t=1206 | R35 slot 4: East-facing starter (R4) CLEAR. | vP 2114 = 1 | — |
| t=1208 | R35 slot 5: Road 4 brake RELEASED. Loco accelerates eastbound. | vP 2203 = 1 | — |
| t≈1215 | Train exits B5, crosses east ladder, enters E1 (vP 1005). | — | — |
Note the symmetry: this same train could equally have been dispatched back to the west (R34 instead of R35), in which case it would have used the WEST ladder + west-facing starter. Roads in a through yard genuinely behave as bidirectional sidings.
Operator pre-sets vP 3050 (the brake-disable override) and the east-facing starter for Road 4 BEFORE the train arrives. The arrival sequence becomes:
A four-road fiddle yard that exits through a three-point ladder. Each road carries its own sense block; firing a route now writes two point positions in sequence so the train's path is set all the way from its road to the single exit road.
This is the configuration to reach for when you want a small staging yard (3 to 6 roads, typically) without the dispatcher, brake-control and signalling apparatus of the §6 Mega Sidings build. No conditions, no chains — just one route per road that throws every point on the train's exit path.
Each of the four roads carries a sense block in the same vertical band — the detection zone. The two ladder points fan in to short trunk sections; a third point merges those trunks onto the single exit road. Trains travel left → right.
Still only three System 2 nodes — the same parts as the simple example, just using more channels.
| Node | Qty | Channels used | Role |
|---|---|---|---|
| S2-Route — Route Processor | 1 | — | The brain. Holds the four routes that throw the ladder points. |
| S2-Mini Panel (8 inputs + 8 outputs) | 1 | 4 of 8 inputs | Block-occupancy detection on the four sense blocks. Four spare inputs and all eight outputs remain. |
| S2-serv8 (8-channel servo driver) | 1 | 3 of 8 servos | Drives the upper ladder, lower ladder and exit-point motors. Five spare channels for signals, semaphore arms or future points. |
Four detection inputs in the low 10s, three point servos on the 200 series.
| vPort | Function | Device | Semantics |
|---|---|---|---|
| 10 | R1 sense block | S2-Mini Panel input | 1 = train present, 0 = clear |
| 11 | R2 sense block | S2-Mini Panel input | 1 = train present, 0 = clear |
| 12 | R3 sense block | S2-Mini Panel input | 1 = train present, 0 = clear |
| 13 | R4 sense block | S2-Mini Panel input | 1 = train present, 0 = clear |
| 200 | Upper ladder point (R1/R2 merge) | S2-serv8 servo | 0 = aligned to R1, 1 = aligned to R2 |
| 201 | Lower ladder point (R3/R4 merge) | S2-serv8 servo | 0 = aligned to R3, 1 = aligned to R4 |
| 202 | Exit point (upper/lower trunk merge) | S2-serv8 servo | 0 = aligned to upper trunk, 1 = aligned to lower trunk |
Four routes, two slots each. Each route writes both of the points on the exit path for its road. The two slots fire in immediate succession — the engine staggers consecutive slots by at least 50 ms (this route sets an explicit 100 ms gap). Because the two points are driven by different physical channels, that fraction-of-a-second stagger is imperceptible, so the servos appear to swing together.
| Route | Trigger | Slot 1 | Slot 2 | Effect |
|---|---|---|---|---|
| R1 — Exit via R1 | vP 10 rise | vP 200 ← 0 DLY 100 ms |
vP 202 ← 0 DLY 100 ms |
Upper ladder → R1, exit point → upper trunk. |
| R2 — Exit via R2 | vP 11 rise | vP 200 ← 1 DLY 100 ms |
vP 202 ← 0 DLY 100 ms |
Upper ladder → R2, exit point → upper trunk. |
| R3 — Exit via R3 | vP 12 rise | vP 201 ← 0 DLY 100 ms |
vP 202 ← 1 DLY 100 ms |
Lower ladder → R3, exit point → lower trunk. |
| R4 — Exit via R4 | vP 13 rise | vP 201 ← 1 DLY 100 ms |
vP 202 ← 1 DLY 100 ms |
Lower ladder → R4, exit point → lower trunk. |
vP 200 ← 0. This is harmless — the servo doesn't re-swing if commanded to its current position — and it makes the route self-contained: from any prior state of the ladder, firing R1 leaves the exit path correctly set for R1 with no dependency on history.
A typical exit from R3 with the ladder set the wrong way (previous train came out of R1):
vP 201 ← 0 — the lower ladder begins swinging to R3.vP 202 ← 1 — the exit point begins swinging to the lower trunk.Note that vP 200 (the upper ladder) was never touched — it stays set to R1 from the previous operation. That's fine: no train is on the upper trunk and nothing about the R3 exit cares where the upper ladder is pointing.
is CLEAR" with Defer 10 s on each route, so a train won't be released into the back of another train still occupying the exit road. This is the first interlock and is independent of which road is exiting.Everything so far has been OCS operation (One Control Switch): each route has one button, and pressing it fires that one route. OCS is perfect when a move has a single obvious path — a passing loop, a fiddle-yard exit. There is nothing for the operator to choose, so one button is all you need (and an entrance/exit gesture there would be pointless — the straight road between two buttons is simply the shortest route, which a single OCS button already sets).
NX (eNtrance–eXit) earns its keep somewhere quite different: a junction or station throat with many ways in and many ways out, where each approach can reach several platforms and each platform can be reached from several approaches. The operator joins the dots — presses the button at the line they are coming from and the button at the platform (or line) they want to go to — and the interlocking looks up and sets the one route between that pair.
The win is combinatorial. With N entrances and M exits there can be up to N×M routes, but the panel needs only N+M buttons — one per place a train can enter or leave. A four-platform throat fed by three lines is a dozen-odd routes from seven buttons, and the operator never hunts for “the Platform-3-from-the-Down-Main button”: they press Down Main, then Platform 3. The same seven buttons set departures too (platform → line), so a handful of buttons compose dozens of routes.
The NX layer sits on top of the existing engine: occupancy reuses each route's Conditions (§3.4), the points and signals are driven by the route's ordinary slots, and only the gesture + locking are new.
The smallest layout where NX actually means something: a station approached by two lines — Main and Branch — that share a single lead through the throat to two platforms, P1 and P2. A point PA selects which approach line is connected to the lead; a point PP selects which platform the lead feeds. Either line can reach either platform, so there are four arrival routes.
This is why you need both buttons: pressing Main alone is ambiguous (P1 or P2?), and pressing P1 alone is ambiguous (from Main or Branch?). Neither end on its own identifies a route — the entrance+exit pair does.
vPorts. Points PA=201, PP=202. Approach aspects Main=211, Branch=212. Mimic entrance buttons Main=5211, Branch=5212; exit buttons P1=5221, P2=5222. Detectors: throat 810, P1 811, P2 812. Route-light lamps 251–254 (one per route).
The four routes. One ordinary route per (entrance, exit) pair; each route's slots set the two points and clear the approach signal, its Condition is “target platform CLEAR and throat CLEAR”, and its NX block names the entrance and exit buttons.
| Route | Entrance (in) | Exit (out) | Slots (points + signal) | Condition |
|---|---|---|---|---|
| 1 Main→P1 | 5211 Main | 5221 P1 | PA→N, PP→N, Main→clear | P1 CLEAR, throat CLEAR |
| 2 Main→P2 | 5211 Main | 5222 P2 | PA→N, PP→R, Main→clear | P2 CLEAR, throat CLEAR |
| 3 Branch→P1 | 5212 Branch | 5221 P1 | PA→R, PP→N, Branch→clear | P1 CLEAR, throat CLEAR |
| 4 Branch→P2 | 5212 Branch | 5222 P2 | PA→R, PP→R, Branch→clear | P2 CLEAR, throat CLEAR |
Notice entrance 5211 (Main) appears on two routes and exit 5221 (P1) appears on two routes — that overlap is exactly what makes a single button ambiguous and the pair unambiguous.
Walkthrough.
NX route 2 SET (5211->5222).Now the real thing. A through station whose west throat is fed by three lines — Up Main (UM), Down Main (DM) and a Goods Loop (GL). All three merge into a common throat lead, and a single point ladder fans that lead out to every one of the four platforms, P1–P4. So any line can be routed to any platform — twelve possible arrival routes — and the operator simply joins the dots between the line they are on and the platform they want.
Every line merges into the throat lead, and the ladder fans the lead to every platform — so any of the three entrance buttons pairs with any of the four exit buttons. 3 × 4 = 12 arrival routes, from just 3 + 4 = 7 buttons.
The route matrix. With this throat every line reaches every platform, so all twelve pairs are valid routes:
| from ↓ to → | P1 | P2 | P3 | P4 |
|---|---|---|---|---|
| Up Main (6311) | ✓ | ✓ | ✓ | ✓ |
| Down Main (6312) | ✓ | ✓ | ✓ | ✓ |
| Goods Loop (6313) | ✓ | ✓ | ✓ | ✓ |
Twelve arrival routes from 3 + 4 = 7 buttons. With OCS you would wire twelve dedicated route buttons; add the twelve departures (platform → line at the east end) and OCS needs twenty-four, while the NX panel composes them all from fourteen buttons — seven at each end of the station. The exit buttons are P1=6321…P4=6324; the ladder points are 301…304 (one per platform); platform detectors 821–824, throat lead 820.
Walkthrough. This throat has a single lead, so it carries one move at a time and the lock serialises requests — exactly what the interlocking is for. (A larger station has several leads; the lock table then grants any moves that don't share a point set the other way, so they run in parallel.)
NX route N SET (6311->6323).A button-pair you have not built returns NO_ROUTE and the panel does nothing — there is no path-finding, so the interlocking can never invent a move you did not define.
There is no special “NX mode”: you build each route exactly as an ordinary route — slots that throw the points and clear the signal, a Condition for occupancy — and then, in the route editor's NX (Entrance / Exit) block, tick Enable NX and name the entrance and exit button vPorts (and optionally a route-light vPort and an auto-release detector vPort). One route per cell of the matrix. Save Routes. The editor warns if two routes claim the same entrance/exit pair (a duplicate — the lowest route id wins). The global pair-window / confirm-hold / cancel settings sit in the NX Live Monitor and can stay at their defaults.
Choosing: reach for OCS (one button per route) when the move has a single obvious path or there are only a few routes; reach for NX when a throat has several entrances and several exits, so a single button can't identify the move. The two coexist freely — an NX-enabled route is still a perfectly ordinary route that can also be fired by its enable vPort, a timer, RFID or a chain.
The gesture, the lock table and the denial reasons all run on the main loop — no new task, no blocking, no extra heap; every NX structure is a fixed RAM array. NX runtime state is RAM-only and rebuilt empty on boot, so after a power cycle every route comes up free and the operator re-sets the throat, exactly like a real panel returning from a supply interruption. The per-route NX fields ride inside /routes.bin (preserved across firmware OTA); the global timing lives in NVS (survives OTA, rollback and recovery).
Both examples can be wired up on a bench — signals, points, brake relays, and block-detector dummy inputs — and tested by typing trigger events into the router's web console:
1 (use another node, or a CAN frame generator) and watch the group status flip to OCCUP.... dropped: condition #N failed for routes that should have eventually succeeded. 5 s is plenty for express passenger but tight for a 30-wagon goods.is CLEAR fails on UNKNOWN. Solution: configure your block detectors to heartbeat their state every ~60 s, or briefly occupy each block on layout startup to "seed" the cache.Trigger vPort = the input vPort for that detection block. Trigger edge = rise. Condition (optional) = the train's expected approach blocks must be SET so a glitch in detection doesn't fire the route.
Trigger vPort = the input vPort. Trigger edge = fall. Use for "train cleared the loop", "starter signal reset", "release a downstream interlock".
Add a condition: the "path ahead" block group is CLEAR. Use Defer 10–15 s on fail so a slow upstream train clearing the path doesn't lose the trigger.
Use the Chain field. The chained target is independently gated — if its own conditions fail, it defers or drops without affecting the upstream route.
Three slots, two non-zero delays. Slot 1 throws points, DLY 2000 ms. Slot 2 clears the signal, DLY 2000 ms. Slot 3 releases the brake, DLY 100 ms (last slot's DLY is irrelevant).
Signal hardware powers up with vPort = 0 (RED). No route needed for the default state. Add a defensive "stop on arrival" route that re-stamps the signal to 0 when a train approaches, in case anything earlier left it at 1.
Same pattern as the signal. Relay coil de-energised on power-up = brake engaged. Defensive "stop on arrival" route confirms the brake is on. Departure route flips it to 1 (released).
Wire a panel button to a vPort. Use it as a route trigger directly, OR as a condition (vPort N is SET) on multiple routes — effectively a "permission" or "interlock" toggle.
Add a schedule (start HH:MM, end HH:MM) to any route you want to fire only during operating hours. Triggers outside the window are dropped with a status-log entry.