Project tutorial
Automated Model Railroad Layout With Reverse Loops

Automated Model Railroad Layout With Reverse Loops © CC BY-NC-ND

Automate a point-to-point model railroad with reverse loops to make the train move continuously forward.

  • 1,775 views
  • 0 comments
  • 3 respects

Components and supplies

Necessary tools and machines

26w6260 40
Multitool, Screwdriver
A screwdriver with a small chisel end to tighten terminal screws of the motor driver sheid.

Apps and online services

About this project

In one of my previous tutorials, I showed how to make a Simple Automated Point to Point Model Railroad. One of the main disadvantages of that project was that the train had to move in the reverse direction for going back to the starting point. Running a train in that layout meant that it had to run in reverse with the locomotive at the back. So, in this tutorial, let's learn to make a similar layout with a reverse loop at each end so our train can run in the forward direction all the time. Let's get started!

Step 1: Watch the Video

Watch the above video to get a better understanding of this project.

Step 2: Get All the Required Stuff
if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['f54e3ff9e4'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303105/FIE6YKAKBTDFF77.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303104/F0WW7UUKBTDFF78.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

For this project, you will need:

Electronic supplies:

  • An Arduino microcontroller compatible with the Adafruit Motor Shield V2. (1)
  • An Adafruit Motor Shield V2.
  • 2 'Sensored' tracks.
  • 10 male-to-male jumper wires.
  • A 12-volt DC power source.

Model railroad supplies:

  • 2 turnouts(One for each reverse loop).
  • 3 track feeders(One for mainline and the rest two each for a reverse loop).
  • 4 insulated rail joiners(Get 4 more if the turnout being used don't have a "Power Routing" feature).

1. Any R3 Arduino board such as UNO, Leonardo, and similar ones can be used. Boards like Mega can also be used with a slight modification(Get help here).

Step 3: Program the Arduino Microcontroller

if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['97a13d59f8'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303382/automated_model_railroad_layout_with_reverse_loops___arduino_1_8_13_27-05-2021_10_46_28_mBYWhcZ2MC.png?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

I would recommend going through the Arduino code to get a deeper understanding of how the code works in making the train run around the layout.

Step 4: Replace the Rail Joiners of the Turnouts
if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['7b11454abe'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303107/F6ZBDNLKBRXZZAM.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

If the turnouts being used have a "Power Routing" feature then only the outermost rails need to be electrically isolated using insulated rail joiners. If the turnouts being used don't have this feature, all 4 rails need to be electrically isolated.

Step 5: Set Up the Layout
if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['05501caccb'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303108/F2HDUSTKBRXZZAK.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303109/FOL48OLKBRXZZAL.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

The 'sensored' track will be installed at the entrance of each of the reverse loops. The mainline and the two reverse loops each will have a separate feeder track.

Decide which one of the loops will be loop A and B. The loop into which the train will enter first on startup will be loop A and the other will be loop B. So, the turnout in loop A will be turnout A, and one in loop B will be turnout B.

Step 6: Install the Motor Shield on the Arduino Board and Connect the Track Power and Turnouts
if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['542347512e'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303116/FZ2N9E4KBRXZZAH.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303113/FMY37BJKBTDFGCE.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303111/FD3ZFX5KBTDFGBU.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303114/F2059EQKBRXZZ9R.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303112/F8065HAKBTDFGC5.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303110/FWA3EFEKBTDFGBV.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303115/F1KN9Y4KBRXZZAG.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

Turnouts:

Both the turnouts need to be connected in parallel but in opposite polarities so that they always switch in the opposite directions.

  • Connect the turnout A to the motor shield as shown in picture 4.
  • Connect the turnout B to the motor shield as shown in picture 5.

Track feeders:

The track feeders for both the reverse loops need to be connected in parallel with the same polarities so that the train moves in the same direction in both the loops, i.e., entering in from the branched line of the turnout and leaving from the straight side(Watch the video in Step 1 for clarification).

  • Connect the mainline's feeder power wires to the motor shield as shown in picture 5. Make sure the polarity of the connection is such that the train moves into loop A on startup.
  • Connect the loops' feeders' power wires to the motor shield as shown in picture 6.

Step 7: Connect the Sensors
if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['98805d2bac'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303119/F1TETPCKBRXZZ9Q.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303117/FSYQS4NKBRXZZ9N.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303118/FOSEZ29KBRXZZ9P.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

Connect the sensors' -ve pin to the 'GND' header and the +v pins to the +5-volt header. The 'IQREF' pin of an Arduino board can also be used as a +5-volt connection to power sensors for boards working on a logic voltage level of 5-volts.

Connect the sensor's output pin adjacent to the first reverse loop to the input 'A0' of the Arduino board and the output pin of the sensor adjacent to the second reverse loop to the input pin 'A1' of the Arduino board.

Step 8: Double-check All the Wiring Connections

Make sure all the wiring has been done correctly and no connections are loose.

Step 9: Connect the Setup to Power
if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['74e719d177'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303121/FQPBVJKKBRXZZ9O.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' },{ URL: 'https://hackster.imgix.net/uploads/attachments/1303120/FK0WRNOKBRXZZ9J.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

You can either connect the Adapter to the Arduino board's female DC jack connector or you can use the terminal block on the motor shield to power up the setup.

Step 10: Place the Train/locomotive on the Mainline

if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['ce72a32af0'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303122/F8PHJEVKBRXZZ9M.jpg?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

Using a rerailer tool is highly recommended, especially for steam locomotives. Make sure that the wheels of the locomotive and the rolling stock(If using) are properly aligned with the track.

Step 11: Power Up the Setup

if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['7b08cd8026'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303385/img_2535_t2kaxkp84Q.JPG?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

Step 12: Watch Your Train Go

After powerup, the turnout in loop A should switch to side and the turnout in loop B should switch to straight. After then, the train/locomotive should start to proceed towards loop A.

If something goes wrong, power down the setup immediately to prevent the motor drivers from getting fried.

Step 13: Troubleshoot If Required

If particular turnout switches in the wrong way, reverse the polarity of its connection. Do the same for the track power feeders if the train starts to move in the wrong direction.

If the setup resets after a while after startup even when the turnouts are switching correctly, check the polarity of connection of the track feeders of the reverse loops and make sure the current is flowing in the correct direction, reverse the polarity if needed.

Step 14: Go Furthur!

if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages['02bea03c50'] = [{ URL: 'https://hackster.imgix.net/uploads/attachments/1303387/img_2536_tmfYkoSsFv.JPG?auto=compress%2Cformat&w=1280&h=960&fit=max', caption: '', type: 'image' }];

After you have got your project working successfully, why not tinker with it? Change the Arduino code to suit your needs, add more features, maybe a passing siding? Or run multiple trains? Whatever you do, all the best!

Code

Arduino CodeArduino
/*
   Arduino program to automate a continous-running single-track model railroad layout with
   reverse loops.

   Made by TechBuild: https://www.youtube.com/channel/UCNy7DyfhSD9jsQEgNwETp9g?sub_confirmation=1

   Feel free to modify the code to suit your layout.
*/
#include<Adafruit_MotorShield.h>//Make sure this library is installed in your IDE.


Adafruit_MotorShield AFMS = Adafruit_MotorShield();

Adafruit_DCMotor *mainline = AFMS.getMotor(1);//Connected to the single-track mainline's feeder.
Adafruit_DCMotor *loopline = AFMS.getMotor(2);//Connected to the two reverse loops' feeders.
Adafruit_DCMotor *turnout = AFMS.getMotor(4);//Connected to the reverse loops' turnouts connected in parallel.

#define sensorA A0//Sensor on mainline at the entrance of the first reverse loop.
#define sensorB A1//Sensor on mainline at the entrance of the second reverse loop.

int s;//Variable for storing the speed of the locomotive(0 to 255, from stop to max speed).
int tripCount = 2;//Number to trips the train will make around the layout.
int i;//Variable for use in a for() loop for tripCount.

//All the below values should be in the range of 0-255.
//Most locomotives don't start to move until 30.
//Speed vales greater than 180 might be too much for a model railroad.
int StandBySpeed = 35;//Speed at which the locomotive's lights turn on while it is still at rest(Not all locomotives can do this!).
int SlowSpeed = 60;//Speed at which the locomotive will start to move.
int FastSpeed = 90;//Maximum speed of the locomotive.

//Function to set the speed and direction of the locomotive on the mainline depending on the
//vlaue and the sign(+/-) of the variable 'sp', ranging from -255 to 255.
void mainlinePwr(int sp)
{
  if (sp > 0)
  {
    mainline->setSpeed(sp);
    mainline->run(FORWARD);
  }

  if (sp < 0)
  {
    mainline->setSpeed(-sp);
    mainline->run(BACKWARD);
  }

  if (sp == 0)
  {
    mainline->setSpeed(sp);
    mainline->run(RELEASE);
  }

}

//Functions to switch the turnouts to staright or side.

/*When this function is called(activated), the turnout in the first reverse loop must switch
  to straight and the turnout in the second reverse loop must switch to side.
*/
void turnout_straight()
{
  turnout->run(FORWARD);
  delay(50);
  turnout->run(RELEASE);
}

/*When this function is called(activated), the turnout in the first reverse loop must switch
  to side and the turnout in the second reverse loop must switch to straight.
*/
void turnout_side()
{
  turnout->run(BACKWARD);
  delay(50);
  turnout->run(RELEASE);
}

/*
   Custom function made to wait for the train to pass the 'sensored' track connected to the
   input pin declared in the bracket(in the place of int i in void loop()).

   The sensor's output does not remains steady HIGH when a train is passing over it.
   This can be observed by the flickering light of the sensor when the train crosses over it.

   This means that the earlier used while() statement can't be used here.

   To slove, it a for() loop is made which waits for the sensor output to remain_track low for
   a long enough time to ensure that the train has crossed the 'sensored' track.

   When the train crosses the 'sensored' track, the ocasional flicker of the LED(Meaning that
   sensor is sending digital HIGH signals to the Aruino board.) causes the loop to reset.
   This loop ends only sfter the complete train has crossed the 'sensored' track.
*/
void waitToPass(int q, int t) { //Variable q 'tells' which sensor to consider.
  //Variable t 'tells' the clearance delay(in seconds).
  int a;
  while (digitalRead(q) != HIGH);
b:
  for (a = 0; a != 1000 * t; a++) {
    if (digitalRead(q) == HIGH) goto b; //If the sensor output turns HIGH in between the for() loop, it will start over.
    delay(1);
  }
}


void setup() {
  // put your setup code here, to run once:

  AFMS.begin(960);

  loopline->run(FORWARD);//Set the direction of current in both the reverse loops.
  //This will remain constant forever.

  turnout->setSpeed(255);//Allow maximum voltage(=supply voltage) to be applied to the turnouts whenever they need to be switched.


  //Switches the turnouts in both the directions on startup.
  //This can help check if the turnouts arr working or not.
  turnout_straight();

  turnout_side();


  //Set pins for the sensors as digital inputs.
  pinMode(sensorA, INPUT);
  pinMode(sensorB, INPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

  for (s = 0; s != StandBySpeed; s++)
  {
    mainlinePwr(s);
    loopline->setSpeed(s);
    delay(30);
  }

  delay(2000);

  for (s = s; s != SlowSpeed; s++)
  {
    mainlinePwr(s);
    loopline->setSpeed(s);
    delay(125);
  }


  //
  /*
     The below loop will go on until the value of the variable 'i' matches the value of the
     variable 'tripCount', i.e., until the train makes the set number of trips around the layout.
  */
  for (i = 0; i != tripCount; i++)
  {
    while (digitalRead(sensorA) != HIGH);

    waitToPass(sensorA, 4);

    mainlinePwr(-s);

    turnout_straight();

    for (s = s; s != FastSpeed; s++)
    {
      mainlinePwr(-s);
      loopline->setSpeed(s);
      delay(125);
    }

    while (digitalRead(sensorB) != HIGH);

    waitToPass(sensorB, 4);

    mainlinePwr(s);

    turnout_side();
  }
  //


  for (s = s; s != SlowSpeed; s--)
  {
    mainlinePwr(s);
    loopline->setSpeed(s);
    delay(250);
  }

  while (digitalRead(sensorB) != HIGH);

  waitToPass(sensorB, 1);

  for (s = s; s != StandBySpeed; s--)
  {
    mainlinePwr(s);
    loopline->setSpeed(s);
    delay(60);
  }

  delay(2000);

  for (s = s; s != 0; s--)
  {
    mainlinePwr(s);
    loopline->setSpeed(s);
    delay(60);
  }

  delay(5000);//Wait for a set amount of time before starting the entire process again.





}

Comments

Similar projects you might like

Simple Automated Model Railroad Loop with Yard Siding

Project tutorial by Kushagra Keshari

  • 5,211 views
  • 0 comments
  • 12 respects

Automated Point to Point Model Railroad with Yard Siding

Project tutorial by Kushagra Keshari

  • 3,654 views
  • 1 comment
  • 15 respects

Simple Automated Model Railway Layout | Arduino Controlled

Project tutorial by Kushagra Keshari

  • 20,751 views
  • 1 comment
  • 25 respects

Simple Automated Point to Point Model Railroad

Project tutorial by Kushagra Keshari

  • 6,556 views
  • 4 comments
  • 14 respects

Automated Model Railway Layout with Passing Siding

Project tutorial by Kushagra Keshari

  • 18,000 views
  • 13 comments
  • 50 respects

Model Railway Layout with Automated Passing Siding (V2.0)

Project tutorial by Kushagra Keshari

  • 2,976 views
  • 0 comments
  • 10 respects
Add projectSign up / Login