Arduino IDE

Modellers like a complex systems. If you look at any of your layouts or rail lines, then it's always a lot of wires and swithes. But when the modeler sees Arduino sketch of 400 lines for his layout, then this amount of code scares him. My American friend Dan, was so scared saw the code of Arduino that he abandoned railway modelism and began to manufacture toy furniture:)

In fact, the amount of code Arduino directly corresponds to the complexity of your track-plan and layout. But the good news is that what the more Arduino boards you use in your layout, the simpler and shorter the code of sketches. If you want to immediately try to apply the URB project to your complex layout without minimal experience using Arduino, then you will not succeed. In my experience and Dan's experience, it's better to do it gradually.

I've been thinking for a whole year how to simplify your entry-point into this system, and do not turn the project into a rigid design in which you can not do anything yourself. And I managed to make the code modular.

Another common mistake is the use of microcontrollers that are in trend. Even my friends, professional C++ programmers first-time microcontrollers programming, before writing code for modern microcontrollers from AVR, NRF, Intel, AMD and so one start learning experiment with ATmega328 from Microchip (Arduino UNO/NANO). Modellers, on the contrary, for strange reasons, buying the ESP32 Devkit or Cortex-base boards and try to use it right away. After which they can’t even load the sketch from Arduino IDE into them and... People end up renouncing their project of using Arduino. Therefore, I repeat here the phrase from the Hardware section – if you are just starting to use Arduino, use entry-level microcontrollers.

Unfortunately, the information on the arduino.cc portal also adds confusion. The main direction of the development of the Arduino platform is now aimed at Cloud computing and migration to online programming. The Arduino project has lost the clone war and is now trying to make money on access to its servers. To create railway electronics, this is redundant.


Arduino sketches

In the URB project, sketches are divided into 4 modules. The first module describes global variables, and, if necessary, their initial values. Declares 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 compile component. In the second part, the modes of the Arduino pins are set, the used libraries are initialized and running commands are given to the 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. And the last part is the functions that will be discussed in detail later.

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 has the syntax «999z», 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 DEFAULT 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 second difficult part of the code, 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 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 meaning of the function is the same. 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() {
  pinMode(LED_BUILTIN, OUTPUT);
}

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

void yourfavoritname() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);                    
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);  
}                       
                     

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 putting in parentheses, here is an example:

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

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 controlPlayerA(); function on COMM.

More complex microcontrollers have an operating system instead of an infinite loop. The Arduino IDE programming environment was originally created specifically for the creation of line-by-line code execution, so for new microcontrollers (for example ESP or AVR) you will need to install plug-ins for these microcontrollers.


Serial Event

As you already know, in my project the console is the any Android phone or tablet with the Arduino Trains application. In addition to the fact that you immediately get several a ready «free» and wireless management consoles, this solution transfers the configuration of the logic and algorithms of your layout to the network of Arduino blocks located directly on the layout. This is a very big difference from the usual model of building electronics on the layout, since you are building a distributed control system. This solution allows you to perform most of the control algorithms locally, which greatly simplifies and speeds up the setup and programming of sketches.

The basic concept of the URB Project is just a simple and understandable code that you can write yourself. Only simple codes and standard Arduino libraries are used. My friend says a great phrase about Arduino: Don’t be afraid of programming, for Arduino programming is like teaching the dog to execute commands. To do this, all communications between the Arduino Train app and Arduino are based on the example of communications from the Arduino IDE. And this example is fundamental for understanding the URB control system as a whole.

I assume that you already know how to apply a sketch to rotate a servo (see File → Examples →Servo → Sweep). Let's apply the SerialEvent example for controlling a servo directly from your computer from Arduino IDE. We need a control system, not an autonomous servo rotation. Let's correct it by leaving the same circuit. For this, we will also use a ready-made Serial Event sketch (File → Examples → Communiction → SerialEvent), adding to it the code from the previous example.

Servo control circuit

I changed and expanded the capabilities of the sketch a bit, leading it to the rules for writing code for my project. But it's still SerialEvent.

Arduino Terminal
#include <Servo.h>

// GPIO
#define SERVO 2

Servo myservo;

// VARIABLES 
bool stringComplete = false;
String inputString = ""; 
int angle = 0;

void setup() {
  Serial.begin(9600);
  inputString.reserve(4);
  Serial.print("Start");
  myservo.attach(SERVO);
}

