Train Controller

Z Scale model trains are extremely small, which makes them great for coffee table layouts. I have designed a fully web-based controller so that can be used with a phone, tablet or computer to wirelessly interact with any small scale train layout with up to 16 turnouts.

I started the project in 2013, as I wanted to get more seriously into the latest trends in HTML5 and javascript development, and used this as a way to make the whole process more fun.

There are two intended audiences for these articles: either electronics people who will probably laugh at the electronics part and hopefully provide me with insights, but still learn a thing or two about the software part. And software people, who will sneer at the way I architected the web app and server, but still learn about the electronics. And with everyone’s feedback, I certainly hope the end result will end up being decent!

The reason why I wrote all this, is that there are many tutorials on the web that cover tinkering with DIY electronics, even more that cover the multitude of libraries and frameworks that make web application development easier, but while they all provide great help to get to the “Hello World” stage, a lot of them fall short when it comes to providing guidance on how to create ‘real world’ complex applications.

This series aims to fill in the gap, since it will cover the following:

  • Design of a circuit to drive the small DC motors inside of Z-Scale locomotives using speed regulation, as well as drive ‘accessories’ such as turnouts.
  • Design of an embedded controller firmware using Arduino first, and Beaglebone second, to connect that circuit to a controlling computer
  • Design of a small server application that talks to the hardware controller
  • Design of a complete multi device web application that talks to the server and in turn to the train controller.

The whole series

Main design goals

It is always a good thing to have clear goals in mind when starting a project, it does help to keep focus and move faster. For this project, the goals were many:

  • The controller should drive one locomotive in both directions, and up to 16 accessories (turnouts etc)
  • The UI for the controller should be a web browser, and it should work on any device, especially mobile and tablet.
  • It should be flexible in order to support both simple analog trains, and also DCC later without having to restart from scratch
  • Speed control should be proper speed control, not simply power control.
  • The UI should be very simple to use, a simple finger/mouse slide to go faster/slower, and an easy way to control accessories
  • The controller should be able to track locomotive runtime, and maintenance logs
  • The controller should be self-contained in its final version (no computer needed to run it)
And as mentioned above, the idea was also to use state of the art Javascript and HTML5 tools for development.

Driving a small locomotive

One great thing with Z scale is that the power involved is fairly small: locomotives are powered with a 10V DC supply, and only ever need 2 to 3 watts for a well-maintained loco. This can raise to 5/6W for an old or not well oiled locomotive. This means that we won’t need to spend too much time worrying about power dissipation.

Speed control

There are several ways of controlling the speed of a small motor: you can either vary the voltage across the motor connectors, or use a fixed voltage, but only apply it part of the time. Most model train controllers do this, and use an unregulated DC voltage that looks like a half sine-wave, directly converted from AC by a diode, so the period of this unregulated voltage is 50Hz or 60Hz depending on location. It is also possible to just switch power on and off rapidly. In electronics terms, the latter is called “Pulse Width Modulation” or PWM. Basically, with a fixed signal period, you switch power on only a certain percentage of the period, which results in pulses that range from very narrow, to nearly on all the time. I chose this method to drive the motors:

  • It is very simple to implement using microcontrollers
  • The pulses actually help the locomotives run more smoothly (see references)


Model trains literature will tell you lots about how PWM is or is not good for loco motors: truth is, for the tiny motors of Z-Scale locomotives, as long as the controller does not make them heat up significantly, there’s nothing to worry about, really. During the hours and hours of testing my locos went through, I never had a single problem. If you want to learn more about train controllers, I recommend you head over to this article, which will teach you all you need to know and then some.

Motor driving with the L293D

A very popular chip used to drive small motors is the L293D, a chip that was created by SGS nearly 20 years ago. The L293D can be used to  drive motors in a “H-Bridge” configuration. Wikipedia explains what a H-Bridge is, and I won’t get into more details here, but the main point is that it enables you to easily drive a motor in both directions, using just a couple of logic signals. Moreover, the L293D can drive motors up to 600mA continuously and 1.2A peak, so its specs match what we need nicely. As is shown on the diagram below, from TI’s L293 datasheet, motors can be connected in various ways to this driver:

In our setup, we will use the L293D in a slightly unusual manner: rather than being connected to the first two half-bridges with the PWM signal applied to the “EN” pin, the motor will be connected between the first and the fourth half-bridges, so that we can manipulate both “EN” pins, as shown below:

Here is how the motor is driven:

