Top Logo Sp Logo
Make Your Trains Run on Time – Automate Model Train Controls and Set it to Your Schedule with Arduino UNO

Make Your Trains Run on Time – Automate Model Train Controls and Set it to Your Schedule with Arduino UNO

Make Your Trains Run on Time – Automate Model Train Controls and Set it to Your Schedule with Arduino UNO

Want to program your train set to run according to your schedule?

In this project, inspired by Steve Massikker of arduinorailwaycontrol.com, we will use Arduino Uno to create a simple scheme for automatic train control that can be reconfigured to generate any movement pattern.

Here’s what you’ll need:

That’s it!

Swing Script Code

The following code runs a script that will stop the train smoothly at the time you set, then after a pause begin moving in the opposite direction in a repeating cycle.  Below we will break down the variables you can adjust to change the timing or create your own movement patterns.

// L298 

#define L298_ENA 5

#define L298_IN1 6

#define L298_IN2 7

// SCRIPTS VARIABLES

int counterScheduler;

unsigned long timerScheduler = 0;

unsigned long timerLocal = 0;

byte speedAuto = 0;

void setup() {

// Initializing pins

  pinMode(L298_ENA, OUTPUT);

  pinMode(L298_IN1, OUTPUT);

  pinMode(L298_IN2, OUTPUT);

// Set default direction to FORWARD

  digitalWrite(L298_IN1, HIGH);

  digitalWrite(L298_IN2, LOW); 

}

void loop() {

   // Start Scheduler

    if (millis() > (timerScheduler + 1000)) {  // Tick every 1 sec

      counterScheduler++; 

      timerScheduler = millis();

    }  

    // ------------- SCRIPT SWING

    int brakingDelta = 5;

    int accelerateDelta = 6;

    // 1  | 0 > Time < 5 sec

    if (counterScheduler <= 5) {  

        // Start train

        if (millis() > (timerLocal + 100)) {

          if (speedAuto < 240) speedAuto = speedAuto + accelerateDelta;

          else speedAuto = 255;

          analogWrite(L298_ENA, speedAuto); 

          timerLocal = millis();

        }   

    }       

    // 2  | 10 sec > Time < 15 sec

    if ((counterScheduler >= 10) && (counterScheduler <= 15)) {  // Stop train after 10 sec

        // Stop train

        if (millis() > (timerLocal + 100)) {

          if (speedAuto > 30) speedAuto = speedAuto - brakingDelta;

          else speedAuto = 0;

          analogWrite(L298_ENA, speedAuto); 

          timerLocal = millis();

        } 

    }  

    // 3  | Change direction

    if (counterScheduler == 16) {  

        digitalWrite(L298_IN1, LOW);

        digitalWrite(L298_IN2, HIGH); 

    }   

    // 4  | 20 sec > Time < 30 sec

    if ((counterScheduler >= 20) && (counterScheduler <= 30)) {  

        // Start train

        if (millis() > (timerLocal + 100)) {

          if (speedAuto < 240) speedAuto = speedAuto + accelerateDelta;

          else speedAuto = 255;

          analogWrite(L298_ENA, speedAuto); 

          timerLocal = millis();

        } 

    }       

    // 5  | 31 sec > Time < 40 sec

    if ((counterScheduler >= 31) && (counterScheduler <= 40)) {  // Stop train

        // Stop train

        if (millis() > (timerLocal + 100)) {

          if (speedAuto > 30) speedAuto = speedAuto - brakingDelta;

          else speedAuto = 0;

          analogWrite(L298_ENA, speedAuto); 

          timerLocal = millis();

        } 

    }    

    // 6  | Return to Step 1

    if (counterScheduler > 40) {

        counterScheduler = 0;   

        digitalWrite(L298_IN1, HIGH);

        digitalWrite(L298_IN2, LOW); 

   }

}

Altering the Schedule

By changing the following parameters in the above sketch, you can create any pattern of automatic movement you want for your train set.

Here’s how we’ll alter the time parameters:


// 1  | 0 > Time < 5 sec

if (counterScheduler <= 5) { 

......

// 2  | 10 sec > Time < 15 sec

if ((counterScheduler >= 10) && (counterScheduler <= 15)) { 

......

// 3  | Change direction

if (counterScheduler == 16) {

.... etc.


This sets a timetable.  It controls when the train starts, how long it runs before it stops, and how long before it starts again.

Its direction is determined by the state of pins D6 and D7:

// Set default direction to FORWARD

 digitalWrite(L298_IN1, HIGH);

 digitalWrite(L298_IN2, LOW); 


You can also reconfigure the train’s braking and acceleration with these variables:

int brakingDelta = 5;

 int accelerateDelta = 6;

Note that these simple controls will start and stop the train purely as a function of time.  While you can get your trains to do a lot of things by adjusting the above parameters, you can gain even greater control over their movements by adding various sensors to your circuit and programming them accordingly (for instance, to get your train to automatically stop every time it reaches a certain station).  But this project should provide a good basis to get you started.


Wiring

Here is the schematic to wire your circuit:

Now that you’ve got your trains running on a schedule, see what else you can get them to do with Arduino… All aboard!


For more ideas you can try using Arduino and Raspberry Pi, be sure to check back here on our Vilros Projects blog for more fun electronics projects!

Shop the story