Instead of a long and not always successful efforts of making a real console with buttons and throttle rudders, the Arduino Train Apps immediately provide you with many advantages:

The applications interface was developed primarily for phones (portrait screen mode). If you want to use a tablet, then consider using Arduino Train Tablet. Also, my applications have the following features that complement the usual model railway management systems.

Especially for moderators of app stores: my real name – Stanislav Moiseev aka Steve Massikker. I am the developer of all applications used for the URB project and the owner of this site.


Once again, the URB system operates in the classic DC mode. This means that there are no Bluetooth or DCC decoders in locomotives and cars. You can use any types of point motors, any types of signals and other devices of your railway peripherals without digitals. Also, you can directly connect old-timer devices to the URB system. If you adhere to the concept of DCC, then you may be interested in the LayoutControl app for switching turnouts, but my basic system does not work in a DCC environment.

Multiplayer and driver's multi-channel control

This feature is similar to the trains control from several transformers. The only difference is in convenience: you can install the application on a second Android device or use the Driver selector and get the same result without adding hardware. This function is shown in detail inExample 3 and Combined railway track.

The interface of the DUO and QUADRO applications remembers the current state of the train controls and restores it when switching Drivers.


Applications that support this feature



Applications that support this feature

Inertial mode of the throttle

To get more enjoyment from driving trains, I added an inertial control mode. When the inertia mode is activated, the traction controller is set to the central position and its behavior becomes similar to the TDB (Throttle/Dynamic Brake) handle. The further away from the center you move the slider, the more active the acceleration or braking. When the slider is released, it is immediately set to the central position, while the speed is stabilized.

Try this mode when stopping at a station or before a dead end. It is especially interesting to perform a smooth stop in this mode just before reaching the stop sign.

In DUO app you can also use different inertia levels of your trains. A LOW level allows you to accelerate and brake quickly, which is suitable for trains with a small number of cars, a HEAVY level simulates driving heavy freight trains.

Managing of other layout devices

Your layout is not only trains, railway tracks, and switches. In the buildings/structures on your landscape, windows should be lit in the evening, street lights also should be turned on. The URB system offers a flexible lighting solution. You can use dozens of lighting control channels, use any effects from smooth switching on to random turning on/off many of windows. To manage all this, special buttons are provided in the applications.

All applications have a CUSTOM button. You can assign it function in the sketch code to any event. There is even more choices in the DUO app. This application was developed to manage large layouts saturated with a variety of infrastructure elements. You can control drawbridges, automatic gates, railway barriers and everything else from this application. Also, the DUO interface provides control of the turntable.


Applications that support this feature


Turnouts switching is the main property of the URB system. Since their position is constantly monitored by the system, it becomes possible to automatically enable/disable track segments according to the Smart-track algorithm.

The motor switching of the turnout under control the URB system in railway modeling gives a lot of unrealized opportunities and gives rise one problem. For example, the position of all turnouts can be uniquely associated with traffic light signals and, as a result, get a ready signal system. But problem is, the position of turnouts is not always known after the layout is turned ON. All this was taken into account in the development of this project. In the application there is a button RESET, which sets turnouts to the position assigned initially by the user, the same happens when the layout is initialized when the power is turned on.


Possible number of turnouts control channels

All Arduino Trains apps have a switching turnout control function. The number of control buttons is not directly related to the number of turnouts on the layout. In some cases, thanks to the algorithm, you can switch several turnouts at once with one button. Moreover, this is the preferred method, since the control system primarily controls the track segments.

The ability to control of turnouts increasing from the 1 in the LOCALS app, to the ability to control 17 channels for two-positioning turnouts and all types of switches in the DUO and QUADRO applications.

Sketches coding by the rules of Protocol 3 work the same for all my applications. Methods and examples of connecting any drives for switching turnouts to Arduino you can see here.

Feedback and sensors

Bluetooth connection between an Android device (phone or tablet) and COMM can transfer data in both directions. Organizing the transfer of telemetry from railway devices to the application, we can implement the feedback mode.

Feedback allows for the opportunity to use sensors to control trains. Two feedback options are supported: automatic train stop with sound and color indication in the UI of application and displaying in the application the real position of turnouts on the layout. The first possibility is called AWS and ways to apply this subsystem are constantly evolving. You can program AWS for any events occurring on your layout. The video shows the option of automatically stopping the train before the dead end, here with the train throttle lever in the application is also set to the start position. This feature is especially useful when you don't see a train, for example in a tunnel.


Applications that support this feature


Automatic trains driving, timetable and routing

This option is available only to members of the URB Club.



Arduino sketches

In the URB project, sketches are divided into 4 modules. The first module describes global variables, and, if necessary, their initial values. Adds required for this unit of the library. First part also mandatory to have the function of reloading a unit on an external command. There also overriding the Arduino pins using the #define component. In the second part, the modes of the Arduino pins are set, the used libraries are initialized and running commands are given to your layout devices so they took the default position. The third part is the loop, and it is in it that all commands are executed.

