
Computers are ever more frequently used in model railroading, from DCC to full layout control. Computers lend themselves to smaller solutions, too, providing the modeler with easy ways to solve old problems. In this article, we will look at a small but capable computer solution for simple problems around the layout. We will then discuss a modified version for use in C/MRI systems.
A very popular microcontroller is the Intel MCS-8051, which has been around since the early 1980s. The 8051 family of devices contain entire computers on a single chip, combining CPU, memory, clock generators, timers, serial lines, and digital inputs and outputs. There is a large base of support for these devices, and documentation, assemblers, compilers, and operating systems are available.
New technologies have resulted in 8051-family devices that are faster and easier to work with. In particular, flash memory allows quick programming and reprogramming of these devices from your PC, making them easy to program even for the hobbyist. At about $6 apiece, the devices are also inexpensive enough to consider for multiple uses around the layout.
We used the Atmel 89C52 to construct a basic 89C52 platform which can be used to build sequencers, diode-matrix controllers, animation controllers, and other solutions for the layout, for a total parts cost of about $20. We then modified this basic platform to add an RS-485 serial port to build a single-board C/MRI-compatible control node, for a total parts cost of about $25. Both units are 3.75" square, giving them a very high functionality to size ratio.
In Figure 1, the basics we need to make the processor run are shown in blue. The 7805 regulator and capacitors C1 through C4 convert DC power from 8 to 15 volts to the regulated 5 volts required. The quartz crystal XTL1 and capacitors C5 and C6 provide the basic timing reference to allow the unit to generate its internal clock signal. Finally, capacitor C7 slows the rise of the reset signal when power is applied, resetting the processor to run the program from the beginning.

The 89C52 provides 32 pins that can each be programmed to be either an input or an output. On the basic platform, all of these pins are used as digital I/O. To use these pins as digital I/O, we need to provide pull-up resistors on the pins. We use four 10-kohm resistor networks that provide nine resistors apiece, which are shown in Figure 1 in red. We only need eight resistors per I/O byte, but the nine-resistor network is the most common to find and the cheapest to buy. The extra resistor in each network will be unused.
The I/O pins of the 89C52 have other uses as well, including serial lines and access to external memory. On the C/MRI-compatible platform, we have used three pins to provide the RS-485 serial line, and five more pins to provide 5 bits of address, giving the board a programmable 'identity' within the C/MRI system. The other 24 bits are each used as either input or output, as with the basic platform.
The 89C52 output pins can sink 1.6 milliamps for ports P1, P2, and P3, and 3.2 milliamps for port P0. That isn't a lot, as even a single LED or switch motor takes 10 to 20 milliamps. For most model railroad uses, the outputs will require more current capability. The output current capabilities of the 89C52 are augmented on both boards with transistors. The resulting current allows the unit to drive lamps, LEDs, relays, stall motor switch machines, and both common-cathode and common-anode signals without any additional components except dropping resistors.
In Figure 1, the 2N7000 MOSFET transistors we use for outpputs are shown in green. Thes transistors take the output of the 89C52 directly, and give 200 milliamps of current sink capability. That is 10 times what is required for an LED or a switch motor such as Circuitron's Tortoise or the Hankscraft stall motors. They also invert the output signal, so a '1' written by the processor connects the output to ground, while a '0' from the processor results in an open circuit.


The parts list in Table 1 includes part numbers and known sources for all parts. The part number with a double asterisk is the least expensive source that we know as we write this.

