Automated Model Train Schedule
Program your model trains to run on a timetable using Arduino and L298 motor driver with customizable timing scripts.
- Arduino
- Intermediate
- 60 minutes
- 4 steps
Shop this project
CartYou'll need
Arduino Uno Rev 3Board Only$32.24
Male-Male Jumper Wires (Set of 65-assorted sized and colors)$6.99
Prices from vilros.com. Tax and shipping at checkout.
Before you start, you'll need
- Arduino Uno
- L298 motor driver module
- Jumper wires
- Model train track and locomotive
- Power supply for track
Connect the L298 motor driver
About 15 minutes
Wire Arduino to control train power.
- Connect L298 ENA to Arduino Pin 5 (PWM for speed control).
- Connect L298 IN1 to Arduino Pin 6 (direction).
- Connect L298 IN2 to Arduino Pin 7 (direction).
- Connect L298 output terminals to track power feeders.
- Connect L298 power input to track power supply.
- Connect Arduino GND to L298 GND.
You should see
L298 is wired between Arduino and train track.
Upload the swing script
About 20 minutes
Program automatic back-and-forth movement.
- Open Arduino IDE and create a new sketch.
- Copy the complete swing script code below.
- The script starts the train, runs for 10 seconds, stops smoothly, pauses, then reverses.
- Upload to your Arduino.
#define L298_ENA 5
#define L298_IN1 6
#define L298_IN2 7
int counterScheduler;
unsigned long timerScheduler = 0;
unsigned long timerLocal = 0;
byte speedAuto = 0;
void setup() {
pinMode(L298_ENA, OUTPUT);
pinMode(L298_IN1, OUTPUT);
pinMode(L298_IN2, OUTPUT);
digitalWrite(L298_IN1, HIGH);
digitalWrite(L298_IN2, LOW);
}
void loop() {
if (millis() > (timerScheduler + 1000)) {
counterScheduler++;
timerScheduler = millis();
}
int brakingDelta = 5;
int accelerateDelta = 6;
// Start and accelerate (0-5 sec)
if (counterScheduler <= 5) {
if (millis() > (timerLocal + 100)) {
if (speedAuto < 240) speedAuto = speedAuto + accelerateDelta;
else speedAuto = 255;
analogWrite(L298_ENA, speedAuto);
timerLocal = millis();
}
}
// Stop train (10-15 sec)
if ((counterScheduler >= 10) && (counterScheduler <= 15)) {
if (millis() > (timerLocal + 100)) {
if (speedAuto > 30) speedAuto = speedAuto - brakingDelta;
else speedAuto = 0;
analogWrite(L298_ENA, speedAuto);
timerLocal = millis();
}
}
// Change direction (16 sec)
if (counterScheduler == 16) {
digitalWrite(L298_IN1, LOW);
digitalWrite(L298_IN2, HIGH);
}
// Start reverse (20-30 sec)
if ((counterScheduler >= 20) && (counterScheduler <= 30)) {
if (millis() > (timerLocal + 100)) {
if (speedAuto < 240) speedAuto = speedAuto + accelerateDelta;
else speedAuto = 255;
analogWrite(L298_ENA, speedAuto);
timerLocal = millis();
}
}
// Stop reverse (31-40 sec)
if ((counterScheduler >= 31) && (counterScheduler <= 40)) {
if (millis() > (timerLocal + 100)) {
if (speedAuto > 30) speedAuto = speedAuto - brakingDelta;
else speedAuto = 0;
analogWrite(L298_ENA, speedAuto);
timerLocal = millis();
}
}
// Return to start
if (counterScheduler > 40) {
counterScheduler = 0;
digitalWrite(L298_IN1, HIGH);
digitalWrite(L298_IN2, LOW);
}
}The train runs forward for 10 sec, stops, reverses for 10 sec, stops, and repeats.
You should see
Sketch uploads successfully.
Test the automated schedule
About 15 minutes
Watch the train follow its timetable.
- Power on the Arduino and track.
- Place the train on the track.
- Watch it accelerate, run, stop smoothly, pause, then reverse.
- The cycle repeats automatically.
You should see
The train follows the programmed schedule.
It didn't work
Train doesn't move.
Check track power connections to L298. Verify L298 output wires connect to track feeders. Test track power with a multimeter.
Customize the timing
About 10 minutes
Adjust the train schedule.
- Change timing by editing the counterScheduler comparisons.
- Adjust speed with brakingDelta and accelerateDelta variables.
- Example: if (counterScheduler <= 10) runs longer before stopping.
- Experiment with different schedules and speeds.
You should see
You can create custom train movement patterns.
What to do next
Stuck? Contact Vilros Support with your board model and what you see on screen.