Project tutorial
Arduino Train Demo for ESP32, NANO, UNO and MEGA

Arduino Train Demo for ESP32, NANO, UNO and MEGA © Apache-2.0

Many had asked to me make simple project with the simplest set of hardware, without using URB boards. You're welcome.

  • 7 views
  • 0 comments
  • 0 respects

Components and supplies

Apps and online services

Ide web
Arduino IDE
Arduino Train DEMO
Android app for phones and tablets (Android OS 6 or higher)

About this project

Hello there! I have designed a Universal Railroad Bus (URB) system as a tool for creating a model railway management system. This DC control system lets the modeler create a management system completely custom to his own layout. It is completely expandable as his layout grows. The modeler can start off slowly with a simple system and add to it as he goes along. This system provides the modeler with none of the restrictions that are characteristic of off-the-shelf control systems, such as the DCC, and without the large cash layout.

To try this system, I created a free application Arduino Train DEMO. You also need any micro controller, Bluetooth module, motor-driver and several wires. I created for you sketches that fit the most popular Arduino products - NANO, UNO, MEGA and ESP32 (for ESP32 Bluetooth module is not needed).

The sample offered here is very simple. You can use ANY model train kit with metal rails (for example, an old version of LEGO TRAINS with metal rails). Probably, if you are interested in my project, you already have such a kit or a set of rails and trains in a storage box.

The video tutorial explains the process of creating a control system for ESP32 DOIT DEVKIT. For other Arduino boards, the principle is the same, but please use the appropriate sketches and circuits.

You can expand this system infinitely by adding sound effects, managing all the elements of your railway layout and so one. All aboard!

Code

Sketch for Arduino NANO and UNOArduino
//---------------------------------------//
//   WWW.ARDUINORAILWAYCONTROL.COM       //
//---------------------------------------//
//   QUICK START                         //
//   NANO/UNO                            //
//   ARDUINO TRAIN DENO                  //
//   PROTOCOL 2.3.X                      //   
//   V.1.2020  Steve Massikker           //
//---------------------------------------//

#include <SoftwareSerial.h>


// I/O PINS

#define L298_ENA 9 // MOTOR-DRIVER L298
#define L298_IN1 8
#define L298_IN2 7

SoftwareSerial Bluetooth(12, 13); // RX, TX


// VARIABLES //
bool stringComplete = false;
String inputString = ""; 

// 6 speed
byte speedArrayA [] = {50,80,120,160,200,255};
byte speedTrainA = 0;

void setup() {

// Initializing COMM
  Serial.begin(9600);
  Bluetooth.begin(9600);
  inputString.reserve(4);

// Initializing Motor-Driver
  pinMode(L298_ENA, OUTPUT);
  pinMode(L298_IN1, OUTPUT);
  pinMode(L298_IN2, OUTPUT);

// Set PWM frequency for D9 & D10
// Timer 1 divisor to 256 for PWM frequency of 122.55 Hz
  TCCR1B = TCCR1B & B11111000 | B00000100;   

// Set default direction to FORWARD
  digitalWrite(L298_IN1, HIGH);
  digitalWrite(L298_IN2, LOW); 
}


void loop() {

// ---- START PARSING INCOMING APP COMMANDS
  if (stringComplete) {

    if (inputString.charAt(0) =='a') {
      // Speed 
      if (inputString.charAt(1) =='0') {
        if (inputString.charAt(2) =='0') speedTrainA = 0;
        if (inputString.charAt(2) =='4') speedTrainA = speedArrayA[0];
        if (inputString.charAt(2) =='8') speedTrainA = speedArrayA[1]; 
      } 
      if (inputString.charAt(1) =='1') {
        if (inputString.charAt(2) =='2') speedTrainA = speedArrayA[2];
        if (inputString.charAt(2) =='6') speedTrainA = speedArrayA[3];
      }
      if (inputString.charAt(1) =='2') {
        if (inputString.charAt(2) =='0') speedTrainA = speedArrayA[4];
        if (inputString.charAt(2) =='4') speedTrainA = speedArrayA[5];         
      }

      // Direction and Stop
      if (inputString.charAt(1) =='d') {
        if (inputString.charAt(2) =='f') { // (f) Forward
          digitalWrite(L298_IN1, HIGH);
          digitalWrite(L298_IN2, LOW); 
        }
        if (inputString.charAt(2) =='b') { // (b) Backward
          digitalWrite(L298_IN1, LOW);
          digitalWrite(L298_IN2, HIGH); 
        }
        if (inputString.charAt(2) =='s') { // (s) Stop button
          speedTrainA = 0;
        } 
      }

      analogWrite(L298_ENA, speedTrainA);
    }

    inputString = "";
    stringComplete = false;
  }
  
  bluetoothEvent();
}