void loop() {

// ---- START PARSING INCOMING APP COMMANDS
  if (stringComplete) {
    if (inputString.charAt(0) =='a') {

      if (inputString.charAt(1) =='0') {
        if (inputString.charAt(2) =='0') angle = 0;        
        if (inputString.charAt(2) =='1') angle = 10;
        if (inputString.charAt(2) =='2') angle = 20;
        if (inputString.charAt(2) =='3') angle = 30;
        if (inputString.charAt(2) =='4') angle = 40;
        if (inputString.charAt(2) =='5') angle = 50;
        if (inputString.charAt(2) =='6') angle = 60;        
        if (inputString.charAt(2) =='7') angle = 70;
        if (inputString.charAt(2) =='8') angle = 80;
        if (inputString.charAt(2) =='9') angle = 90;
      } 
      if (inputString.charAt(1) =='1') {
        if (inputString.charAt(2) =='0') angle = 100;        
        if (inputString.charAt(2) =='1') angle = 110;
        if (inputString.charAt(2) =='2') angle = 120;
        if (inputString.charAt(2) =='3') angle = 130;
        if (inputString.charAt(2) =='4') angle = 140;
        if (inputString.charAt(2) =='5') angle = 150;
        if (inputString.charAt(2) =='6') angle = 160;        
        if (inputString.charAt(2) =='7') angle = 170;
        if (inputString.charAt(2) =='8') angle = 180;
      }
    }

    myservo.write(angle); 
  }

  inputString = "";
  stringComplete = false;
}

// ARDUINO - COMPUTER COMMUNICATE FUNCTION 
void serialEvent() {
  if (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == 'z') { // Flag end of command
      stringComplete = true;
    }
  }
}                                     
                     

How to use

To rotate the servo to the desired position, for example 120 degrees, write in the line of the terminal «a12z» and press Send. The «a05z» command will rotate the servo lever 50 degrees and so on. Of course, you can send the desired position of the servo, for example 180, and make parsing arriving bytes into the rotation position of a servo. But the purpose of this example is to introduce you to the universal way to transfer any symbols commands to Arduino, and it performs the actions you programmed for on these commands.


Protocol 2.5

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 can not change anything in it, and this significantly limits the ability to connect various devices on the railway layout. In railway model, there is not a lot of data flow and the speed of passing the team is also not very important. Therefore, you can use a very simple protocol. It consists of four characters, the last character – «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 straight position
        Bluetooth.print("ja1z"); // feedback command
    }
    if (inputString.charAt(2) =='0') { 
        // Code for switch Turnout to branch position
        Bluetooth.print("ja0z"); // feedback command
    }
  }
}                     
                     

So, you can change this protocol and expand it yourself. The protocol now also supports automatic train traffic control commands.

This type of command is parsing in the Part 3 of the sketch. It's based on the example of Serial Event from Arduino IDE, but is different only by the sign of the completion of the command is the symbol «z». For testing and adjusting your layout devices you can type these commands directly into the Serial Terminal of Arduino IDE. Full description of last Protocol version (currently 2.5) you will read at Orange Book.

Orange Book

Communication between Arduinos

After several successful experiments railway modeler will faces the problem of lack of free I/O pins (GPIO) on Arduino. And many people try to solve this problem directly, change board UNO or NANO to bigger Arduino (DUE, MEGA). It seems to me wrong, the problem still remains. The best way – to unite the microcontrollers to the network, allow scale the number of pins of the microcontroller to almost endlessly. The I2C bus is a good fit for this. It has native support with the Wire library in the Arduino, and has addressing in contrast to the serial connection solution. The second way to use many serial connections between Arduino boards, but for this, need use Arduino MEGA as a COMM unit.

Many Serial connections

An example of using multiple serial connections is here. This code is also based on Serial Event code, only the serial port number is different.

I2C Bus. COMM and Local URB units.

The I2C bus allows you to transfer data to the specific address of the URB unit, but, unlike a Serial connection, it can transfer it only as bytes. That is, it is necessary to translate alphanumeric (String variables) commands into numbers (Byte variables). I have introduced restrictions on the transmission of only one byte on the bus, that is, any digits from 0 to 255, this is more than enough.

I2C bus