We have used Molex 0.156" connectors for the input, output, and power connections. These connectors are sturdy, reliable, and easily available to the hobbyist. We use connectors rather than direct soldered wire connections in order to make it easier to repair or replace a failed unit, but you can solder the wires directly to the board as well if you prefer.
We have placed traces for 2N7000 output transistors on every digital I/O pin. These transistors should not be used on digital I/O pins that are to be used as inputs. Install a 2N7000 on every digital I/O pin you will use as an output, and jumper past the 2N7000 location for every digital I/O pin you will use as an input, as shown in Figure 4.
Figure 5 shows how to wire up the outputs for most model railroad applications. The wiring for bulbs, LEDs, switch motors, relays and signals is shown. Be careful to include the 1N4001 diode across any relay coil. The circuit will work for a while without it, but the surge voltage of shutting off a coil will eventually destroy the 2N7000 output transistor.
Both common-positive and common-negative signal heads can be driven directly by the outputs of the unit. The common-positive (common-anode) case requires one dropping resistor, and LEDs are lighted by activating the R, G, or B leads. The common-negative (common-cathode) case requires three dropping resistors, and LEDs are lighted by releasing the /R, /G, or /B leads. That is, in the common-negative case, you should activate the outputs for the LEDs you wish to be turned off.
Switch machines are operated with pull-up resistors on both leads, and require one output for normal and one for reverse. This ensures that, when the unit is powered on, switch machines stay in their shut-off locations, and don't all go to normal (or reverse) when the 89C52 outputs initiate to '1's. It is possible to provide local control of switch machines using a third output, as shown in the diagrams. When the Normal and Reverse outputs are released, and the Local output is activated (driven to ground by the 2N7000), the local control switch will operate the switch machine.

To program code into the processor, either ours or your own, you will need the Iguana Labs PG302 programmer and adapter for programming the 89C52. This is a significant expense at $90, but it is a one-time expense no matter how many boards you build, and can be shared within a group or club.
We recommend the use of a zero-insertion-force socket, as the processor will be installed and removed from the board several times if you write and test your own program. The extra two sockets in Table 2 are to space the large ZIF socket off the board above the other components. When you have finished your program and have the board working to your satisfaction, remove the ZIF socket and the two spacer sockets and install the programmed 89C52 directly into the socket on the board.


In the programmable sequencer, all 32 I/O pins of the basic platform are used as outputs. Each of these can flash at different rates, at different duty cycles, and in different phases. The code contains a timing table that defines the operation of each output bit using three bytes. The first byte for each bit sets the delay until the first 'on', the second sets the 'on' time for each cycle, and the third sets the 'off' time for each cycle, in units of 1/10 second. When the unit is turned on, each unit will wait the specified delay, then turn on and off alternately for the specified on and off times.
The maximum time for each time period is 25.6 seconds using the pre-scaler value programmed into the sequencer code. Both longerr times and shorter increment can be accommodated by modifying the pre-scaler values as described in the comments in the software. The code has been tested using the existing pre-scaler values, but modifying the pre-scaler values to result in longer times should work fine. Modifying the pre-scaler values for much shorter increments will result in the processor having too little time to complete its work between pre-scaler timeouts.
In the diode-matrix controller, 8 I/O pins of the basic platform are used as inputs for route buttons, while 24 I/O pins are used as outputs: 8 outputs for LED indicators to show the valid routes, and 16 outputs connected to 8 stall motor switch machines, one output for normal and one for reverse for each switch machine. Figure 6 shows the wiring for a diode-matrix controller using the basic 89C52 platform. The pull-up resistors on the Tortoise motors have been left off this drawing for simplicity; see Figure 5 for details.

The code contains a control table that controls which outputs will be turned on, which turned off, and which unchanged by each pushbutton. The first three bytes for each pushbutton have a '1' for each of the twenty-four outputs that need to be turned on. The second three bytes for each pushbutton have a '1' for each of the twenty-four outputs that need to be turned off. To leave an output unchanged, both entries should be '0' for that output. The values contained in the control table in our code are for a simple yard ladder in which each track is reached by a single reversed switch machine off the main track. You should take some time to understand this table before attepting to generate the table for your own application.
Our basic 89C52 platform can be modified to look like a C/MRI control node, and operate on the same serial bus with C/MRI components. For this modification we have added two RS-422/485 driver chips and an address dipswitch to the basic 89C52 platform, giving up eight digital I/O pins. The 24 remaining digital I/O pins can each be used as either an input or an output, installing transistors in the outputs as before.

The circuit diagram of the C/MRI-compatible controller is shown in Figure 7, Figure 8 gives the circuit etch pattern, and Figure 9 gives the component placement diagram. The changes in the circuit diagram from the basic platform are shown in blue in Figure 7. The parts list in Table 3 includes part numbers and known sources for all parts.


