Searchlight panel is a custom turnout control panel for a friend's layout.
Building a control panel for a large layout requires a lot of wiring. Each remotely controlled turnout requires at least 2 or 3 wires, plus wiring for the LED indicators. This rapidly multiplies into a "rats nest" for even moderately large layouts. My friend's layout has 27 individual turnouts and 4 crossovers, totalling 31 control points. Handling all 31 control points with a single CDU and a set of SPDT switches (using a common return bus wire) will require some 62 wires be run from the panel to the layout.
As an additional feature, my friend wants a wall-mounted LED track schematic display. This will require an additional 62 wires (or more) be run from the control panel to the display panel, if all is done the "simple" way.
There are probably more efficient ways of handling this, in terms of the wiring.
My solution is to introduce a microcontroller into the mix. The micro will use an addressing scheme and a time-multiplexed signal bus (or a set of them, really) to cut down the wiring being passed around. A second simple microcontroller in the display panel will manage the LED display.
The turnouts will be directly driven by small driver cards that handle eight turnouts each. Each card will have an assigned address, and will share an 8-bit control bus back to the micro. The driver cards could each contain their own local CDU (and I may design the board that way), but there will also be provision for a single master CDU for all the turnouts.
The control panel switches will be wired via a bus as inputs to the micro in groups of 8. The micro will poll each group of 8 switches in round-robin fashion to check the position of each switch. When a change in switch position is detected, the micro will address the correct driver card and turnout. This will trigger a FET switch that will direct the CDU output to the correct turnout. At the same time, the micro will send a message to the LED display controller to update the display.
At boot time, it is possible that someone may have manually changed a turnout position. To account for this, the display controller will keep track of which turnouts have been moved since the last time it was powered on. At boot time, for each turnout, it will either light both LEDs or neither, to indicate that the turnout position is unknown. Each time it receives a "turnout change message", it will update its status and light the correct LED for the turnout position. In this fashion the user will be warned of the unknown state at boot, and this will be automatically updated as operations progress.
Note that this is not foolproof. The system still cannot detect if someone manually changes a turnout while the system is active. This issue will have to be addressed in the operating rules for the layout, as without some form of feedback from the turnouts (which is not available at this time), run-time manual turnout moves cannot be detected.
Here are proposed definitions for the various buses in the system
All defined bus cables are multi-wire flat ribbon cable with IDC headers. Standard spec is 24ga. but larger wire is allowable. Cable connectors are 0.10" dual row IDC female, mating to matching pin-headers on the boards.
The switch input bus is a 16-pin ribbon cable that connects all of the switch input boards in parallel to the microcontroller. Each switch input board provides 8 inputs, and has a unique bus address (set by DIP switches on the board). The bus is an 8-bit data, 4-bit address bus allowing up to 16 boards, or 128 switches.
The bus is clocked, and operates in a simple master-slave relationship. The processor (master) sets the address and R/W bits, and pulses the CLK. At the CLK high, the input board either latches the value on the DATA lines (R/W == W) or drives the value of its input pins onto the DATA lines (R/W == R). When CLK falls, the input board reverts the DATA lines to a tri-state condition.
Pin Description
1
+5V
2
DATA_0
3
DATA_1
4
DATA_2
5
DATA_3
6
DATA_4
7
DATA_5
8
DATA_6
9
DATA_7
10
Addr 0
11
Addr 1
12
Addr 2
13
Addr 3
14
CLK
15
R/W
16
GND
Logic HIGH indicates diverging route (switch is thrown), LOW indicates main line route (switch is closed).
A lower-pin-count alternate is a SPI-bus based design, still with multi-bit decoded addressing:
Pin Description
1
+5V
2
MISO
3
MOSI
4
SCLK
5
GND
6
Addr 0
7
Addr 1
8
Addr 2
9
Addr 3
10
GND
This version still supports 16 boards (total 128 switches), but does so with only a 10-wire cable, instead of 16. Typically, SPI uses separate chip selects for each slave. That would be a bit of a mess here. Since I'm using custom-made slave devices, the chip select will be decoded by the slave on-board. To connect a "standard" SPI slave (whatever that is), an address decoder (and some form of assigning an address) would have to be added to that slave, but it would otherwise work as expected.
Pros:
Cons:
An even smaller bus can be configured, if the Master device can be told how many slave devices are installed, so it knows how many bits to shift out. This could be done with a DIP switch or rotary encoder on the master board.
Pin Description
1
+5V
2
MISO
3
MOSI
4
SCLK
5
SSn
6
GND
In this case, the boards are all connected in daisy chain fashion (each board's MOSI is the next board's MOSI). The master clocks however many bits it expects to see (as indicated by the "how many boards" setting). If there are 4 boards installed, the master will clock 32 bits, and gather the switch states of all 4 boards in one read.
The daisy chain can be single-ended if the last board has a jumper set or installed to loop back the return path (I think)
Pros:
Cons:
This bus runs from the microcontroller to the output modules. Each output module has an assigned address, and responds only if the address lines match its address. This bus is clocked. Changes are only made on the rising edge of the CLK line (which is really a latch enable).
The bus transaction appears as follows:
When CLK is driven high, the CDU output is routed to the appropriate turnout output. When CLK goes low, all outputs are disconnected from the CDU.
A "digital safe" version of the CDU pulse is returned to the processor via the CDU_FB pin, for timing. The processor will not issue another pulse until a specified recharge time after the previous pulse.
Alt: A "digital safe" version of the CDU pulse is routed as an input to the module logic, and the outputs are not disconnected until the pulse itself is finished. This makes the clock rising-edge-only.
Pin Description
1
+5V
2
CDU_POS
3
CDU_GND
4
OP_ADDR_0
5
OP_ADDR_1
6
OP_ADDR_2
7
BD_ADDR_0
8
BD_ADDR_1
9
BD_ADDR_2
10
BD_ADDR_3
11
Reserved
12
TO_POS
13
CLK
14
CDU_FB
15
GND
16
GND
BD_ADDR selects an output module from among all the modules on the bus. OP_ADDR selects one of the 8 outputs on the selected module. TO_POS contains the new turnout position for that specific output. CLK triggers the output change event, and CDU_POS/CDU_GND carries the CDU pulse. There is no memory on the output module.
The remote LED display board contains its own small microcontroller. This allows us to use a simple serial interface between the boards. Because of the possibly long cable routing, RS-232 +/-12V signaling will be used. We will evaluate whether a different, simpler interface could be used, since it is desirable to provide a LocoNet interface, and multiple UART microcontrollers are hard to find these days. Other options are SPI, I2C or CAN bus, or a simple clocked serial interface.
Pin Description
1
+5V
2
MC_TxD
3
MC_RxD
4
GND
MC_TxD and MC_RxD are defined from the perspective of the primary microcontroller. That is, the LED controller transmits on RxD and receives on TxD. This convention is indicated by the "MC_" prefix. +5V is supplied by the primary controller, and is optional. The LED controller need not use it.
The Input module provides the interface between the control panel switches and the main processor. Optionally, it will provide direct local LED feedback of the switch state.
The Input Module provides connection for up to eight electrical switches for controlling eight turnouts (or turnout pairs), as well as LED indicator outputs for local panel indication. It is designed to be installed inside a control panel and connected to a master control processor via a ribbon cable.
The control bus connects via a bus transceiver to the board logic. A 4-DIP selects the board address, which the processor uses to read the switch settings.
The switches are connected via a second ribbon cable (which can be separated for routing to the panel switches). Either SPDT or SPST switches can be used. For SPDT operation, the center lead of the switch is connected to the switch input, while +5V and GND are connected to the outer leads. When the switch is thrown, the board input is tied to +5V or GND, and the logic is able to read the switch position. For use with SPST switches, pullups to +5V are provided on the board. The switch is wired from the board input to GND, and the open position represents +5V.
By convention, +5V indicates the diverging turnout position (switch "thrown"), and GND indicates the "through" turnout position (switch "closed").
The processor continually polls all the boards on the ribbon cable bus. When the Input Module detects its own address on the bus, it will drive the current state of the switches onto the bus (or read the value sent by the processor), as described above in the bus interface documentation.
Local panel LEDs are automatically driven by the input switch position. Exact implementation is TBD.
Each Input Module on the bus must be assigned a unique address value by setting the DIP switches on the board. 16 different addresses are available. The address value of each Input Module must also match the address of a corresponding Output Module, and the input pins and output pins matched to ensure that a given input switch triggers the correct turnout.
For example, one must wire such that Switch #2 on Input Module #3 is mated to the turnout on Output #2 on Output Module #3.
I may choose to "daisy-chain" the input and output modules in such a way that the physical bus connections indicate the address numbers (first board in the chain is Address 1, and so on). At Power on, all the boards would disconnect their "downstream" bus connections. The processor then would go through a process of "discovering" and assigning addresses to each board in sequence. There are issues with this, though, and I'm not sure I want to go that way.