Project tutorial
Simple Automated Point to Point Model Railroad Running Tw...

Simple Automated Point to Point Model Railroad Running Tw... © CC BY-NC-ND

An Arduino-based point-to-point model railroad automation project.

  • 340 views
  • 1 comment
  • 2 respects

Components and supplies

Apps and online services

About this project

Arduino microcontrollers are a great way of automating model railroad layouts due to their low-cost availability, open-source hardware and software and a large community to help you.

For model railroads, Arduino microcontrollers can prove to be a great resource for automating their layouts in a simple and cost-effective way. This project is such an example of automation of a multi-point model railroad layout to run two trains.

This project is an upgraded version of some of my previous point to point model railroad automation projects.

A bit into this project:

This project focusses on automating a multi-point model railroad layout which has three stations. There is a starting station, say 'A' which initially houses both the trains. The mainline track leaving the station branches into two lines which go respectively to the two stations say 'B' and 'C'.

Step 1: Watch the Video

Watch the above video to understand the operation of the layout.

Step 2: Get All the Required Stuff

Here is what you will need for this project:

  • An Arduino microcontroller compatible with the Adafruit motor shield V2.
  • An Adafruit motor shield V2. (Know more about it here.)
  • An expansion shield(Optional but highly recommended)
  • Three 'sensored' tracks.
  • 6 male to male jumper wires(To connect the turnouts and track power wires to the motor shield.)
  • 3 sets of 3 male to female jumper wires, a total of 9(To connect the sensors to the Arduino board)
  • A 12-volt DC power supply adapter with a current capacity of at least 1A(1000mA).
  • A suitable USB cable(For connecting the Arduino board to the computer).
  • A computer(For programming the Arduino board)
  • A small screwdriver

Step 3: Program the Arduino Microcontroller

Make sure you have the Adafruit's motor shield v2 library installed in your Arduino IDE, if not, press Ctrl+Shift+I, search for the Adafruit motor shield and download the latest version of the Adafruit Motor Shield v2 library.

Before uploading the code on the Arduino microcontroller, make sure to go through it to get an idea of what all is happening and how.

Step 4: Make the Layout

Click on the above image to know more about the layout and the location of each 'sensored' track and the turnout.

Step 5: Install the Motor Shield on the Arudino Board

Install the motor shield on the Arduino board by carefully aligning the pins of the shield with the herders of the Arduino board and make sure no pin gets bent.

Step 6: Connect the Turnouts to the Motor Shield

Make the following connections:

  • Connect the output of the motor shield 'M3' to turnout 'A'.
  • Connect the output of the motor shield 'M4' to turnout 'B'.

Step 7: Connect the Track Power to the Motor Shield

Connect the output of the motor shield 'M1' to the track power feeder installed in the mainline.

Step 8: Install the Expansion Shield on the Motor Shield

Step 9: Connect the 'sensored' Tracks to the Shield

Make the following connections with the 'sensored' tracks:

  • Connect each sensors' pin labeled 'power', 'VIN' or 'VCC' to the header rail of the expansion shield labeled as '+5V' or 'VCC'.
  • Connect each sensors' pin labeled 'GND' to the header rail of the expansion shield labeled as 'GND'.
  • Connect the sensor A's output to pin 'A0' of the Arduino board.
  • Connect the sensor B's output to pin 'A1' of the Arduino board.
  • Connect the sensor C's output to pin 'A2' of the Arduino board.

Step 10: Place the Trains on the Tracks in Station 'A'

Place the trains in the tracks of station A. The train A will be placed on the branch line of station A and the train B on the straight one. Refer to step 4 for more information. A diesel locomotive has been used here to represent train B.

Use of a rerailer tool is recommended, especially for steam locomotives.

Step 11: Connect the Setup to Power and Turn It On

After powering up the setup if the locomotive starts to move in the wrong direction, reverse the polarity of track power's connection with the terminals of the motor shield. If any of the turnouts switch in the wrong direction, you know what to do!

Step 12: Sit Back, Relax and Watch Your Trains Go!

If everything was done properly, then you should see the train in the sideline at station 'A' start to move and the operation to carry on as shown in the video in the first step.

Step 13: What's Next?!

