Kushagra Keshari
Published © CC BY-NC-ND

Automated Point to Point Model Railroad with Yard Siding

An upgraded version of a previous project which now has a yard siding to house the train.

IntermediateFull instructions provided2 hours2,198
Automated Point to Point Model Railroad with Yard Siding

Things used in this project

Hardware components

Arduino UNO & Genuino UNO
Arduino UNO & Genuino UNO
×1
Adafruit motor driver shield v2
×1
IR proximity sensor
Use appropriate sensors which can be used to make 'sensored' tracks for this project: https://www.instructables.com/id/Make-a-Low-Cost-Sensored-Track-in-Minutes/
×2
Jumper wires (generic)
Jumper wires (generic)
Two for connecting the turnout and the other two for the track power feeder to the outputs of the motor shield.
×4
Adafruit 12-volt DC power source
×1
Male/Female Jumper Wires
Male/Female Jumper Wires
Two sets of these wires containing three of them are required to connect the sensors' power, ground, and signal connection to the Arduino microcontroller.
×6

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Point_to_point_automated_model_railroad_with_yard_siding.ino

Arduino
/*
 * Arduino program for controlling a train in a point to pointlayout with a yard siding.
 * 
 * 'Sensored' tracks used for feedback:https://www.instructables.com/id/Make-a-Low-Cost-Sensored-Track-in-Minutes/
 * 
 * Made by Tech Build:https://www.youtube.com/channel/UCNy7DyfhSD9jsQEgNwETp9g/
 * 
 */
#include<Wire.h>
#include<Adafruit_MotorShield.h>//Make sure this library is installed in your Arduino IDE.

Adafruit_MotorShield AFMS = Adafruit_MotorShield();

Adafruit_DCMotor *loco = AFMS.getMotor(4);//Track power to be connected to the output of the motor shield marked M4.
Adafruit_DCMotor *turnout = AFMS.getMotor(3);//Turnout to be connected to the output of the motor shield marked M3.

int s, n;// Integer s for storing the speed and direction of the train. 
         // Integer n for storing the number of trips made by the train between points A and B.        
int m = 2;// Integer to determine the number of trips the train will make between points A and B.
int MaxSpeed = 80;// Integr to store the maximum speed at which the train will move in the mainline(0-255).

void loco_go(int i){// Custom function made to control the speed and direction of the locomotive based on the input integer and its sign(+/-).
 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);
 }
}

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

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

  AFMS.begin();

  pinMode(A0, INPUT);//Pin connected to the 'sensored' track in the yard.
  pinMode(A1, INPUT);//Pin connected to the 'sensored' track in the point A track.
  pinMode(A2, INPUT);//Pin connected to the 'sensored' track in the point B track.

  while(digitalRead(A0) != HIGH);//Wait until the train is positioned at the starting point.

  turnout_side();//Switch the turnout to connect the yard to the mainline.
}

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

  for(s=0;s!=30;s++){//Powering up the locomotive in forward direction.
    loco_go(s);
    delay(60);
  }

  for(s=s;s!=MaxSpeed;s++){//Speeding up the locomotive.
    loco_go(s);
    delay(250);
  }

  while(digitalRead(A1) != HIGH);//Waiting for the locomotive to cross the 'sensored' track installed before point A.

  for(s=s;s!=30;s--){//Slowing down the locomotive.
    loco_go(s);
    delay(250);
  }

  turnout_straight();//Switching the turnout to connect the point B track to the mainline.

  for(s=s;s!=0;s--){//Turning off the locomotive.
    loco_go(s);
    delay(60);
  }

  delay(5000);//Delay(in milliseconds) for the locomotive to halt at point A.

 for(n=0;n!=m;n++){//Number of trips made by the train will be stored in 'n'.

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

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

  while(digitalRead(A2) != HIGH);

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

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

  delay(5000);

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

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

  while(digitalRead(A1) != HIGH);

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

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

  delay(5000);
  
  }//End of the for() loop.

  /*
   * The trips made by the train between the points A and B is nnow over. The loocmotive is now at point A.
   */

  turnout_side();//Switching the turnout to connect the yard to the mainline.

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

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

  while(digitalRead(A0) != HIGH);

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

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

  delay(5000);//Delay after which the entire operation will repeat.

}

Credits

Kushagra Keshari

Kushagra Keshari

16 projects • 35 followers
A casual electronics and a model railway hobbyist.

Comments