Kushagra Keshari
Published © CC BY-NC-ND

Control Your Model Train Layout with a Keyboard

Now you can easily control your model railway layout using a keyboard!

IntermediateFull instructions provided2 hours1,876
Control Your Model Train Layout with a Keyboard

Things used in this project

Hardware components

Arduino UNO & Genuino UNO
Arduino UNO & Genuino UNO
×1
Adafruit motor shield(V1)
×1
12V 5A switching power supply
Use any 12-volt DC power source with a current capacity of at least 1A
×1
USB-A to B Cable
USB-A to B Cable
×1
Jumper wires (generic)
Jumper wires (generic)
2 each for two turnouts and track power
×6

Software apps and online services

Arduino IDE
Arduino IDE
Processing
The Processing Foundation Processing

Story

Read more

Code

Code to upload on the Arduino board

Arduino
/*Arduino program for controlling model train layout with a keyboard via serial communication.
 *Watch the video here:https://www.youtube.com/watch?v=n-PcV4UAa4s
 *Tech Build:https://www.youtube.com/channel/UCNy7DyfhSD9jsQEgNwETp9g
 *This program is expandable, feel free to modify it.
 *
 */
#include <AFMotor.h>
AF_DCMotor loco(1);//The terminal block pins to connect the power feeder track.
AF_DCMotor turnout1(3);//The terminal blocks to connect the turnouts.
AF_DCMotor turnout2(4);
int i=0;
int c;
int p=0;
void halt(){
  if(i>=30){
    loco.run(FORWARD);
    for(i=i;i!=30;i--){
      loco.setSpeed(i);
      delay(12);
    }
   }
   if(i<=-30){
    loco.run(BACKWARD);
    for(i=i;i!=-30;i++){
      loco.setSpeed(-i);
      delay(12);
    }
   }
}
void turn_off(){
    if(i>=0){
    for(i;i=0;i--){
      loco.setSpeed(i);
      delay(15);
    }
   }
   if(i<=0){
    for(i;i=0;i++){
      loco.setSpeed(-i);
      delay(15);
    }
   }
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("START!");
  turnout1.setSpeed(500);
  turnout2.setSpeed(500);
  delay(500);
}

void loop() {
  // put your main code here, to run repeatedly:
if(Serial.available()){
  c=Serial.read();
  if(c == '1'&&i<=254){
    i=i+1;
  }
  if(c == '2'&&i>=-254){
    i=i-1;
  }
  if(c == '3'){
    turnout1.run(FORWARD);
    delay(50);
    turnout1.run(RELEASE);
  }
  if(c == '4'){
    turnout1.run(BACKWARD);
    delay(50);
    turnout1.run(RELEASE);
  }
  if(c == '5'){
    turnout2.run(FORWARD);
    delay(50);
    turnout2.run(RELEASE);
  }
  if(c == '6'){
    turnout2.run(BACKWARD);
    delay(50);
    turnout2.run(RELEASE);
  }
  if(c == '7'){
    halt();
    delay(1000);
    turn_off();
  }
  if(c == '8'){
   halt();
  }
   
}
   if(i>=0&&i<=254){
      loco.run(FORWARD);
      loco.setSpeed(i);
   }
   if(i<=0&&i>=-254){
      loco.run(BACKWARD);
      loco.setSpeed(-i);
   }
}

Code for control application

Java
import java.awt.event.KeyEvent;
import javax.swing.JOptionPane;
import processing.serial.*;

Serial port = null;
String portname = null;
  
boolean streaming = false;
float speed = 1;
int i=0;

void openSerialPort(){
  if(portname == null) return;
  if(port != null) port.stop();
  
  port = new Serial(this, portname, 9600);
  
  port.bufferUntil('\n');
}
void selectSerialPort(){
  String result = (String) JOptionPane.showInputDialog(frame,
  "Select the serial port to which your Arduino board is connected to",
  "Select serial port",
  JOptionPane.QUESTION_MESSAGE,
  null,
  Serial.list(),
  0);
  if (result!= null) {
    portname = result;
    openSerialPort();
  }
}
void setup(){
  size(400, 300);
  openSerialPort();
}
void draw(){
  background(3);
  fill(200);
  int y = 24, dy = 16;
  text("USAGE INSTRUCTIONS", 100, y); y +=dy;
  text("----------------------------------", 100, y); y +=dy;
  text("P:  select the serial port", 12, y); y += dy;
  text("Up arrow key:  Move locomotive forward", 12, y); y += dy;
  text("Down arrow key:  Move locomotive backward", 12, y); y += dy;
  text("Enter key:  Stop the locomotive", 12, y); y += dy;
  text("Shift key:  Power down the locomotive", 12, y); y += dy;
  text("Enter:  Stop the locomotive", 12, y); y += dy;
  text("Q:  Switch turnout1 to straight", 12, y); y += dy;
  text("W:  Switch turnout1 to right", 12, y); y += dy;
  text("E:  Switch turnout2 to left", 12, y); y += dy;
  text("R:  Switch turnout2 to straight", 12, y); y += dy;
  y = height - dy;
  text("current serial port: " + portname, 12, y); y -= dy;
}
void keyPressed(){
  if(keyCode == UP) port.write("1");
  if(keyCode == DOWN) port.write("2");
  if(key == 'w') port.write("3");
  if(key == 'q') port.write("4");
  if(key == 'e') port.write("5");
  if(key == 'r') port.write("6");
  if(keyCode == SHIFT) port.write("7");
  if(key == ENTER) port.write("8");
  if(key == 'p') selectSerialPort();
  delay(10);
}

Credits

Kushagra Keshari

Kushagra Keshari

14 projects • 26 followers
A casual electronics and a model railway hobbyist.

Comments