The portion of the circuit diagram unchanged from the basic microcontroller is shown in black, while the changes are shown in blue. The transceivers provide serial communications to the bus of the C/MRI system, while the dipswitch is used to give the unit an address within the USIC address space of the C/MRI system. Construction of the board is as for the basic platform.
C/MRI input cards have 24 dedicated input pins, and C/MRI output cards have 24 dedicated output pins. We originally had a bit of a concern about mapping the configurable I/O pins of our unit into a protocol designed to handle 24-pin blocks of input and output. We solved that issue by treating the unit as if it were a USIC with one digital input card and one digital output card, both connected to the same 24 pins!

The biggest differences are that there is only one group of 24 input pins, equal to one digital input card, and one group of 24 output pins, equal to one digital output card, and that these 24 input pins and 24 output pins are overlaid. It is exactly as if there were one digital input card and one digital output card in the system, and their 24 pins were wired together.
This introduces one programming difference: when writing to the output pins, '1's need to be written to pins which serve as inputs, and when reading the input pins, the pins which serve as outputs should be ignored. This is not a big difference, as writing to any output pin must preserve the status of the other output pins on a C/MRI digital output card, and reading an input pin must ignore the other input pins on a C/MRI digital input card.
There is an advantage to this mechanism, as the central control computer can read back its own outputs, providing positive indication that the transmit packet has been received and acted upon.
The serial protocol used with C/MRI systems includes four kinds of packets. Compare Table 3 and the following packet descriptions to the discussion and tables on pages 187-198 of Bruce Chubb's book 'Build Your Own Universal Computer Interface'.
The I packets also tells the USIC in a C/MRI system how much to delay each byte sent back to the central control computer, to keep from overrunning the central control computer's ability to process the incoming information. We retain that feature in the I packet shown in Table 4. We also include the 'N' byte, which we set to '0' to indicate that no CT() bytes follow.

The units of delay set by the I packet differs somewhat from C/MRI systems. Due to the differences in architecture and speed of the processors, the units of delay in the microcontroller are approximately 1/2 microsecond compared to 10 microseconds in a C/MRI USIC. If your system requires a delay, mutliply the I packet value you are using for C/MRI USICs by 20 to get the proper setting for the same actual delay with the microcontroller.
Most recent computers require no delay in bytes received from a 57600 bits per second serial port. If no delay is required by your central control computer, the I packet need not be sent to the microcontroller.

While we can have up to 24 bits of outputs, some of those I/O pins will probably be used as inputs. We must send '1's for each bit in the packet that corresponds to an I/O pin on the enhanced microcontroller that is used as an input. This will ensure that the microprocessor will see an input that is grounded (held to '0') by an external device such as a detector.

The difference relates to the I/O pins being able to be used as either inputs or outputs. When inputs are requested, all three bytes, containing both inputs and outputs, are received in response. To avoid the misinterpretation of a change in output being seen as a change in input, it is recommended that the first step of processing received input bytes from the microcontroller be to 'mask off' the outputs by ORing '1's into the bit positions corresponding to I/O pins used as outputs.
Together with the requirement that output bits sent to I/O pins used as inputs be '1's in the T packet, as discussed above, we get a simple rule: output bits sent to I/O pins used as inputs should be set to '1' before transmitting them, and input bits received from I/O pins used as outputs should be set to '1' after receiving them. The masks used for these processes correspond to the wiring of the input and output pins of each microcontroller, and should be contained in an array with the address of the USIC or microntroller as the array index. The masks for USICs should be set to all '0's so that operation of C/MRI USICs is unaffected.
-- It is very small, allowing the unit to be placed closer to the input and output devices than C/MRI USICs, further distributing the system and reducing wiring.
-- It is very inexpensive, on the order of $1 per control point (either input or output), which puts it within the reach of almost anyone.
-- The I/O is flexible, allowing the I/O pins to each be assigned as an input or output, reducing wasted pins compared to fixed configurations.
-- Finally, the processor for this unit is programmable by the user, and the code is being distributed over the net, which means that the user can build, deploy and support the unit completely independently.
-- Programmable Sequencer (under development)
-- C/MRI-Compatible Controller
-- Test Software for the board, in Visual Basic