Model Railway Start Sets

The samples presented in this tutorial are simple, but sequential. You can use ANY model train kit with metal rails (you can also control old versions of LEGO TRAINS with metal rails or DC LIONEL).

Hardware Requirements: any microcontroller, a Bluetooth module, a motor-driver and several wires.

Software: premade Sketches in this tutorial are for the most popular Arduino products — NANO, UNO, MEGA and ESP32 (for ESP32 Bluetooth module is not needed).

Principal of train control

Entry level

To get started with the URB control system, try the free application Arduino Train DEMO. From there, you can try the paid applications which also work with these examples, while adding more complexity and features.



Arduino NANO and UNO

ATmega328 is an 8-bit MCU

Each type of a microcontroller (MCU) has its individual specs, and pin layout (they are also called GPIO — a General-Purpose Input/Output is an uncommitted digital signal pin).

Arduino NANO and UNO use the same MCU: ATmega 328, and, accordingly, the number and capabilities of GPIO are the same.

This circuit is a typical version of robotic control based on Arduino. Similar schemes can be easily found on the Internet. The only difference is that the output of the motor driver is connected to the rails, and not directly to the motor.

Before the assembly of the circuit, you need to upload to Arduino program called a sketch. Sketch for this experiment is based on the example SerialEvent from Arduino IDE. In general, all the sketches of this project are written at such a level so that they can be easily converted for to your needs. Their complexity at level a examples Arduino IDE.

  1. Upload UNO/NANO sketch (based on SerialEvent from Arduino IDE.)
  2. Assemble the circuit
  3. Play trains!
Start with NANO and UNO


Arduino MEGA

ATmega2560 is an 8-bit MCU

Arduino MEGA is redundant for this simple track-plan, but many modelers already have such a board. Therefore, I added a sketch for the ATmega2560 8-bit MCU.



32-bit MCU
Wi-Fi & BT/Bluetooth LE

Note: this chip works with logic levels of voltage of 3.3 V.

Unlike the classic Arduino boards (NANO, UNO and MEGA) natively supported by the IDE Arduino development environment, special libraries from Espressif Systems are required to program this module based on the ESP32 chip. Also note that the programming syntax of this chip is significantly different from that adopted in the Arduino programming environment.

If you have an initial level of programming in C ++, then using this chip in a project will not be difficult. But if you are new to programming, please do not use this complex chip in your projects.

Basic level

The first thing you need to believe, that most microcontrollers pins are universal. There are no rules for connecting this particular data wires from external device to this particular Arduino pin (with several restrictions).

Arduino NANO pinout

In the picture you can see that only pins D3, D5, D6, D9, D10, D11 can output a PWM control signal. Pins A0-A7 have enhanced capabilities for processing the incoming analog signal and so on. We will use all these features later.

In the URB project, a more understandable way of assigning Arduino pins is used. Before the Setup() block, the pinout is described using the #define construction code. In it, you write the names of the pins that you understand, and then use them in the main code.