//// FUNCTIONS ////

void bluetoothEvent() {
  if (Bluetooth.available()) {
    char inChar = (char)Bluetooth.read();
    inputString += inChar;
    if (inChar == 'z') {
      stringComplete = true;
    }
  }
}
Sketch for ESP32 DEVKITArduino
//---------------------------------------//
//   WWW.ARDUINORAILWAYCONTROL.COM       //
//---------------------------------------//
//   QUICK START                         //
//   ESP32 DEVKIT                        //
//   ARDUINO TRAIN DEMO                  //
//   PROTOCOL 2.3.X                      //   
//   V.1.2020  Steve Massikker           //
//---------------------------------------//


#include "BluetoothSerial.h"

#define LED_BUILTIN 2
#define L298_ENA 13
#define L298_IN1 12
#define L298_IN2 14

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;

// VARIABLES //
bool stringComplete = false;
String inputString = ""; 

// 6 speed
byte speedArrayA [] = {50,80,120,160,200,255};
byte speedTrainA = 0;


// Setting PWM properties
const int freq = 100;
const int pwmChannel_A = 0;
const int resolution = 8;
int dutyCycle = 0;


void setup() {
  SerialBT.begin("ArduinoTrain"); //Bluetooth device name
  SerialBT.register_callback(callback); // Check connection
  inputString.reserve(4);

  // Configure GPIO
  ledcSetup(pwmChannel_A, freq, resolution);

  // Attach GPIO
  ledcAttachPin(L298_ENA, pwmChannel_A);
  pinMode(L298_IN1, OUTPUT);
  pinMode(L298_IN2, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  // Set default direction to FORWARD
  digitalWrite(L298_IN1, HIGH);
  digitalWrite(L298_IN2, LOW);
}


void loop() {

// ---- START PARSING INCOMING APP COMMANDS
  if (stringComplete) {

    if (inputString.charAt(0) =='a') {
      // Speed 
      if (inputString.charAt(1) =='0') {
        if (inputString.charAt(2) =='0') speedTrainA = 0;
        if (inputString.charAt(2) =='4') speedTrainA = speedArrayA[0];
        if (inputString.charAt(2) =='8') speedTrainA = speedArrayA[1]; 
      } 
      if (inputString.charAt(1) =='1') {
        if (inputString.charAt(2) =='2') speedTrainA = speedArrayA[2];
        if (inputString.charAt(2) =='6') speedTrainA = speedArrayA[3];
      }
      if (inputString.charAt(1) =='2') {
        if (inputString.charAt(2) =='0') speedTrainA = speedArrayA[4];
        if (inputString.charAt(2) =='4') speedTrainA = speedArrayA[5];         
      }

      // Direction and Stop
      if (inputString.charAt(1) =='d') {
        if (inputString.charAt(2) =='f') { // (f) Forward
          digitalWrite(L298_IN1, HIGH);
          digitalWrite(L298_IN2, LOW); 
        }
        if (inputString.charAt(2) =='b') { // (b) Backward
          digitalWrite(L298_IN1, LOW);
          digitalWrite(L298_IN2, HIGH); 
        }
        if (inputString.charAt(2) =='s') { // (s) Stop button
          speedTrainA = 0;
        } 
      }

      ledcWrite(pwmChannel_A, speedTrainA); 
    }

    inputString = "";
    stringComplete = false;
  }
  
  bluetoothEvent();
}


//// FUNCTIONS ////

void bluetoothEvent() {
  if (SerialBT.available()) {
    char inChar = (char)SerialBT.read();
    inputString += inChar;
    if (inChar == 'z') {
      stringComplete = true;
    }
  }
}

void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param){
  if(event == ESP_SPP_SRV_OPEN_EVT) digitalWrite(LED_BUILTIN, HIGH);
  if(event == ESP_SPP_CLOSE_EVT ) {
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(L298_IN1, HIGH);
    digitalWrite(L298_IN2, LOW);
    ledcWrite(pwmChannel_A, 0); 
  }
}
Sketch for Arduino MEGAArduino
//---------------------------------------//
//   WWW.ARDUINORAILWAYCONTROL.COM       //
//---------------------------------------//
//   QUICK START                         //
//   ARDUINO MEGA                        //
//   ARDUINO TRAIN DEMO                  //
//   PROTOCOL 2.3.X                      //   
//   V.1.2020  Steve Massikker           //
//---------------------------------------//