Here is a fragment of code that sends the switch command of a turnout A from the COMM unit:

  // Switch A
  if (inputString.charAt(1) =='a') { // Branch direction
    if (inputString.charAt(2) =='0') {
      addressI2C = 4; dataToI2C = 30; sendDataViaI2C();
    }
    if (inputString.charAt(2) =='1') { // Throw direction
      addressI2C = 4; dataToI2C = 31; sendDataViaI2C();
    } 
  }                     
                     

To Local unit #4 which rotates the servo connected to it, thus changes the lever position of the turnout.

  // COMMAND PARSING
  if (dataFromI2C != 0) {
    switch (dataFromI2C) {
    case 30: J1.write(180); break;
    case 31: J1.write(0); break;                     
                     

Extended topology

In the URB project, it is possible to combine Arduino with each other using a combination of serial and I2C data transmission channels. So in my layout there are two independent I2C buses connected by a serial interface.

URB Topology
URB Topology

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 possible to extend the use sensors to control trains. And gradually will be add new features to the project. URB was originally designed for this possibility and the re-equipment of the layout Arduino hardware for the use of feedback is not required. Currently, two feedback options are supported: automatic train stop with sound and color indication in the UI of application and 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.

Realtime indicate of turnouts position

The motor switching of the turnout in railway modeling gives a lot of unobvious opportunities and gives rise to several problems. For example, the position of the turnout can be uniquely associated with traffic light signals and, as a result, get a ready signal system. But at the same time, most of the modellers make bulky and complex panels, and their upgrade will very complicity. This problem is further aggravated by the fact that the position of the arrows is not always known after the layout is turned ON.

All this was taken into account in the development of this project by changing the sketches of a particular URB, you can program any logic of the behavior of the signals. Also in the application there is a button DEFAULT, which sets turnouts to the position assigned user, the same happens when the layout is initialized when the power is turned on. Since there may be more than one player in the project, this button also helps to synchronize the position of the lines during the game. Without using feedback, the DEFAULT button is very useful.

Explanation indicate of turnouts

This situation changes when the feedback mode is activated. The command unit URB always notifies the application about changing the positions of junctions. Thus, even if two Android phones are used, the position of all junctions will be online displayed on each of them.

Feedback indicate of turnouts

To send data to Android device from COMM use simple code Bluetooth.print("a1z"). Thus, the complete code for the switch sketch of the turnout switch (see also snippets for COMM):

  // Switch A
  if (inputString.charAt(1) =='a') { // Branch direction
    if (inputString.charAt(2) =='0') {
      switch_A = false;
      Bluetooth.print("a0z"); // Feedback to App
      Serial.print("a0z");
      addressI2C = 2; dataToI2C = 30; sendDataViaI2C();
    }
    if (inputString.charAt(2) =='1') { // Throw direction
      switch_A = true;
      Bluetooth.print("a1z"); // Feedback to App
      Serial.print("a1z");      
      addressI2C = 2; dataToI2C = 31; sendDataViaI2C();
    } 
  }                     
                     

The most effective application of feedback for turnouts is possible when placing position sensors on point-motors. For example, when using a point-motor proposed here, you can switch turnouts both manually and from several Android devices with the correct control system response to all these influences.

AWS subsystem

Feedback commands «aws» («bws») and «awd» («bwd») for separate Drivers A and B have been added to protocol version 2.0.

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, herewith the train throttle lever in the application is also setted to start position. This feature is especially useful when you don't see a train, for example in a tunnel.

Code for this subsystem for Driver A:

// ----  SENSOR STATE
  if (digitalRead(SENSOR) == HIGH && !direction_forward) {
    flag_latch = true;
  }  

// ----  SENSOR EVENT
  if (flag_latch && !flag_event) {
    Bluetooth.print("awdz");
    flag_event = true; 
  }

// ----  AUTOSTOP
  if (flag_event) {
   int braking_accelerate;
   // Smooth stop train
   if (speedTrainA  > 200) braking_accelerate = speedTrainA / 11; 
   else if (speedTrainA  > 140) braking_accelerate = speedTrainA / 14; 
   else if (speedTrainA  > 90) braking_accelerate = speedTrainA / 16;     
   else if (speedTrainA  > 30) braking_accelerate = speedTrainA / 24;
   else  braking_accelerate = speedTrainA / 36;
   
   if (millis() > (accelerateTimer + 150)) {
      accelerateTimer = millis();
      if (V > 60) V = V - braking_accelerate;
      else if (V > 35) V = V - 4;  
      else { 
        V = 0;
        speedTrainA = 0;
      }  
   }                     
                     

Feedback commands «aws» different in by the fact that it does not affect the train throttle lever and does not affect control. This is an analogue of AWS in the driver’s cab, this command run lights a yellow signal and turns on a sound alert on app.

The AWS button is also used in the system to control the Interlocking process, warning about emergency events during the passage of the reverse loop, etc.

A more detailed description of the AWS subsystem is available to members of the URB club.

Sensors switch

In the Protocol, there is a command «ss1z» and «ss0z» that will turn on or off the code on COMM for processing signals from sensors. This option is available only in the Arduino Train DUO application. With the SENSOR On/Off switch, you can block sensors on the layout in real time.

To enable this switch, wrap the sensors code with a if operator, and add the function void scriptsAndSettings() to the COMM sketch:

if (sensors_enabled) {
// ----  SENSOR STATE
  if (digitalRead(SENSOR) == HIGH && !direction_forward) {
    flag_latch = true;
  }
}                        
                     

Correct indication of the direction when train passing the reverse loop

A unique feature of the URB system is the correct position of the direction buttons in the application. Thanks to the feedback, the buttons automatically switch after train passing via the loop. You can see the algorithm of this subsystem on video above. The protocol uses the «arlz» («brlz») command for this.

Correct direction train indicate

UI of automate train control

Automatic control

The URB controls the voltage on the rails, in contrast of control individual locomotives as in DCC systems. This gives advantages inherent to analog control systems. This is especially true for automatic control and railway signaling. A working Interlocking subsystem with many implementation options, complex maneuvers of trains on a schedule and much more is natively supported by the URB system.

This is a fairly complex code that is available only to members of the URB club. Automatic train traffic is a separate topic for railway modelling. It is important to note that the implementation of automatic movement of trains requires a minimal change in the layout of your layout, in most cases you only need to add sensors and change the sketches code.

This part of the project is in development. The videos below show several uses for such a subsystem. In my opinion, first of all, it is necessary to present the possibilities of automation, so I made a video about the concept of organizing autocontrol. Since there are no restrictions on your imagination, you can come up with and implement any of your options, and even make an «alarm clock» from your layout.

Test URB unit from computer

Entry-level boards (NANO and UNO) have a very good feature – to find errors in the code, faults in the circuit you does not need an additional tool. You can do without even a tester, but it is more convenient with it. The price of these boards is very small, and I will repeat my recommendation, you should have at least three Arduino.

Regardless of the manufacturer, these boards are very reliable. I read messages from users in which they admitted to incorrectly connecting the polarity, supplying a supply voltage of more than 9 volts to a 5-volt power pin, and even the Chinese Arduino remained operational. But sometimes these extreme experiments lead to damage to the Arduino pins, the inability to download sketches and other problems.

Accordingly, to determine the problem, you need a second similar Arduino board. The principle is simple, you just change one Arduino board to another and run your experiments again.

Check-test for Arduino NANO (UNO)

If you suspect Arduino's malfunctioning. Perhaps you have damaged a pin or several pins or the sketch is not working properly. So, each Arduino pin has several levels of protection, and the first thing to do is disconnect all the wires and connect the USB cable. If you have a URB unit, then it’s still easier – remove the Arudino NANO from the connector and move it near from the computer on which Arduino IDE is installed.

Try uploading the BLINK sketch into the problematic Arduino. If this is not possible, then throw this Arduino into the trash.

If, after loading the sketch, the built-in LED flashes, this means that the main Arduino circuits are operational and the problem can only be with a specific pin. You can sequentially check pins of Arduino by connecting an external LED and sequentially be change the pin number in the BLINK sketch. Or use tester instead the LED. Checking pins in INPUT mode is performed similarly. Uploading code:

void setup() {
  pinMode (NUMBER_OF_PIN, INPUT_PULLUP); 
  Serial.begin(9600);
}

void loop() {
  Serial.println(digitalRead (NUMBER_OF_PIN));  
}
                     

And after that, look at the Terminal how data changes when shorting this pin to GND.

If in the Arduino IDE Terminal the data from this pin will not consistently show 0 or 1, then mark this pin as faulty. If your Arduino is working with the exception of the pins do you have defined, then simply do not use these GPIOs in sketches for this instance of the board.

The general principle is this: you are comparing a problematic Arduino with a known-good Arduino.


Basic troubleshooting

To examples on this site are hard to go wrong, but shit happens :)

If you have collected wires and a circuit, have included, but it does not work – we will look for the reason. At the same time you will understand how to act in such situations.

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 for check it.


...nothing working!

That's a quote from real users message. The problem is that it is impossible to guess what went wrong. Therefore, the first thing to do: Don't Panic – you can't do something fatal with voltage of 5V. The biggest mistake: creating a short circuit or overload pins of the chip will only lead to the fact that you be need a new Arduino. In most cases, problems are associated with improper installation of the device in the slot. To avoid this, all connectors of the URB unit have special marks.

If you turned ON the power (or plug USB cable) and the LEDs on the Arduino did not light up, or blinked and went out, then you incorrectly connected wires. Or you have a broken Arduino or problems with the power source.

Solution

Disconnect all wires except power wires and turn on the circuit again. If the problem persists, replace the Arduino, check the power supply with a tester and, most importantly, carefully look at the correctness of your wired connections.

The verification algorithm is simple, you need to divide your scheme into parts. And consistently add to it your items. So you localize first, and then fix the problem. Therefore, first of all, testing begins with the power supply.

Train don't move

Produced are a lot of different variants for Motor-drivers modules. There are even a few dozen modules based on the chip L298, and they differ not only in location but also in the number of pins. Most importantly, there are two standard ways to connect Arduino to dual channel drivers: by six and by four wires. My sketches provide a six-wire connection. If you have another module, change the code according to your module.

The most common two problem situations:

  • when you forgot to connect your circuit with a COMMON WIRE
  • when the Driver A is controlled from the application, and the locomotive is on rails connected to outs B, or voltage measurements are taken on the Motor-driver outputs B

Please check your wires circuit connections carefully.

Solution

First check out the Arduino pins with unplugged the Motor-Driver. When you moving the thrust slider in the application on the corresponding to the ENA and ENB of Motor-Driver pins the voltage should be change from very close to zero to the Arduino's supply voltage. When you pushing buttons for changing the direction of motion should be changed the state of the corresponding pins IN1 IN2 and IN3 IN4 from a high level to a low level and vice versa.

If all the previous steps are completed, but the locomotive still does not move, then with digital multimeter checking the condition Motor-Driver and the locomotive.

I can't connect via Bluetooth

You can use any Bluetooth modules in your project. These modules are often very similar to the HC-06(05) I recommend. Unfortunately, many people like the beautiful name of BLE and Bluetooth 4, but this standard is designed for minimum power consumption, so a level converter is needed. In addition, the assignment of pins on other modules may be completely different. Consult the documentation for your modules if you want to use them.

My applications are connected over an Android Bluetooth. The rule of verification is as follows: if you could pair the Bluetooth module with the phone, then connection is works.

Test BT connection

To finally test the connection, upload a simple sketch to your COMM unit. Open the Serial Terminal Arduino IDE. If you are not mistaken with the wires, you will see Protocol 2 commands transmitted to your COMM unit from the application.

Serial RX TX crossing

The most common mistake is the wrong connection of data wires RX TX between the Bluetooth module and the Arduino. I highly recommend using the URB unit, it solves most of the problems of this kind. In my applications, the connection between the Android phone and Arduino via bluetooth is a virtual analogue of a serial connection.

Test BT sketch

Unlock screen

Tricks

I received several complaints from users of my applications on turning off the screen of the Android device. Firstly, this is not a problem – as soon as you unlock your phone or tablet, the functionality of the application will recover. But you can also increase the sleep time of the screen when idle, or even turn off this power saving function of the Android operating system.

I have this parameter set to NEVER. Compared to the constantly on Wi-Fi, this has virtually no effect on the discharge of the battery.

The appearance of the Android operating system looks different depending on the version and graphical shell installed by the manufacturer of the phone (tablet). In my applications, it is programmatically forbidden to rotate the screen to a horizontal position so that the interface works only in portrait mode. But, in some Android devices, due to the customization of the operating system, autorotation remains on. If you have such a problem, then turn off auto-rotate in the settings of your device.

Testing your sketches

Connecting a computer directly to URB unit is a very important feature. You can debug your sketches on time on the layout, or test the circuits separately by functional blocks.

Big layout is a lot of wires, the complexity of connecting devices and their compatibility among themselves, and most importantly the inability to add or change something in the finished layout without dramatic changes in the wiring. These shortcomings are absent in the URB concept.

All wiring between the blocks is made up of four wires. For example, if you need to put a few new junctions or sensors or streetlights on the layout, you just cut the four-wire bus in the nearest place and insert another URB. It remains only to upload the sketch, and your newly installed pieces are immediately integrated into the layout. At any time you can reprogram already installed URBs directly on a layout, you just need to leave the opportunity to reach it with a mini-USB cable. This way you can change the control or setting of any layout's devices, and replace it if necessary.

Another plus is the ability to experiment with each the URB unit independently of others, and it's still an easy way to look for possible malfunctions in electrical parts on layout. It is also possible to assemble URBs with peripheral modules separately on the table. You'll tune the prototype and then will transfer it to the layout. This allows you to realize your ideas much faster.

Hidden USB connector

History of a model trains control

Model railway consoles heritage

Trains before appearance of the DCC were driven by miniature electric motors to which electricity was supplied direct via rails. Almost all modern models of locomotives can work in this mode. The principle is very simple and understandable even for children – it is enough to press a 9 volt battery to the rails and the train moves. If you change the polarity (unfold) the batteries, the train will start moving in the opposite direction. If a controlled transformer or rheostat is used instead of a battery, it becomes possible to adjust the speed by changing the voltage on the rails. In this way, have been made most of the obsolete control panels that are still very popular.

This principle of management had a significant disadvantage: if you put several locomotives on the rails, they start moving simultaneously. This was overcome by isolating individual sections of the rail and blocking them using a relay or by installing separate consoles for each section. What caused the following problem, the complexity of the electrical wiring has greatly increased. And even now you can see well-made analog railroad models with a very large number of wires. On the other hand, despite the number of wires, the principle itself is very obvious and understandable.

With the beginning of the 1980s, the concept of DCC was introduced. The voltage on the rails will constanted, and the control signals uses of time modulation were transmitted along the same rails. Accordingly, the consoles changed, now they broadcast a control signal. The decoder installed on the locomotive converted these commands into voltage and polarity to the motor. The decoder on the locomotive also added new features – motion sounds, headlight lighting effects and cockpit lighting. Now this is the main principle in railway modeling.

DCC consoles also elegantly solve the problem of switching junctions and light signalling, there is no need to separately pull the wires to motor points – there too there are decoders. But this in theory, in practice DCC has generated many new problems: when building several lines and using several locomotives, it is necessary to install boosters that distribute the load. Because of the difference in the supply voltage of the drives and locomotives, the wires again need to be pulled through the entire layout. Each manufacturer has a different command system and compatibility is still a very narrow place. Features programming of consoles and locomotives – the main part of the discussions in profile forums. And most importantly, DCC is closed, very incomprehensible and very the cumbersome solution compared to the classical one. For example, troubleshooting in decoders, boosters or in the console itself is very difficult.

Since the beginning of the mass distribution of computers and modern electronics, the modelers have created several universal DCC standards, but in my opinion this all now looks like a giant zoo of disparate and very over-complicated devices.
Modern digital consoles are very good and similar to a specialized computer with a lot of blocks, and it seems to me that they contradict the principle of Occam's razor. Also the price of such a set is simply fantastic.

If you look at these solutions from the side – it's obvious that the DCC is just a data bus and microcontrollers installed in the console and decoders. And if you try to use Arduino, and this is a microcontroller Atmega, you can use both the classic control option and the DCC.
Combinations of DCC and Arduino designed out a lot, and they work well. But I'm of the opinion that this way is too complicated. Therefore, I returned to DC concept, only instead of the transformer I apply the ready-made block L298 with Pulse-width modulation PWM) to control locos. Also for Arduino there are a lot of reliable cheap modules. The Arduino programming language is very simple and flexible. Reprogramming Arduino gives you almost infinite possibilities for updating the layout. It's like updating the firmware of modern electronic gadgets. As the site is being updated, I will publish new ideas on automation and drawing of railway devices. Now on the site you will find all the necessary details for creating switching motors, light signals, consoles and many others. Using this information, any fashion designer can, step by step, realize his own projects.