The idea of a clock that runs faster than real time to compensate for the compression in our model world is nothing new. The idea has been with us since at least the 1960s. It provides a way to schedule our operating sessions, providing a sense of real time passage and urgency without needing literally thousands of feet of track to represent the vast distances covered by our prototype railroads. Aside from being a display on the wall, guiding operators’ train movements, fast clocks have remained an isolated system, our model world unaffected by the passage of scale time. Think about all the things in our daily lives that are linked to the time of day and you’ll quickly realize how odd that is given all our other technological advancements, and how much potential is in that idea. I believe fast clock integration is one of the huge, unexplored areas left in the hobby today for added realism.
In this article, we’ll show you how to build an inexpensive device that allows you to synchronize items on your layout to fast clocks by using MRBus, the networking protocol that connects the Iowa Scaled Engineering Networked Fast Clocks, in conjunction with the popular Arduino prototyping environment.
On a grand scale, imagine the potential to change the scene lighting as your operating session progresses, from the dark blue ambient light of a full moon through the oranges and yellows of daybreak into the bright white light of midday sun and finally back to the reds and oranges of sunset. Thinking somewhat smaller, streetlights should start coming on around “dusk”, and go off around “dawn”. Building lights should start coming on around the same time, but start turning off as businesses close and your tiny model citizens go to bed. Possibly you’re modeling the midwestern US, where it’s common to have the local civil defense siren go off at noon. The possibilities are nearly endless, and thanks to modern electronics, these possibilities can be realized.
Building a Fast Clock Interface – Hardware
Arduinos are a really easy way to get started working with microcontrollers – tiny little computers costing only a few dollars that you can program to do simple tasks. All you need to get started with the Arduino world is your computer, their free development software, and an Arduino board. There are literally tens or hundreds of thousands of examples around the internet of how to program Arduinos to do almost anything you can imagine. The environment was designed for hobbyists and non-engineering types, so don’t be afraid if you’re not familiar with programming. There’s even the Arduini Yahoo Group, which is a community for folks using Arduinos in the model railroading world.
For this project, we’ll be using an Arduino Leonardo. The Leonardo is somewhat unique in that the connection to the computer isn’t shared with the board’s hardware serial port. The MRB-ARD uses the hardware serial port to communicate with MRBus. If the serial port is shared with the computer interface, such as it is on other boards such as the Uno and derivatives, then you have to disconnect the MRB-ARD every time you want to program the Arduino and you can’t use the serial console for debugging. The official Leonardo is about $20, but you can find Chinese knockoff clones for $7. I typically buy real ones for development boards to support the Arduino project, but then use the knockoffs in any hardware I intend to just install and forget about.
The core Arduino board is mostly just the microcontroller – the tiny little computer you can instruct to do things. Usually you need to add shields – add-on boards with more circuitry – to give it the ability to sense, communicate, or affect the outside world. For this project, I’ll be using two shields – the Iowa Scaled Engineering MRB-ARD, which gives us the MRBus interface, and a no-name shield that brings the Arduino pins out to screw terminals for easy prototyping. (Sparkfun has a similar screw terminal shield, but I think I paid $3 for mine from China.) For our example, I’m using a separate 5V dual SPDT relay module I had sitting around in my junk bin.
To connect them, all you need do is stack the screw shield on the Leonardo, and then put the MRB-ARD on top. Be careful while lining up all the pins to make sure they’re all in the sockets and not shifted or bent. Next, connect the four MRBus lines (Power, Ground, and signal A & B) from your fast clock network to the MRB-ARD shield. (Note: If you’re using the wireless fast clocks, you’ll need to get the wireless signal back onto a wired MRBus network for this project. The MRBus Access Point – MRB-AP – provides this functionality. In the future, we’ll show you how to use a Digi Xbee radio attached to the Arduino to connect to the wireless network directly.) After that, set the jumpers on the MRB-ARD so that none of the I2C lines are connected, the Arduino is powered from the MRBus network, and that MRBus termination is off (as the master fast clock or MRB-AP is already providing it).
The exact connections to your relay board will be dependent upon the hardware you’re using. If you’re using a relay shield, chances are there won’t be any wiring to the Arduino other than the header pins. If, however, you’re like me, and using an external module, you’ll probably need to connect power, ground, and two signal lines. I wired these over from my relay module using a chunk of ribbon cable with a 5 pin header on it, attaching 5V and Ground to the appropriate screw terminals of the same name, and then attached the signal lines to Arduino pins A0 and A1.
You could also use something like one of Seeed’s relay shields if you wanted to put the output relays right in the stack. It provides a much cleaner stackup and two more output channels. I didn’t have one when I originally started writing this post, but I borrowed one just to show you what it would look like.
Getting Started With Software
I’m going to assume at this point you have the Arduino development environment installed. If you don’t, Arduino’s Getting Started Guide is a pretty good place to start. Specifically, you’re going to want to read the Installation section for your specific operating system.
The easiest way to get an Arduino to talk to MRBus is by using our library. A library is just a chunk of code that’s designed for reuse, typically because it does something that gets reused a lot. It’s designed to hide much of the complexity and make using MRBus easier. Our core MRBus for Arduino library is part of the MRB-ARD shield project over on our Github site. Download it – either by cloning the repository or by just clicking the “Download ZIP” link in the lower right corner. Once you have the zip file, get the MRBusArduino directory out of the src/ subdirectory and put it in your Arduino development environment’s libraries/ directory. For more details on how to do this, read the “Manual Installation” section of Arduino’s page on how to install libraries.
Once you have that done, fire up the Arduino dev environment. If you’ve done everything right, you should be able to go to File->Examples->MRBusArduino and find an example sketch called “simple_mrbus_node”. Load this up. You’ll then need to tell the environment what board you’re building for, and how to find it. Select “Arduino Leonardo” under Tools->Board, and select the correct serial port under Tools->Serial Port.
Once you’ve completed that, click the little icon with the check in it. This will compile the example source code. If all is well (basically there’s no orange colored error lines in the bottom terminal), you’re ready to load it to the board. Push the button with the right arrow on it (next to the check mark button) to actually send this program to the Arduino board. If everything succeeds, the little amber LED on the MRB-ARD should quickly flash every now and then. Congratulations! You’ve made your first MRBus node!
That said, your little node is just running the barest of example MRBus applications. It doesn’t yet do anything useful – it just fires off a status every two seconds, and if you have a MRB-CI2 computer interface, you could send it a command to turn the D13 LED on and off. It definitely doesn’t know how to interact with the clock. For that, you need the MRBusClock protocol library to understand the data the clocks are sending. This builds on the previous MRBusArduino library, which provides the basic communications layer and hardware support. The installation process is very similar – download it from Github, copy the MRBusClock directory (the whole thing this time) into your libraries/ directory, and restart the Arduino environment.
Again, if you’ve done everything right, you should see MRBusClock show up in your File->Examples list, and you should be able to pick the “mrbus_clock_example” sketch from it. Select it and compile/load it to the Arduino as you did above. If that succeeds, open the serial terminal (assuming you’re using a Leonardo) under Tools->Serial Monitor. You should see a line every half second or so telling you what the clock is doing. It’ll tell you either a real or fast time, that the clock is on hold, or that it’s timed out because it’s not receiving clock packets.
Doing Something Useful… Finally
Obviously a serial monitor of what your clocks are doing isn’t very useful. It’s just a stepping stone we can use to prove everything is working.
In the example sketch, the interesting stuff starts at about line 105. This is where – every 100mS – the Arduino will check the status of the MRBusClock. There’s not much of a need to update more often than that, since the maximum update rate is only about 10 times per second.
The first thing you’ll notice is an if..else that checks that the clock is running on fast time and is not timed out. This means that the clock is set to fast time, not on hold, and it hasn’t been more than the timeout period since we saw a packet from the clock. That’s pretty much the conditions in which you probably want to actually cause model behaviours to run. Everything else (clock on real time, clock on hold, clock disconnected) probably isn’t going on during your operating session. That’s what the “else” case of this is for down at line 122, and it just defaults to turning off the Arduino’s onboard D13 LED.
Assuming we’ve met all those conditions so we’re probably in the middle of an operating session, what’s this code do? Line 112 creates a variable to store the current fast time, and line 113 gets it from our clock. Line 117 then tests if this time is between 0300h and 0400h (MRBusTime(h,m) creates a time value that can be compared, where h is hours and m is minutes). If we’re in that time interval, turn on the onboard D13 LED. If we’re outside of it, turn it off.
That’s not very interesting but it gives you an idea of how to get the time and then act on it to do other things. To see it work, set your fast clock to 0255h. As it clicks over to 0300h, you’ll see the light turn on. At 0400h, it’ll go back off.
Let’s now extend that to drive our relays. Let’s say that relay 1 (pin A0) is connected to the layout lighting. It can either be day (bright white lights) or night (blue lights) depending on whether the relay is energized or not. For the sake of this application, it doesn’t matter if it’s LED, fluorescent, or incandescent. If you size the relays properly, you can drive almost any load. We’ll also say that day-night transition occurs at 0717h (dawn) and 1955h (dusk). When the layout is not running on fast time (meaning hold or on real time), we want the white lights to be on so that we can see what we’re doing.
The other channel – relay 2 on pin A1 – will be used for some low voltage residential structure lighting. We’ll say that most of our model citizens are turning on their lights around 1900h and then turn them back off again at 2200h when they go to bed. We want these lights off when the layout is not actively running so that we save power and don’t put unnecessary hours on the bulbs.
The core of it is adding more conditionals like you saw above. Here’s the one that will switch on/off A0 (the room lights) based on what time of day it is in our model world:
if (currentFastTime > MRBusTime(7, 17) && currentFastTime < MRBusTime(19, 55)) digitalWrite(A0, LOW); else digitalWrite(A0, HIGH);
I’ll put the full code here as an example so you can download and see for yourself what changed from the library example.
My layout is far too incomplete to give you the full work-up, demonstrating this in a world with full scenery. So we’ll do it using what I had on the bench last night at midnight – a blue and a white LED strip light to represent the layout lights, and a single white 5mm LED to represent the structure lights.
Early AM- note that the blue (night) layout lighting is on, but the structure lights are off. Also note that the yellow light – which is tied to D13 and the LED on the Arduino – is on, indicating that it’s between 0300-0400 because of the code from the original example sketch.
So this shows you how to create simple time-triggered events on the layout – things that have an on or an off state. But what about something like the Holy Grail I promised above – lights that gradually transition through the day? That’s a whole other ball of worms.
Fortunately, it’s one I’ve thought a great deal about, as I developed a prototype about a year ago for my own Copper River & Northwestern (which is still very much under construction). I’ll be writing a follow-up post showing you how to extend what we’ve done today into a large scale light controller.