RPi model railway controller
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
- 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)
- Raspberry Pi compatible OS image
- RPi.GPIO (pip)
- tornado (pip)
- soldering iron
- wirecutter, pliers, etc...
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.
wiring underneath the board
This makes it easy to connect/disconnect the rest of the wiring using another
m-m strip header used as a plug
Neat and portable!
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.
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.
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.
all connected and ready to go
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,
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
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!
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
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!