If you want you can go ahead and tinker with the Arduino code and make changes to suit your needs. You can expand the layout, add more motor shields to run more trains, increase the complexity of railroad operation such as running two trains simultaneously and so on, there is a very long list of what you can do.

If you want you can also take a look at some different layout automation projects here.

Code

Automated_point_to_point_model_railroad_runjing_two_trains.inoArduino
No preview (download only).
Automated_point_to_point_model_railroad_runjing_two_trains.inoArduino
/*
 * Arduino code for automated multi point model railorad for running two trains in an 
 * automated sequence.
 * 
 * Made by Tech Build: https://www.youtube.com/channel/UCNy7DyfhSD9jsQEgNwETp9g?sub_confirmation=1
 * 
 * Find more such projects here: https://www.instructables.com/member/KushagraK7/
 * 
 * Feel free to tinker around with the code, add some features or change the existing ones
 * to suit your requirements.
 * 
 * Happy railroading!
 */
#include<Wire.h>
#include<Adafruit_MotorShield.h>//Make sure this library is installed in your IDE.

Adafruit_MotorShield AFMS = Adafruit_MotorShield();

Adafruit_DCMotor *loco = AFMS.getMotor(1);//Track power connected to the terminal 'M1'.
Adafruit_DCMotor *turnoutA = AFMS.getMotor(3);//Turnout at station 'A' connected to the terminal 'M3'.
Adafruit_DCMotor *turnoutB = AFMS.getMotor(4);//Turnout at mainline branching two tracks to stations 'B' and 'C'.

int s;              //int variable for storing the speed and direction of the train, speed ranges
                    //from -255 to 255.
int sensorA = A0;   //The sensor installed in the track approaching station A.
int sensorB = A1;   //The sensor installed in the track approaching station B.
int sensorC = A2;   //The sensor installed in the track approaching station C.
int MinSpeedA = 20; //The low speed for train A, you might need to try with different values 
                    //before settling for the optimum one.
int MinSpeedB = 55; //The low speed for train B.
int MidSpeed = 55;  //The medium speed for both the trains is kept same.
int MaxSpeedA = 80; //The maximum speed for train A when running on the mainline.
int MaxSpeedB = 100;//The maximum speed for train B when running on the mainline.

/*
 * Custom function made to adjust the speed and direction of the train based on the value and
 * sign (+/-) of variable i, between -255 and 255.
 */
void loco_go(int i){
 if(i>=1&&i<=255){
  loco->setSpeed(i);
  loco->run(FORWARD);
 }
 if(i<=-1&&i>=-255){
  loco->setSpeed(-i);
  loco->run(BACKWARD);
 }
 if(i==0){
  loco->setSpeed(i);
  loco->run(RELEASE);
 }
}

//Custom functions made for turnout switch control.

void turnoutA_side(){
turnoutA->setSpeed(255);
turnoutA->run(FORWARD);
delay(100);
turnoutA->setSpeed(0);
turnoutA->run(RELEASE);
}

void turnoutA_straight(){
turnoutA->setSpeed(255);
turnoutA->run(BACKWARD);
delay(100);
turnoutA->setSpeed(0);
turnoutA->run(RELEASE);
}

void turnoutB_side(){
turnoutB->setSpeed(255);
turnoutB->run(FORWARD);
delay(100);
turnoutB->setSpeed(0);
turnoutB->run(RELEASE);
}