Continuing with a simple BLINK example, you can connect a real LED to any Arduino data pin, and it will flash just like the built-in one. But if you try to connect the LED, for example to the pin D2 of Arduino, and do not change the sketch, nothing will happen. The fact is that Arduino needs to explain what you have connected to it. And these explanations you must do at the beginning of the code of the sketch. Such a section is void setup() called. And this code is executed once after turning on the power or resetting the microcontroller, then the main loop void loop() is executed endlessly.
It is enough to change this code:

  void setup() {
    // initialize digital pin LED_BUILTIN as an output.
  void loop()  {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(LED_BUILTIN, LOW);

on that:

  void setup() {
    // initialize digital pin D2 as an output.
    pinMode(2, OUTPUT);
  void loop()  {
    digitalWrite(2, HIGH);
    digitalWrite(2, LOW);

and it will work.

Tracks basics – add a turnout

The URB Project you can connect any types point-motors for switching turnouts – servo, electromagnetic and having a stepper or DC motor. Features of the use of different types, see the section «Plugging Point-Motors to your turnouts». But in this experiment I will use the classic solenoid mechanism. The sketch is written for this type of device. So you need a separate power source with a voltage of 12 to 16 volts for switching these point-motors. Therefore, you need have a separate output on your power supply terminal block of or have a separate source of this voltage.

Add switch-machine

The motorization of turnouts is the next stage that any modeler implements when building his own layout. The project involves the management of any type of railroad switches. In this example, you can add control to one turnout. Note how easy it is to add new code to the sketch.

Any of GPIO pins of the microcontroller can control the point-motor contacts with a simple command: digitalWrite(Number GPIO, HIGH/LOW state). But the output voltage and current from the pins (GPIO) are too small to move the solenoid inside the coil, thereby moving swith point rails of your turnout. Therefore, a current amplifier is needed. For this you can use a simple circuit with transistors, but in my project I use only ready-made electronic components. This is an assembly of Darlington transistors placed in a finished chip. Chip manufacturers produce many variants of such chips and you can apply any of them. In the Arduino environment, the most common chip is ULN 2003, so it is used in this example.

Darlington Array

In this sketch you can see commands for switching turnouts. ja1z and ja0z – commands to switch the turnout A to positions of straight or branch. First letter (j – junction), second letter (a) means the individual number of the turnout, the third – switch points position (1 – straight, 0 – branch).

  if (inputString.charAt(0) =='j') { 
    // Switch A
    if (inputString.charAt(1) =='a') { 
      if (inputString.charAt(2) =='0') { // Branch
        digitalWrite(2, LOW);
        digitalWrite(3, HIGH);
      if (inputString.charAt(2) =='1') { // Straight
        digitalWrite(3, LOW);
        digitalWrite(2, HIGH);


Later I will show how to add a code to the sketch to automatically turn off the voltage from solenoids after switching position of the turnout.

Plugging Point-Motors to your turnouts

Magnetic coil (solenoid machine)

To control this type of point motors, the project uses a ULN2003 chip or similar. You only need to select the voltage for your machine, and if you want the time needed to move the core of the coil.

Turnout Servo Motor

The servo is natively controlled by Arduino. Servo.h library allows an Arduino board to control RC (hobby) servo motors. Servos have integrated gears and a shaft that can be precisely controlled. Standard servos allow the shaft to be positioned at various angles, usually between 0 and 180 degrees. The Servo library supports up to 12 motors on most Arduino boards and 48 on the Arduino Mega.

Especially for the URB project, I developed an original easy adjustable and cheap servo point motor.

Ways to connect different types of point-motors

Polarity Dependent point-motors

Types of switch-machines Types of switch-machines

The most famous representatives of this type of drive for turnouts are KATO and Tortoise products.

The KATO point motor is a classic electromagnetic drive with two solenoids. But the control wires are separated by diodes. Therefore, only two wires are needed, and depending on the polarity, the position of the turnout changes on them.

A DC motor with a gearbox is located inside the green Tortoise box. That is, this is the usual circuit for controlling the direction of rotation of the motor using Arduino. Limiters of end positions are integrated into this drive, therefore the control method is similar to the KATO drive.

In both cases, the easiest way is to use the L298 motor driver with installed jumpers on the speed control contacts. The voltage supplied to the input of the motor-driver is determined by the technical characteristics of the drive. The sketch is the same as for the control of a point electromagnetic motor (see abowe).

Connect L298 to switch-machines
Types of switch-machines L9110S 4 CHANNEL DC STEPPER MOTOR DRIVER.jpg

In fact, there are a lot of Arduino devices that can be used to control turnouts. For example, you can use the L9110 stepper motor-driver or even several conventional switch transistors. The most important thing is that their characteristics must be sufficient for such voltages and currents on the coils of the point motor. From the point of view of the sketch for Arduino, any of these devices is controlled in exactly the same way. Therefore, the sketch code presented on the site for the L298 will work exactly the same with the L9110 motor driver.

Special thanks to modeller Muro for reporting that he successfully uses L9110S 4 CHANNEL DC STEPPER MOTOR DRIVER BOARD to manage 4 turnouts of KATO on his N scale railway layout.

Connect L298 to switch-machines


Big and old-timer Switch Machines

Types of switch-machines Types of switch-machines

These machines generate very high currents when switched. In some cases the motor-driver above can handle this load, but it is better to use a dual relay. With this type of connection, you physically separate the electronics and the Arduino from such a powerful load. Older twin coil switches have a contact problem, and using a dual relay with auto-off by time eliminates this problem. Also, when connected via a relay, you will not have voltage restrictions, since some drives require voltages up to 36 V.

And in this case, sketches also do not require changes. You just need to adjust the delay time for the complete movement of the actuator arm.

Relays and older switch-machines


Modern Point electric motors

Types of switch-machines

Most modern electromagnetic switches successfully operate with a voltage of 12 V. The resistance of the coils in them is very small and amounts to a smaller of an Ohm. If you notice that the drive is heating up, you can put a current limiting resistor with a nominal value of 0.5 – 1 Ohm.

Examples of controlling such motors are shown in the Tracks basics – add a turnout chapter.

For the URB project, I recommend using URB units with the ULN2003 chip integrated into them. But there are many reasons why modelers are reluctant to make such units themselves. One of them is the habit of using ready-made modules. For such modelers, I suggest using the ready-made High-power ULN2003 Stepper Motor Driver Board.

There are also boards with ULN2003 and UL2803 chips installed on them. Please do not forget to connect the COMMON output to a positive power supply, otherwise these chips will burn out very quickly.

Driver ULN2003 for point motor


Servo points

Types of switch-machines Types of switch-machines

In my opinion, using a servo as a drive for switching turnouts is the best option. Servos SG-90 are cheap and you don't need a separate power supply as they use 5 V. The Servo library allows you to connect a servo to any Arduino pin.

To increase the service life of the servo drive in the URB project there is a code for turning off the power. Physically, this function is performed by the ULN2003 chip, one pin on it which works as a contactless switch. The URB unit has special connectors for servos with auto off, but you can create a similar circuit yourself.

In most actuator designs using a servo, the possibility of switching the turnout switch by hand is blocked. My proposed rocker design allows manual shifting and electronic control to be used simultaneously. If you add a sensor to this design, you can use feedback and get the extended functions shown in the video.

Servo and ULN2003

Turnout control subsystem

Arduino Railway Layout app

You can apply the Project URB in parts, for example, to control only turnouts and signaling. For modelers who want to build control of turnouts on the basis of the URB system, I wrote a special application Arduino Railway Layout Control. Connection diagrams and control commands comply with Protocol 2.5.

Insulated rail joiners and relays

Add switch-machine

The URB project operates in the classic DC control mode. This means that, unlike the DCC control systems with a decoder in the locomotive, sections of rail tracks are controlled, not the locomotive itself.

Contrary to popular belief among supporters of DCC systems, this control method has much more possibilities. The transparency and reliability of the DC system are obvious – you always know what is happening, due to the lack of modulation of the digital signal under voltage for the decoder on the train and the elementary principal of «Rails – DC motor inside of a loco». To identify possible malfunctions, a conventional voltmeter is enough.

But other benefits are less obvious. For example, the creation of an interlocking system for several trains in the DCC system is impossible without the use of a very complex subsystem for controlling the position of all trains on a layout with online identification by using local «GPS for the hobby room» (see Faller system). To implement interlocking or other options for automatic control of train traffic in the URB system, several sensors are enough…

An example of controlling multiple trains is this sketch. You can increase the number of lines by simply increasing the number of relays and switches. Sketch do contain having code of the algorithm, which automatically activates the line depending on the position of the turnouts. Also in this sketch, the voltage from the solenoids is turned off after the timeout you define (I set 0.7 sec).

  if (millis() > (millisJunctionsA + 700)) {
    digitalWrite(JA_STRAIGHT, LOW);
    digitalWrite(JA_BRANCH, LOW);
  if (millis() > (millisJunctionsB + 700)) {
    digitalWrite(JB_STRAIGHT, LOW);
    digitalWrite(JB_BRANCH, LOW);


Insulated rail joiners
Insulated rail joiners

Rail joiners are small clips used to join two sections of track mechanically. They come in metal (nickel silver) which also connects the rails electrically, and plastic which are insulated to isolate the two sections of track electrically.

Relay module

A Relay is an electrically operated switch. Many relays use an electromagnet to mechanically operate the switch and provide electrical isolation between two circuits.

Tomix Micro-Layout

Tomix Micro-Layout

The modeler asked me to sketch for a popular track-plan from the Layouts with Tomix Track. He has a stepper motor ULN2003 driver module and wanted to use it to control the turnouts. Well this is it. This is the control sketch for UNO or NANO.


ULN2003 driver
ULN2003 Stepper driver

The ULN2003 stepper motor driver board allows you to easily control the stepper motor from a microcontroller, like Arduino. This module can also be used to control two point-motors.

Point-motor and ULN2003

An important feature of microcontrollers is the versatility of GPIO. You can change the destination of any Arduino pin by changing code of header's sketch. For example, I changed pins numbers that control point motors, and now the pins D2 and D3 now control the relay module. You can see more interesting examples in the video. Sketches for them do not differ from the above.

The fun feature of the URB control system is the simultaneous control of trains and layout by several players. Arduino Train Junior Pro, DUO and Tablet applications support multiplayer for two participants, the Quadro app up to four.

In the new version of the Protocol version 2.4 four letters are reserved for these purposes – a, b, c and d. This is a very flexible solution – you can alone control trains and the layout, switching between sections of railtracks (for example, between the outer and inner circles in this example), or adding additional Bluetooth modules to playing on multiple smartphones or tablets. The rule is simple: you need one Bluetooth module for one smartphone, two Bluetooth modules for two phones, etc.

The speed of data transmission and processing in Arduino is much higher than in DСС control systems, so there is practically no delay between the movement of the traction control in the application and the reaction of the locomotive to this effect. This is very similar to analog control using a transformer – instant response. To make it even more interesting, you can enable several modes of inertia in the Pro and DUO applications, which will simulate the movement of light, medium and heavyweight trains.

Dual control can be applied in other games. The scheme given at the beginning of this page for Arduino and the sketch to it may will also apply to any other similar systems, for example, to toys like Electric Loop Road Racing.

Advanced level

The main advantage of my project is the combine of many microcontrollers (Arduino boards) to each other, as well as to external computers or other digital devices. Thus, there are no hardware restrictions on the number and types of devices using on your layout (turnouts, sensors, signals, lights, any mechanisms and other). This is a clear difference to other railway control systems.

All the possibilities of the URB project are revealed when several Arduino are connected to the mesh. The flexibility of the system lies in the fact that you can use several types of Arduino boards in one project and connect them together using any standard bus for microcontrollers. Examples in this section use multiple serial connections and the I2C bus.

The only restriction necessary for the implementation of my control system in your railway layout is the allocation of one Arduino as COMM, all the other Arduino should be LOCAL.

The video shows a complete analysis of the sketch code for such a system. If you noticed, then almost all the videos on my YouTube channel use the URB unit.
I repeat, the use of this adapter board for my project is not a prerequisite!


Signal system

First you need to introduce you to the Smart Track function and Boolean logic.

Boolean logic

You have already met with the comparison operators IF and ELSE. By adding to them Boolean variables (having only two states), you can very simply describe the behavior of your layout.

I apply the following rule to turnouts: if the point (switch rail) has a direct position, then the value of the variable «1» or TRUE; if the point has a branch position is the variable «0» or FALSE. The same for the active / passive the line's states.

By using these variables, the COMM remembers the state of all lines and turnouts, and you can use comparison operators to program the logic of the behavior of signals, relays and other things.


signal system track-plan

To demonstrate the advantages of a system of several Arduino, in this example I will give two solutions for a standard track-plan.


A long time used contacts mechanically connected to the points of turnout. An example of such old-school excellent mechanics is Twin Coil Switch Machines with signal contactors.

Old Twin Coil Switch Machines

This simple system activated a rails line according to the position of the turnout. This works well, but as soon as you need to make a more complex switching logic, for example if you have three turnouts, there are very big problems with creating circuit.

Microcontrollers elegantly solve such problems. Instead of connecting multiple relays and wires or soldering many discrete elements, the logic of the lines and signals is transferred to the sketch code. Therefore, you can always add, modify or correct errors by simply reprogramming a sketch without having to change the electric circuit.

Code for switching relays between lines

if (switch_A == true) {
  digitalWrite(RELAY, LOW);
if (switch_A == false) {
  digitalWrite(RELAY, HIGH);

Now I will add another turnout, and I will only need to rewrite the sketch without changing a circuit on the layout.

In the C programming language (Arduino sketches), it is customary to reduce the comparison operators of Boolean logic. Instead if (switch_A == true) is written if (switch_A) and instead of if (switch_A == false) – if (!switch_A) (sign «!» means inverse). Since the state of the switch_A variable can take only two values, you can use the else operator. Two letters && are a comparison operator AND.

if (switch_A && switch_B) {
  digitalWrite(RELAY, LOW);
else {
  digitalWrite(RELAY, HIGH);  


Smart track

Look, in case you haven't noticed, I tricked you a bit with the code for two turnouts. In fact, given that each turnout can have two states, the number of options will be four. If you add even more turnouts, the situation will quickly get out of your control.

In the URB project, this misunderstanding is resolved by grouping variables of turnouts and moving the logic of switching relays and signals to LOCAL Arduinos.

But before it, let's look at all the options for the states of signals and relays turning on / off the corresponding lines (see pictures).

I suggest the following algorithm:
– if the Switch A is in the branch position, then Signal 1 is yellow with a white line indicating the movement of trains along the Line A. Signal 2 is green and the corresponding relay activates line A.
– remaining states of Signal 1 depend on the positions of switches B and C and the position of switch A (to straight).

if (!switch_A) { // Branch position
  digitalWrite(RELAY_LINE_A, LOW); // Line A ON
  digitalWrite(SIGNAL_1_YELLOW, LOW); // ON
  digitalWrite(SIGNAL_1_WHITE, LOW); // ON
  digitalWrite(SIGNAL_1_GREEN, HIGH); // OFF
  digitalWrite(SIGNAL_1_RED, HIGH); // OFF 
  digitalWrite(SIGNAL_2_GREEN, LOW); // ON
  digitalWrite(SIGNAL_2_RED, HIGH); // OFF        
else { // Straight position
  digitalWrite(RELAY_LINE_A, HIGH); // Line A OFF
  digitalWrite(SIGNAL_1_YELLOW, HIGH); // OFF
  digitalWrite(SIGNAL_1_WHITE, HIGH); // OFF
  digitalWrite(SIGNAL_2_GREEN, HIGH); // OFF  
  digitalWrite(SIGNAL_2_RED, LOW); // ON

  // Code for Switches B and C  

But before we create the sketches, let's calculate the number of pins on the Arduino necessary for this track-plan. The motor-driver needs three pins, three relays are needed on three lines – these are three pins. Signal 1 has four LEDs, signals 2-6 have two LEDs each. A total of 20 pins.

In this example, I will use servos to switching the turnouts, these are three pins (in the case using the classic inductive point-motors needs six pins). And, as you can see, the number of GPIOs (pins) on the Arduino NANO, UNO and ESP32 is not enough even for such a simple experiment.

The most unreasonable solution to the problem of lack of pins is the use of Arduino MEGA. Firstly, this does not solve the problem itself, as soon as you try to control the layout with ten or more turnouts and signals, you again will not have enough GPIOs. Secondly, the number of wires and the complexity of the electrical circuit will quickly lead you to disheartening. Thirdly, the dimensions of the sketch will very quickly exceed five hundred lines, and you will not be able to understand what you programmed in a few days ago.

In the URB project, you can increase the number of GPIOs (pins) you need by simply increasing the number of Arduino. This dramatically simplifies the circuit and sketches. You can transfer data between several Arduino via serial communications, routed buses of type I2C or wireless channels.

In this example, I will show two options for such a solution:
– Serial connection of two Arduinos (MEGA and UNO)
– Connection via I2C bus of three Arduino NANO.

Layout circuit

To demonstrate the flexibility of the URB system, I will connect the servos, relays and signals in these sketches in different ways. Using URB units allows you to placed Arduino directly to the installation location of the drives and signals on your layout, which simplifies the setup, length and number of wires. Later you will be add new devices to your layout without changing the wiring, due to the availability free Arduino pins. That is, you can consider the URB unit as a socket with remote control through the application.

Since in the URB project there is always one COMM and several LOCAL Arduino, so, COMM always has a Bluetooth and receives control commands from the application. In the example with serial communications, MEGA is COMM, in the sketch for URB units, since they are the same, you can assign COMM to any of them by simply installing the Bluetooth module on it. The algorithm switching relays and signals on lines B and C, depending on the state of the turnouts B and C in the first sketch for MEGA and UNO, is performed on MEGA. In the case of three URB units, this algorithm runs on local units.

3 URB units (3 NANO)

Three URB units COMM (URB#1) LOCAL (URB#2) LOCAL (URB#3)

In the sketches for the URB units there is a code that implements auto-shutdown of servos after switching the turnouts and moving position of turnouts to the default position.

Arduino MEGA + Arduino UNO (NANO)

MEGA-UNO serial COMM (MEGA) sketch LOCAL (UNO-NANO) sketch

Sketches for MEGA – UNO and 3 URB units perform the same functions, only for URB units the sketches are more concise and, due to the standardization of the devices connection, their code is universal. That is, you can simply copy the sketch code from the snippets and adjust it, instead of creating a new one.
Also, the signals in the version for URB units are connected through a current amplifier, that is, you can use not only LEDs, but also old signals with incandescent bulbs.

Power supply

In examples on the Advanced Level section, we create an extensive network of many URB units and a large number of railway peripherals connected to them. Because of this, the load current on 5V can become significant, so we need more powerful power sources compared with the charger for phone. I highly recommend a 5V power supply with a current of at least 2 amps.

The ideal solution can be a computer power supply, it immediately gives out voltages both 5V and 12V with protection. Also, most railway sets usually include a 9-18V power supplies. Also, you can apply two standard power supplies, to 5V and 12V, by combining their negative wires together.

Old timers layout


Let's bring all of the previous pieces together!

Big Layout

The URB project is a constant discovery of new opportunities. Sometimes it even surprises me. When I created the protocol and applications, it seemed to me that I was making a railway layout control system. Then when I started experimenting with sensors it turned out that we can create automatic train movement specific to the scenario. Then, modelers who were interested in the URB project began to connect automatic decouplers, drawbridges and control of MAGNORAIL system. Suddenly, we've discovered that Arduino microcontrollers have no boundaries for creativity and experimentation.

The network topology of URB allows you to mix data buses in any way convenient for you. The Arduino code variant for this is shown in the example above, but for a Big Layout I created a circuit consisting of a serial connection an Arduino MEGA as COMM and Local URB units with two separate segments I2C (the length of the I2C bus is limited to 3 meters).


Big Layout plan

The flexibility and universality of URB gives you the opportunity to make decisions about the organization of the behavior of devices on your layout. This lead to replacing the COMM URB in the Big Layout with an Arduino MEGA.

This change complicated the connection of the railway periphery to the system in comparison with the URB unit and requires more attention when installing the wires. However, this configuration provides more flexibility when creating a network thanks to Arduino MEGA's four serial ports. Serial data routing simplifies the connection of sensors and increases the length of data buses. Combining serial connections with I2C buses, you can create a heterogeneous network with various types of microcontrollers and Arduino modules. For example, connecting a sound module (or several) with a serial interface.

I want to control my layout from my mobile phone or tablet. Before connecting the circuits and writing the code, I need to figure out how the trains will move via the layout lines. I have two independent circles and a rail connecting them. With a scale of 1:87, the size of the layout is about 4x2 meters (14x7 ft). In addition, I want to run the wires of the electrical circuit mainly along the external contour of the layout, and also I want to avoid wiring in the back of the layout. And lastly, I don't yet know how many signals and channels of lighting control layout I need. I want to be able to add or change my layout in the future.

Observing the basic rule of the URB project (place units as close to the railway periphery as possible) – I placed these units on a draft picture of the layout. Now I can make a connection map. In this layout, I use the HO PIKO Point electric motors to move levers of turnouts, which means that I need current drivers (ULN2003). Each of them can control three motors which dictates the number of URB units needed for the switches.


Now divide the rails into sections. An example of TWO CIRCLES gives me a way of dividing the plan into sections of outer A (green) and inner B (blue) sections.

Next add isolated rail lines and give them a name. Connect a relay to these lines later.


From the picture there are 8 Lines in total, 8 relays are needed. In addition, there is a Transition Line along which you can move trains from the outer circle to the inner circle and vice versa, requiring two more relays. To simplify the sketches connect all relays to the Arduino MEGA using two relay modules one 8 relay unit and one 2 relay unit.

Logic & Algorithm

This is a rather complicated yet interesting stage. The function of the URB project is to make the lines operate automatically based on the position of the turnout switches.


There may be several options for these algorithms, and it all depends on your preferences. For Yard and Depot Lines, the algorithm directly depends on the position of the turnout switch J3 and J4. For Lines 1 and 2, I made a dependency; with the direct position of the turnouts, Line 2 is active, with the branch position, Line 1 is active. But if the J2 is in the branch position, both lines are blocked. The blocking algorithm for Lines 5 and 6 depends on the turnouts J10 and J12.

As you can see, these are already quite complex interactions in which it is easy to get confused. There is a solution – make a Karnaugh map. In the next section I will show how to do this without using the theory of logic and at the same time optimize the switching of turnouts.

An important function of URB should be noted – moving levers of turnouts to the default position.

In traditional DC or DCC train operation, when you turn on the layout, the position of turnouts is unknown. Moreover, during operation you can also forget the position of turnouts, this will cause delays, inconvenience, and crashes! Therefore, for each layout you will need to set the initial position, which will correspond to the variables switch_N. When you turn on the power or by command from the set default position button, all turnouts will automatically switch to this initial position and signal states are set. I chose the following starting position:


Karnaugh map


J1 – TRUE, J2 – TRUE, J3 – TRUE,
J4 – FALSE, J5 – TRUE, J6 – TRUE,
J10 – TRUE, J11 – TRUE, J12 – TRUE
J1 – FALSE, J3 – TRUE, J8 – TRUE, J9 – FALSE




J1 – TRUE, J2 – FALSE, J4 – FALSE, J6 – TRUE, J7 – TRUE, J9 – TRUE


J10 – FALSE, J12 – FALSE


J10 – TRUE, J12 – FALSE


J5 – FALSE, J6 – FALSE, J7 – FALSE, J11 – FALSE, J12 – TRUE


A dual relay will transfer voltage to Station Line 3 either from section A or from section B depending on the position of the turnout J7. These relays switch independently of the algorithm.

Arduino understands the values of Boolean variables in the form of TRUE or FALSE as 1 and 0. This translates to 1 representing the unswitched/straight/primary position of the turnout points and 0 to the switched/curved/secondary position.


Matching between Active Lines and Turnouts Table
# J1
Switch A
Switch B
Switch C
Switch D
Switch E
Switch F
Switch G
Switch H
Switch I
Switch J
Switch K
Switch L
Depot Line (see circuit) 1
Yard Line 0 1 0
Station Line 1 0 1 1 0
Station Line 2 (Default) 1 1 1 0 1 1 0 0 0 1 1 1
Station Line 3 A 0 0 0 0 1
Station Line 3 B 1 0 0 1 1 1
Station Line 4 (Default) 1 1 1 0 1 1 0 0 0 1 1 1
Station Line 5 0 0
Station Line 6 1 0

Look at your layout railpaths and fill out the table. Do not try to build an algorithm without creating a rail lines state table. If the railpath does not depend on the position of the particular turnout or if the position of the turnout blocks the track, then the table cell remains empty.

You can also combine hardware and software switching solutions. For example, the Depot relay of line and Line 3 is connected in series, so in the first row of the table there is only one value (see the relay diagram).

Using this table, I made algorithms for enabling corresponding lines. In this example, turnouts J corresponds to the SWITCH buttons in the Arduino Train application (J1 → Switch A, etc.). I use separate names of the real turnouts on the layout (J #) and app buttons (Switch #) to control them. This can later be used to optimize switching.


One command from the application can switch several turnouts at once. For example, it is logical to switch two turnouts J20 and J21 at the same time. That is, using the Switch W button on the app through a sketch, you can assign any change in position of any number of turnouts and etc. To implement this behavior of point-motors in the project, it is possible to assign the Switch command to a several turnouts J # like this:

void controlJunctions() {
  // Switch W
  if (inputString.charAt(1) =='w') { 
    if (inputString.charAt(2) =='0') {
      switch_W = false;
      digitalWrite(J20_BRANCH, HIGH); // two Junctions at once
      digitalWrite(J21_BRANCH, HIGH);      
    if (inputString.charAt(2) =='1') {
      switch_W = true;
      digitalWrite(J20_STRAIGHT, HIGH); // two Junctions at once
      digitalWrite(J21_STRAIGHT, HIGH);      
Line power

Another unique and important function of URB is that you can connect the relay to any Arduino on your layout to reduce the number of wires and simplify the circuit, in this example all the relays are connected to MEGA only to simplify understanding of the sketch code. This algorithm also allows you to build any system of railway signals, according to the principles described above.

void setup () {
  // Set relays states by Default
  digitalWrite(RELAY_Depot, HIGH);  //  OFF 
  digitalWrite(RELAY_Yard, HIGH);  //  OFF 
  digitalWrite(RELAY_Line1, HIGH);  //  OFF 
  digitalWrite(RELAY_Line2, LOW);  //  ON 
  digitalWrite(RELAY_Line3, HIGH);  //  OFF 
  digitalWrite(RELAY_Line4, LOW);  //  ON 
  digitalWrite(RELAY_Line5, HIGH);  //  OFF 
  digitalWrite(RELAY_Line6, HIGH);  //  OFF 
  // Power to Line 3 from Section A
  digitalWrite(RELAY_Transition, HIGH);  // From Section A 
void setup () {
  // Station Line 1
  if (!switch_A && switch_C && switch_H && !switch_I) {
    digitalWrite(RELAY_Line1, LOW);  //  ON 
  else digitalWrite(RELAY_Line1, HIGH);  //  OFF
Relays connections

If you notice, relay destinations 5 and 6 are sequentially reversed. These are the advantages of microcontrollers and Arduino in particular. You do not need to follow the procedure for connecting wires to pins (GPIO). Connect as you like, later you assign a pin number to a specific device in a sketch. In my example, all the relay control output wires are connected to the digital side connector of the MEGA, in the header of the sketch, write the correspondence between RELAY_Line6 and pin D51 using operator #define.

After the planning stage, all the data to place Arduino /URB units has been identified, enabling the creation of the electrical circuit and sketches. Next, open the corresponding snippets in the Arduino IDE editor and adapt them to the layout.

Programming the COMM

According to the plan created above, I determine the details of connecting to Arduino MEGA. Then, guided by the picture of the connected devices, I add them to the sketch header. The method of controlling point motors is given in the section Tracks basics – add a turnout. For this layout two ULN2003 chips are needed, pins D22-D33 are connected to the inputs of these chips. Thus, the sketch for MEGA will directly control the turnouts J1 – J6, and send commands to switch the remaining turnouts to the URB #2 unit through the Serial 3

Bus I2C MEGA will be used to control the light channels of URB #5 unit. I suggest using six channels to illuminate buildings and lights. If you need more channels, add one more unit (6) to the I2C bus. The pull-up resistors necessary for the correct operation of the I2C bus are installed on the URB #5 unit.

URB #2

In addition to the main function of executing commands, this URB unit also translates the commands from the MEGA serial interface to its own I2C bus, essentially creating a local router.

I rewrote this sketch from the snippet for the COMM URB unit, to demonstrate the universality of the rules for creating code for the project.

URB #2

URB #3

Sketch for URB 3 is a «LOCAL for URB» snippet. The functionality of this unit completely coincides with the example of using I2C bus. This sketch shows the practical application of the URB unit for the management of turnouts. You can use free pins later to connect signals or other peripherals.

URB #3

URB #5

This is a good example of adding an additional URB module to the finished layout for future expansion. You can also change the voltage for the LEDs, for example, connect them to 12 volts for standard LED stripes.

Also here is the algorithm of the RANDOM function, which ensures the random inclusion of lighting elements on your layout.

You can assign any lighting effects to your LEDs.

 URB #5 


After launching an experiments, you may notice some confusion. For example, if you typed the command: «jd0z» – the point-motor turned the turnout to straight position instead of the expected one a branch position. This is the logic chain: the command on the serial port → conversion to the byte-command → resend via I2C → processing on the local URB → a switching of the turnout D. This is quite a long chain of communication with many possible places for error. So, the rule is the following: setting the final position of turnout or the color of the signal should be made on the final URB unit to which they are connected.

In other words, you can build the correct logical model, but signals sent from the communication station cause an inverted response – instead of the expected red signal, the green signal is turned on. To fix this change the state of the outputs of the local URB (by changing the description of the outputs in the header of the sketch).

The number of units for the Big Layout compared to the old version of the site is reduced to three. As practice has shown, the example with 6 units was too complicated to study and raised many questions. Nevertheless, a version with 6 units is available on the old version of the site. I would also like to note that all project sketches and all application are compatible with each other and do not require additional changes.

The examples on this site are hard to get wrong, but shit happens :) Following these instructions and reversing the process, now you will diagnose your problems. The hardware of the URB project consists of modules that can operate autonomously. Therefore, troubleshooting is a simple checking of the modules by one. You can always connect the URB unit to the computer and add test commands to sketch from the Protocol to check it. For more information, see Running and troubleshooting.

Railway layout for Imre

My friend Imre from Hungary sent me his project. It turned out an excellent video about the adaptation of the URB control system for a specific railway layout. This example consists of two parts. The first is the planning of the electrical circuit, the second is the implementation.

Imre Layout's sketches (Zip)

This sketches was programmed for Protocol 2.1 and URB 2.122.


Dogbone track-plan

Many modelers like the Dogbone rail plan. I created this example especially for them, showing the universal capabilities of URB. For automatic operation of the loops, you need four IR sensors, which you need to modify according to my instructions. You can watch the basic working principles of sketching in videos.


A sketch should not cause you difficulties with its understanding, it is a common URB LOCAL snippet. Sensor signals from a local unit are transmitted through a serial connection. Turnouts J Loop A and J Loop B switch automatically and do not depend on the application command. The loops operation algorithms are symmetrical for COMM and LOCAL units.

To add turnouts controlled from the application, connect a new unit via the I2C bus, as in the example of the Big layout.



This sketch preprocesses the sensor signals and transfers their state to the COMM unit. Feature is the control of a motor-driver 2 from COMM via a serial. This method is also used in the Interlocking system.

Pay attention to the another location of the sensors on the layout and the associated direction of train movement when entering the loop.