1A EN1-2 4A EN3-4 Result 1Y 4Y
1 1 0 1 Motor run direction 1 V+ GND
1 0 0 1 Motor freewheel Z GND
0 1 1 1 Motor run direction 2 GND V+
0 1 1 0 Motor freewheel GND Z

The important thing to notice is that we freewheel the motor with one pole in high impedance, and one to the ground, in both directions. Why do we need that? This is because we want to measure the speed of our motor. Read on to understand!

Motor speed measurement

As mentioned in the design goals, we want our controller to regulate the speed of trains, not merely the power sent to the rails. This is similar  to the difference between a car’s throttle, and its cruise control. The performance of small locomotives varies a great deal depending on whether they are warm or not, which means that you will have to decrease the amount of power applied to a train a great deal as soon as it warms up, to achieve the same speed. Our controller needs to be able to do this by itself.

In order to achieve speed regulation, we need a way to measure train speed. It is not practical to modify locomotives, but there is fortunately another way to do this: as you probably learned in school, a motor that is turned manually becomes a generator, and the voltage between its connectors is roughly proportional to its rotation speed. For our model train, this means that if we cut power on a running locomotive, its motor will generate a voltage as long as its momentum keeps it turning. It won’t last long as Z scale locomotives as very lightweight and will stop very fast, but it will be there.

As you saw in the previous section, we decided to drive the locomotives using PWM, which means that we are switching power on and off all the time: we therefore have a perfect window to measure this freewheeling voltage whenever power is switched off! With a PWM frequency of 60Hz, similar to what unregulated DC train controllers use, this means that 60 times per second we will have a few milliseconds of power off to do this measurement, which is all we need. The scope capture below summarises the whole process:

  • In green the PWM signal (here with a 40% duty cycle)
  • In pink, a debug signal that indicates the beginning and the end of the BEMF measurement window
  • In yellow, voltage across the motor poles, which never goes back to zero  when the motor is running, because of back-EMF. 660mV*3 in this capture.

A tricky part, though, is that when we switch EN off (with the PWM signal),  depending on motor direction, the polarity of the voltage generated across its poles will change. This makes measuring it tricky if we don’t want to use additional switches to select the pole were we measure voltage – a standard microcontroller ADC will measure between 0 to 5V, but not negative tensions.

This is the reason why we wired the motor as shown on the schematics earlier: by using both EN pins, we are able to always ground one pole of the motor, and toggle the other between V+ and high impedance. And by connecting both poles to a resistor and those resistors to another one connected to ground, we end up with a simple voltage divider where we can measure the freewheeling voltage independently from the motor’s direction! The diagram below shows how this is done more clearly:

The only drawback of this method, is that it requires two PWM lines on the microcontroller, but this is not an issue in our case.

Proof-of-concept implementation on an Arduino

The diagram below shows how the circuit was implemented and connected to an Arduino. I don’t think Arduino needs to be introduced, it uses an AVR processor with an overlaying framework that makes programming it extremely easy and quick. An alternative for a final version would be to use a more interesting and more powerful processor such as an ARM-based ST32 F0 to F3, and I have not decided yet which way I’ll go – I only have a limited amount of time to work on all this, and a great advantage of Arduino is the wealth of libraries available on it.

L293 motor driver with Back-EMF measure point

On the diagram, locate PWM1, PWM2, 1A and 4A. These are the pins that are connected to the Arduino. Freewheeling voltage (called “Back EMF” as in Electro Motive Force) measurement is done just above R3. The resulting bridge means that the measurement point will present a voltage that is 1/3 of the actual BEMF voltage (R1 / R2+R3 in parallel or R2 / R1+R3 in parallel).

Another thing to note, is that there are plenty of capacitors added: motors generate a lot of noise, parasites, inductive current, you name it. Add to this the fact that those lightweight Z-Scale locos constantly lose contact on dirty tracks which leads to uncontrolled inductive kickback, and you end up with constant glitches in your circuit. Those capacitors are therefore here to filter out all these effects and only leave what we want to measure. Without this filtering, voltage peaks would at best crash or reset the microcontroller regularly, and at worst simply damage it.

Last, you might have noticed R5 at the bottom, with a very small value (50 milliohms). This is a shunt resistor that we will use later to measure the current used by the locomotive.

Real life results

Below is a picture of what the circuit above looks like on a breadboard: not very pretty, but it does work!

How well does it actually work? In order to find out, we will now have to write a small firmware on the Arduino to drive those PWM signals! This will be the topic of the next article.