void turnoutB_straight(){
turnoutB->setSpeed(255);
turnoutB->run(BACKWARD);
delay(100);
turnoutB->setSpeed(0);
turnoutB->run(RELEASE);
}
void setup() {
  // put your setup code here, to run once:

  AFMS.begin(200);//Starting the motor shield and defining the frequency of the PWM signals
                  //to be sent to the motors, you can try with different values.
                  //Here, for example, it has been set to 200Hz.

  //Declaring the pins connected to the sensors to be digital input pins.
  pinMode(sensorA, INPUT);
  pinMode(sensorB, INPUT);
  pinMode(sensorC, INPUT);
}

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


  turnoutA_side();

  for(s=0; s!=MinSpeedA; s++){
   loco_go(s);
   delay(250);
  }

  while(digitalRead(sensorA)!=HIGH);
  
  turnoutB_straight();

  for(s=s; s!=MidSpeed; s++){
    loco_go(s);
    delay(250);
  }

  delay(2000);

  for(s=s; s!=MaxSpeedA; s++){
    loco_go(s);
    delay(250);
  }

  while(digitalRead(sensorC)!=HIGH);

  for(s=s; s!=MidSpeed; s--){
    loco_go(s);
    delay(125);
  }

  for(s=s; s!=MinSpeedA; s--){
    loco_go(s);
    delay(125);
  }

  delay(4000);

  for(s=s; s!=0; s--){
    loco_go(s);
    delay(250);
  }

  turnoutB_side();
  turnoutA_straight();

  for(s=s; s!=30; s++){
    loco_go(s);
    delay(60);
  }

  for(s=s; s!=MinSpeedB; s++){
    loco_go(s);
    delay(125);
  }

  while(digitalRead(sensorA)!=HIGH);

  for(s=s; s!=MidSpeed; s++){
    loco_go(s);
    delay(125);
  }

  delay(2000);
 
  for(s=s; s!=MaxSpeedB; s++){
    loco_go(s);
    delay(250);
  }

  while(digitalRead(sensorB)!=HIGH);

  for(s=s; s!=MidSpeed; s--){
    loco_go(s);
    delay(125);
  }

  for(s=s; s!=MinSpeedB; s--){
    loco_go(s);
    delay(250);
  }

  delay(4000);

  for(s=s; s!=30; s--){
    loco_go(s);
    delay(125);
  }

  for(s=s; s!=0; s--){
    loco_go(s);
    delay(60);
  }

  turnoutB_straight();

  for(s=s; s!=-MinSpeedA; s--){
    loco_go(s);
    delay(250);
  }

  while(digitalRead(sensorC)!=HIGH);
  
  turnoutA_side();

  for(s=s; s!=-MidSpeed; s--){
    loco_go(s);
    delay(250);
  }

  delay(2000);

  for(s=s; s!=-MaxSpeedA; s--){
    loco_go(s);
    delay(250);
  }

  while(digitalRead(sensorA)!=HIGH);

   for(s=s; s!=-MidSpeed; s++){
    loco_go(s);
    delay(125);
   }

   delay(2000);

   for(s=s; s!=-MinSpeedA; s++){
    loco_go(s);
    delay(250);
   }

   delay(5000);
   
   for(s=s; s!=0; s++){
      loco_go(s);
      delay(60);
    }

  turnoutB_side();
  turnoutA_straight();

    for(s=s; s!=-30; s--){
      loco_go(s);
      delay(60);
    }

    for(s=s; s!=-MinSpeedB; s--){
    loco_go(s);
    delay(125);
  }

  while(digitalRead(sensorB)!=HIGH);

  for(s=s; s!=-MidSpeed; s--){
    loco_go(s);
    delay(250);
  }

  delay(2000);

  for(s=s; s!=-MaxSpeedB; s--){
    loco_go(s);
    delay(250);
  }

  while(digitalRead(sensorA)!=HIGH);

   for(s=s; s!=-MidSpeed; s++){
    loco_go(s);
    delay(250);
   }

   delay(1000);

   for(s=s; s!=-MinSpeedB; s++){
    loco_go(s);
    delay(250);
   }

   delay(4000);
   
   for(s=s; s!=0; s++){
      loco_go(s);
      delay(125);
    }  

}

Comments

Similar projects you might like

Simple Automated Point to Point Model Railroad

Project tutorial by Kushagra Keshari

  • 2,788 views
  • 4 comments
  • 12 respects

Automated Point to Point Model Railroad with Yard Siding

Project tutorial by Kushagra Keshari

  • 2,248 views
  • 1 comment
  • 14 respects

Simple Automated Model Railroad Loop with Yard Siding

Project tutorial by Kushagra Keshari

  • 3,515 views
  • 0 comments
  • 8 respects

Simple Automated Model Railway Layout | Arduino Controlled

Project tutorial by Kushagra Keshari

  • 9,334 views
  • 1 comment
  • 16 respects

Automated Model Railway Layout with Passing Siding

Project tutorial by Kushagra Keshari

  • 11,096 views
  • 10 comments
  • 43 respects

Control Your Model Train Layout With Your Mobile Phone!

Project tutorial by Kushagra Keshari

  • 2,905 views
  • 0 comments
  • 8 respects
Add projectSign up / Login