I have this tiny n-scale model railway layout partially finished, designed to sit in a coffee table. It’s difficult to use a normal controller in this case, so a different solution is needed - a controller I can use over wifi from my phone.

top view of trainset

Ingredients

Hardware

  • Raspberry Pi
  • usb wifi card (unless you have the Pi 3 or ethernet)
  • micro SD card
  • 5V battery to power the Pi (the type designed for charging phones via micro usb)
  • Motor driver (reversible, works well for pwm control)
  • 4+ MOSFET drivers
  • jumper wires
  • strip headers
  • 12-14V power supply for powering the trains (battery or wall transformer)

Software

  • Raspberry Pi compatible OS image
  • python3
  • pip3
  • RPi.GPIO (pip)
  • tornado (pip)
  • tmux/screen

Tools

  • soldering iron
  • multimeter
  • wirecutter, pliers, etc…

Process

Hardware

First, the wires for everything on the railway itself needed to be connected. My board is slightly raised by wooden strips, giving enough space to route the wires underneath the board, and into a f-m strip header to act as a socket.

the setup as described wiring underneath the board

This makes it easy to connect/disconnect the rest of the wiring using another strip header:

the setup as described m-m strip header used as a plug

Neat and portable!

the setup as described view of the socket connected

That’s the railway board done, now for the electronics. The wires for the turnouts are connected to the MOSFET drivers, since they require a short pulse of electricity to trigger (about half a second). Note that two drivers are needed for each turnout, one for each direction.

A reversible motor driver is used for powering the train itself. Just connect the two track wires to its output.

photo of drivers the motor driver on left, MOSFET drivers on right

The Raspberry Pi is wired to the motor driver and MOSFET drivers via any GPIO pins using the jumper wires. Don’t worry about hardware PWM - the RPi.GPIO library only supports software PWM, which is good enough to drive the train.

the setup as described electronics setup with Pi connected

I used a dedicated power supply for the Pi (5V battery), and a 14V supply (wall transformer) for powering the trains and turnouts.

the setup as described all connected and ready to go

The Software

I installed Archlinux ARM on the Raspberry Pi, but any compatible OS would do. Just have to set it up and install python and pip (and other essential programs like tmux, cron, etc…).

Pip was used to install the RPi.GPIO python library, and later, tornado for the server.

Now comes the tricky part - working out which pins are connected to what. It took a bit of fiddling around to work out functions for triggering the correct pins for controlling the turnouts and train speed.

Since the aim was to be able to control it wirelessly, I decided to set up a tornado server with python, with an API that allowed securely controlling the functions over the internet, along with sanity checks server-side to avoid damage to components from the turnouts being spammed, etc.

The server I built is opensourced and available on GitHub as swalladge/trains. If you want to use it, you’ll likely need to make some modifications to work with your setup.

To control it, I made a web client (also opensourced - swalladge/trains-client). It’s a static webapp that uses ajax to connect to the api server, so it doesn’t matter where it’s hosted. There’s currently a copy of the webapp hosted here.

Note that the server and client, while simple and configurable, aren’t very scalable as they stand - adding any more than a couple of extra turnouts would require a lot of refactoring for example. Pull requests with improvements are always welcome!

the setup as described action shot during testing

With the server installed on the RPi and the webapp hosted on my server for quick access, the final step was to add a cronjob to start a tmux session running the server on boot. Now getting the trains running is as simple as plugging in the RPi and the train power supply, and waiting a minute for it to boot up.

Final Notes

To DCC users: the setup described here wouldn’t be suitable, as they usually use proprietary protocols and require specialized controllers. They often have wireless options anyway…

Next steps will be adding scenery, buildings, and maybe even RPI controlled lighting!