Using Arduinos for Model Railroading
An Arduino is a very simple computer, actually it’s a family of different models for specific uses, with the typical one costing around US$30 (but you’ll spend more on things to add to it). It doesn’t (normally) have a keyboard or display, but instead is designed to perform a set function over and over, which can involve reading the state of simple switch or knob controls, and controlling the state of simple (and not so simple) output devices. As you might imagine, this lends itself to all sorts of useful hobbyist applications.
The really cool thing about the Arduino is that it is designed for hobbyist use. All you need is a computer, some skill at very basic electronics (of the kind many model railroaders have) and a WHOLE LOT of patience. Programming skill is helpful, but there are enough examples out there that you can probably teach yourself the basics enough to create a simple system. Don’t assume that you need to be a computer programmer to use an Arduino; lots of hobbyists who aren’t have used them.
Arduino has an introduction, plus a lot of online reference and tutorial material, and the development environment software (which is free) contains a lot of example programs that do simple things. Don’t overlook them. There’s also a discussion forum where you’ll find answers to many common questions (but look for an existing answer before asking yourself!). Don’t overlook the benefit of using Google or other search engines; some hobbyist may have already done what you want to do, or encountered the same problem you just did, and an answer or a simpler solution may be only a few clicks away.
There’s a nice overview slide deck of the basics of how the Arduino works with some more suggestions by a couple of model railroaders from a convention (PDF), and if you want some more complex ideas (like a DCC throttle) check out Model Railroading With Arduino (mrrwa.org).
A number of the diagrams from these pages are available in larger 800 pixel versions in the Arduino Diagrams album.
What Can It Do?
The limits are likely your imagination (and skill set), although there are some practical limitations I’ll get to below. If you want a really concrete example, I’m using one (still under construction although I have the basic functions working) to operate a simple back-and-forth automated light rail line, with two trains sharing end-of-line stations that have a single track, and a mid-track passing section. I made some very specific assumptions to simplify the design of the Arduino-based controls for this (I use slip switches for example, rather than having the Arduino throw turnouts). You can see my project description on my Tram Controller page, and some past posts about the development in my Musings Tram Controller category. There are also some pages associated with the main Tram Controller page that get into more detail on what I did with the motor controller and the infrared sensors.
Some other ideas I’ve had, or heard of from others, include:
- controlling lights, simple animated signs, or something more complex like traffic lights
- make a fancy animated sign with a matrix of LEDs
- a simple turnout control
- a simple DC throttle
- build a staging yard that has one-button control for “select the next empty siding”
- control signals in a prototypical “block” system with train detection (I wrote a library to do this without extra circuitry)
- create a “control point” for signals that works just like the prototype
- a servo-motor controlled drawbridge with signals
- a servo-motor controlled water tower spout for steam locomotives
- a turntable or transfer table
Notice that several of these use servos. The combination of Arduino and servo motor is a powerful one, which can provide all sorts of interesting animation on a layout.
My advice: start simple, really simple, and learn how Arduino works with some basic lighting or similar, then gradually work your way into more complex systems. Trying to dive into the deep end will likely only end in frustration. My tram controller turned out to be more complex than I thought it was going to be, and although I’m a fairly skilled programmer, my lack of understanding of how the Arduino worked was a big problem for me at times. Learn to walk, then run if you want to.
What Can’t it Do?
There are some important limitations, although it’s surprising how little these get in the way. An Arduino can power some devices, but it’s limited to about 500 mA (or maybe 200 mA), so running a train directly with one is a bit of a stretch. But there are external boards that will let it control a motor using a separate power supply for the motor (called motor shields; Arduino expansion modules that clip onto it are called shields). See my Tram Controller for a lot more on motor shields.
An Arduino has “pins” (electrical contacts) to which you can wire up switches (digital pins) or sensors (analog pins), but the number of pins is very limited. Usually you have 14 digital pins, although three are effectively reserved, and six analog pins (although on some models some digital pins can also act as analog ones, and you can always use a spare analog pin as a digital one). One way to deal with this is “multiplexing”, using a smaller number of Arduino pins to read/control a larger number of electrical contacts. This requires more complicated programming on the Arduino, but only slightly. And it can help if you use pre-built external circuitry, like this Mux Shield, but you can also do it yourself.
Pins can be used to drive circuits directly, but they’re very limited in power (on the standard model the limit is 40 mA per pin max, and pins are arranged in groups that are limited to 100 mA for the whole group, however some models, such as those based on the M0, are significantly more limited and even driving LEDs directly is risky). Usually you’ll use the pins to control external circuitry, rather than drive power-hungry devices directly. But you can power fairly simple circuitry, as long as you’re careful.
Memory is going to be the most limiting factor. An Arduino has two main kinds of memory: flash and SRAM. Flash is where the program itself is stored, and can’t be changed except when you load a new program (called a “sketch” for some reason) from a computer. It also keeps what’s loaded into it even if power is turned off. When you Verify or Upload a sketch, it will tell you in the window how much flash you have and how much it used (if you have enabled “verbose mode” in the Preferences). Each time you load a new sketch, it overwrites the old one; an Arduino only holds one program at a time, and when power is provided to the Arduino that program runs, forever (unless it crashes; and there’s a reset button for that).
The SRAM is used for storing data, like the last reading from a sensor. What’s in there goes away when the power is turned off. Most modern Arduinos have about 32K of flash, which is pretty small, and limits the size of the programs (sketches) you can load. But SRAM is the real limit for many things. You only get 2 KB in most cases, and that’s tiny. It will hold less than 1,000 integers, or 500 floating-point numbers, and some of it needs to be used by the Arduino. You really need to be careful about planning so you can minimize what you really need to save. And if you try to use too much, you normally don’t get a nice warning, the Arduino just doesn’t work. You won’t even get it to print out any debugging “println” statements you put in; it just dies until you load a working program.
Here’s an important reminder: because the contents of SRAM go away when the Arduino is turned off, you can’t store things like “track seven is in use” between sessions on your layout (unless you leave the power on and never have power failures where you live). Each time the Arduino starts up, it needs to re-learn the environment it is working with. That’s an essential aspect to consider when designing a system. However, you can store some essential information between uses.
There’s actually a third kind of memory, EEPROM, which can be written to and will be saved over a power interruption. This is a bit more complicated to use (you have to read/write individual bytes, not larger amounts like integers or strings of characters) and it is very limited (just 1000 bytes on the Uno, or 500 integers or 250 floating point numbers). This is what to use if you need to remember something from session to session, but be careful not to write to it too often. EEPROM will wear out (it takes hundreds of thousands of writes, but an Arduino can do 300 EEPROM writes per second if you’re careless and in theory you could destroy a memory cell in 5 minutes, and the whole EEPROM in under two days).
But before saving something, keep in mind that things can change between sessions. Just because track seven was in use when the power was turned off, doesn’t mean that the great five-fingered crane didn’t remove the cars there, or worse relocate them to track six while the Arduino was off. It’s almost always better to relearn things at startup than to try saving them.
One more thing the Arduino isn’t very good at: interfacing to a control bus. While there are some libraries available, they’re usually limited in functionality and depend on external hardware. The Arduino lacks both advanced serial support needed by some of them, and has limited memory and processing capability for the necessary protocol software. I do mention what I know of the available solutions on my control bus page, but that’s not a whole lot.
A Basic System
The Arduino comes in several models, and there are variations between them. The Arduino Uno is found is most starter kits (you can get them at Radio Shack), and that’s a good model to begin with. You’ll also need a power supply, although for initial use you can hook it up to a computer with USB (which you’ll want to do anyway for testing) and it will get power that way. On the layout, you’ll need to provide it a 7-12V DC power supply. I recommend using a “wall wart” transformer that puts out a regulated supply of 500 mA or more, like this one or this one; I use the 12V model.
I have a brief survey of some common Arduino models and shields, but for a complete list of Arduino models, see the Arduino site’s product list.
Along with an Arduino it’s a good idea to get a breadboard (or several) like this one or this one (and another that comes with some simple jumpers), and some jumpers (these are pretty cool, but you really need a set of these plus some simple jumpers) so you can wire up circuits for testing before you solder things together. You’ll end up using a lot of resistors, LEDs, and various kinds of switches, so a starter set (like this one or this one or even this fancy one) can be the best way to get going. Expect to end up buying a lot of things from companies like AdaFruit, Radio Shack, SparkFun, and others.
Designing Arduino-based Systems
The most important aspect to remember is that the Arduino is designed to control things, not to “do” things. That’s a bit subtle, and in a simple application it can “do” all by itself. But for anything reasonably complex, you’re going to need to supplement it with some external electronics that aren’t necessarily trivial. Fortunately, there are a lot of people solving similar problems, so there may already be a “shield” or other external circuitry that does what you need. Google around, and browse through stores (online or brick-and-mortar) to see what’s out there. When I was working on my Tram Controller, I was surprised to discover that my local Radio Shack had a better motor shield than the one that I’d found online.
The other thing is to keep it simple: don’t try to use a keyboard, if a couple of buttons or switches or knobs are all you need. Don’t add a wireless shield, if all you need is a wire.
Here’s an important tip to remember (the original came from here): when developing a program on an Arduino, it’s typically connected to the computer via USB. But once you have a working program loaded and you want to install it on the layout, you don’t need to have USB connected (assuming you have an external power supply). But in some cases, the Arduino won’t work with USB unplugged (I’m not sure if this applies to all models, or only some). The fix: put a 10K resistor between pins 0 and 1 (the TX and RX pins on USB-equipped Arduinos), or put it between pin 0 (RX) and ground. This keeps the Arduino from thinking it has a serial connection and possibly waiting for data that will never arrive. I haven’t needed that yet, but I don’t want to forget it once I do, so I’m leaving a note here about it.