// I/O PINS

#define L298_ENA 9 
#define L298_IN1 8
#define L298_IN2 7


// VARIABLES //
bool stringComplete = false;
String inputString = ""; 

// 6 speed
byte speedArrayA [] = {50,80,120,160,200,255};
byte speedTrainA = 0;

void setup() {

// Initializing COMM
  Serial.begin(9600); // Serial - USB
  Serial1.begin(9600); // RX - D19 | TX - D18
  inputString.reserve(4);

// Initializing Motor-Driver
  pinMode(L298_ENA, OUTPUT);
  pinMode(L298_IN1, OUTPUT);
  pinMode(L298_IN2, OUTPUT);

// Set PWM frequency for D9 & D10
// Timer 2 divisor to 256 for PWM frequency of 122.55 Hz
  TCCR2B = TCCR2B & B11111000 | B00000110;    

// Set default direction to FORWARD
  digitalWrite(L298_IN1, HIGH);
  digitalWrite(L298_IN2, LOW); 
}


void loop() {

// ---- START PARSING INCOMING APP COMMANDS
  if (stringComplete) {

    if (inputString.charAt(0) =='a') {
      // Speed 
      if (inputString.charAt(1) =='0') {
        if (inputString.charAt(2) =='0') speedTrainA = 0;
        if (inputString.charAt(2) =='4') speedTrainA = speedArrayA[0];
        if (inputString.charAt(2) =='8') speedTrainA = speedArrayA[1]; 
      } 
      if (inputString.charAt(1) =='1') {
        if (inputString.charAt(2) =='2') speedTrainA = speedArrayA[2];
        if (inputString.charAt(2) =='6') speedTrainA = speedArrayA[3];
      }
      if (inputString.charAt(1) =='2') {
        if (inputString.charAt(2) =='0') speedTrainA = speedArrayA[4];
        if (inputString.charAt(2) =='4') speedTrainA = speedArrayA[5];         
      }
    }
    // Direction and Stop
    if (inputString.charAt(1) =='d') {
      if (inputString.charAt(2) =='f') { // (f) Forward
        digitalWrite(L298_IN1, HIGH);
        digitalWrite(L298_IN2, LOW); 
      }
      if (inputString.charAt(2) =='b') { // (b) Backward
        digitalWrite(L298_IN1, LOW);
        digitalWrite(L298_IN2, HIGH); 
      }
      if (inputString.charAt(2) =='s') { // (s) Stop button
        speedTrainA = 0;
      } 
    }

    analogWrite(L298_ENA, speedTrainA);

    inputString = "";
    stringComplete = false;
  }
  
  serial1Event();
}


//// FUNCTIONS ////

void serial1Event() {
  if (Serial1.available()) {
    char inChar = (char)Serial1.read();
    inputString += inChar;
    if (inChar == 'z') {
      stringComplete = true;
    }
  }
}

Schematics

Arduino MEGA
Quick mega bxd3vs7shg
NANO/UNO
Quick nano xjpuacxot8

Comments

Similar projects you might like

ESP01 Webserver to Control Your Arduino UNO, Mega or Nano

Project tutorial by adamsstephen

  • 6,085 views
  • 3 comments
  • 17 respects

Simple UNO calculator

Project tutorial by Joprp05

  • 17,416 views
  • 3 comments
  • 17 respects

Tetris Clone With OLED SSD1306 (I2C) For Arduino Nano / Uno

Project showcase by BADFEED

  • 11,895 views
  • 8 comments
  • 37 respects

ArduTester Millenium, the ultimate UNO & MEGA Versions

Project tutorial by plouc68000

  • 1,608 views
  • 14 comments
  • 18 respects

Arduino Train for Kids 2

Project showcase by Steve Massikker

  • 16,396 views
  • 7 comments
  • 52 respects
Add projectSign up / Login