Your layout is quite complex in terms of wakeup control. The position of turnouts and signals, the order and logic of the power switching on of the lines, the state of the global settings at the power-up of the railway layout must be uniquely determined. In this project, this problem is resolved in two ways. The first, obvious, in the void setup(), you describe not only the purpose of the GPIO pins, but also their meaning. Then you, in accordance with them, bring the layout elements to the initial state. The second way is to use the RESET function. This function resets each URB by a common command. Then the same thing happens as in the first method. The reset command in the Protocol 3 has the syntax "rstz", and is executed every time the application is successfully connected via Bluetooth. You can also force the layout lines at any time by pressing the RESET button in the app. As soon as in the third part of the sketch is recognized of the reset command, control is transferred to the reset function void(* resetFunc) (void) = 0;

The fourth part of the sketch, which causes many difficulties in understanding it, is the function. The code in the ATmega microcontrollers in a void loop() is executed sequentially line by line. One wonders, therefore, how running Arduino libraries if their code is not in a loop.

Imagine the situation, you leave to the doorstep/threshold of your house and saw that it was raining. You return home, take an umbrella and again return on a threshold. That is, you are on the doorstep again, but you have an umbrella. The functions and libraries works in a similar way. Your sketch will be executed line by line with the ATmega microcontroller until it find the instruction yourfunction() (call function), after which it will go to the code block void yourfunction() {...} and then return to the main code.

You can assign any name to your function. Here is a simple example of a modified BLINK sketch code from examples Arduino IDE:

void setup() {

// the loop function runs over and over again forever
void loop() {

void yourfavoritname() {
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(LED_BUILTIN, LOW);

The library code is called in the same way. That is, the library is a function! That is, the principle of line-by-line code execution is always respected for Arduino NANO, UNO, MEGA.

Often in programming, there is a situation that, along with the code performed by a function, it needs to transfer data (for libraries this is the main running way). For this, parameters are put in parentheses, here is an example:

void receiveI2C(int howMany) {
  while (Wire.available() > 0) {
    dataFromI2C =;

This function from the snippet for the local unit accepts commands on the I2C bus. You won’t need to write such complex function calls in the URB project, all you need to understand is a simple function call without parameters.

Function for URB is the basis of the sketch modularity. You will need to add to your sketch only the functions that are needed for your devices. For example, if you only need to control trains by one Driver, without control on turnouts, lighting, etc., you only need a void driver1() function on COMM.

Protocol 3

The URB project uses multiple URB units (or individual Arduino boards) simultaneously, and also receives and transmits data to and from the application on an Android device. Therefore, a standard is needed for data exchange.

For Arduino there is a very large number of protocols for data exchange. For example, Firmata or NMEA 0183. But they are all complicated for this project, in addition, if you use the library implementation code of the protocol, then you cannot change anything in it, and this significantly limits the ability to connect various devices on the railway layout. In a railway model, there is not a lot of data flow and the speed of passing them is also not very important. Therefore, you can use a very simple protocol. It consists of four characters, the last character nbsp;– "z" indicates the end of the command. Combination of the first three letters or numbers gives a lot of variants the commands.

For example, for switching turnout A command are ""ja1z" and "ja0z". In the sketches of Arduino they are parsing by such a well-known block of Serial Event:

// start parsing switching turnouts command                    
if (inputString.charAt(0) =='j') {
 // select Turnout A
  if (inputString.charAt(1) =='a') { 
    if (inputString.charAt(2) =='1') { 
        // Code for switch Turnout to throw position
        Bluetooth.print("ja1z"); // feedback command
    if (inputString.charAt(2) =='0') { 
        // Code for switch Turnout to branch position
        Bluetooth.print("ja0z"); // feedback command

For testing and adjusting your layout devices you can type these commands directly into the Serial Terminal of Arduino IDE.

Typical connections

Ways to connect different types of point-motors

The URB Project you can connect any types point-motors for switching turnouts – servo, electromagneticm, and having a stepper or DC motor. If the servo is used as drive for switching turnouts then all you need to use is the Servo library integrated into the Arduino IDE environment. If a DC Motor or an electromagnet coils are used as drives, the situation changes as follows. 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 switch point rails of your turnout or to rotate motor. Therefore, a booster 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 the same motor driver L298, only in this case it works without PWM pins. It also allows you to manipulate the polarity at its outputs, that is, you can connect not only DC motors in reverse mode, but also KATO point motors.

If you have a very specific drive or you prefer a circuit with control of your drive via conventional buttons, then use a conventional relay instead of buttons.

LEDs and bulbs connections

The voltage on the Arduino pins is equal to the supply voltage of the MCU. ATmega328 can operate in the range from 1.5 to 5.5 V. The current for each GPIO in OUTPUT mode is no more up to 40mA. Such voltage and current are sufficient only for signal LEDs, while it is necessary to install a series-limiting resistor of near 100 Ohm.

To control a load with a different voltage and high current, I suggest repeating the trick described above. But for lighting, I suggest using the Darlington array. You do not need to shoulder to assemble this ULN2003 chip into a circuit – there is a ready-made module based on this chip. This device is called ULN2003 Stepper Motor Driver Module. When creating a circuit with this device, it is important to remember that this module must be included with a POSITIVE common wire. Using this module, you will get a maximum current at each output of about 200 mA and a maximum voltage of 52 V. If you need a current of more than 200mA, then connect the outputs in parallel.

You can also use a relay, but you will not be able to use lighting effects. I consider using a relay to control the lights to be the worst option.