Let's Add a Few New Parts to the Diagram Model Train Control on Arduino

843

6

Published

Introduction: Let's Add a Few New Parts to the Diagram Model Train Control on Arduino

About: Hello. Main name is Steve. I'm designer and former engineer from Moscow.

To the release of this instruction, I rewrote the Android application ArduinoTrain BtControl Lite, but it works with to the same scheme. Only we need to add an additional power supply for 5 volts. Thus, we divide the circuit into two parts, one for starting locomotives (12 volts), and the second for Arduino and for the layout. In this example, each of the seven windows of the house on the layout is turned on and off separately, this is helped by a cheap and widely used module Arduino I2C LCD Backpack. Maybe you already have it with the LCD display.

I recommend using it, so as not to drag a lot of wires from the Arduino to the layout house. And also 8 such modules can be connected together, and this is already 64 separately controlled channels LED lamps (more details here). And using Arduino code you can do anything with lighting. Create even the NY illumination managed from your phone :). And at the same time drive trains!

Step 1: Introduce I2C Bus

We need a small breadboard to place it together with LED lamps inside the house. And also the chip ULN2003, seven 150Ω resistors and seven LEDs (LEDs can be much many, just connect them in parallel). Since by default the bus address of the I2C LCD of the 0x27 and the clear pins on the finished module is seven (actually 8th), we can control them using the library Wire.
Now it is enough just to link this with the breadboard Arduino on four wires.

Step 2: Sketch

Lighting adds a realism to the model railway layout. But simple light bulbs are boring, it is better if every window will lighting individually with delay. Or added random effects. Change the sketch as you need!

// http://arduinorailwaycontrol.com/
// CommandStationPlusWire.ino
// 15.11.2017
// Author: Steve Massikker

#include 

//// GPIO PINS ////

// L298
#define ENA_PIN 3
#define IN1_PIN 2
#define IN2_PIN 4

//// VARIABLES ////
boolean stringComplete = false;
String inputString = "";
static uint8_t PCF8574;
byte dataToI2C;


void setup() {     
  
  // Initialize Serial
  Serial.begin(9600);
  inputString.reserve(16);

  // Initialize I2C
  Wire.begin();  
  
  // Initialize Motor Driver
  pinMode(ENA_PIN, OUTPUT);
  pinMode(IN1_PIN, OUTPUT);
  pinMode(IN2_PIN, OUTPUT);

  // PCF8574 lighting channels
  //             7654X210   
     PCF8574 = 0b00000000;
}

void loop() {

  if (stringComplete) {

    // ----------- START COMMAND PARSING ----------- //
    
    //THROTTLE
    
    if (inputString.charAt(0) =='t') {
      if (inputString.charAt(1) =='0') {
        analogWrite(ENA_PIN, 0);
      }
      if (inputString.charAt(1) =='1') {
        analogWrite(ENA_PIN, 80);
      }
      if (inputString.charAt(1) =='2') {
        analogWrite(ENA_PIN, 100);
      }
      if (inputString.charAt(1) =='3') {
        analogWrite(ENA_PIN, 150);
      }
      if (inputString.charAt(1) =='4') {
        analogWrite(ENA_PIN, 200);
      }
      if (inputString.charAt(1) =='5') {
        analogWrite(ENA_PIN, 255);
      }
    }

    // DIRECTION

    if (inputString.charAt(0) =='d') {
      if (inputString.charAt(1) =='r') {
        digitalWrite(IN1_PIN, HIGH);
        digitalWrite(IN2_PIN, LOW);
      }
      if (inputString.charAt(1) =='f') {
        digitalWrite(IN1_PIN, LOW);
        digitalWrite(IN2_PIN, HIGH);
      }
      if (inputString.charAt(1) =='s') {
        digitalWrite(IN1_PIN, LOW);
        digitalWrite(IN2_PIN, LOW);
        analogWrite(ENA_PIN, 0);
      }
    }

    //I2C

    if (inputString.charAt(0) =='l') { // Yellow channel
      if (inputString.charAt(1) =='a') {
        dataToI2C = bitSet(PCF8574, 0);
        sendDataViaI2C();
        delay(200);
        dataToI2C = bitSet(PCF8574, 1);
        sendDataViaI2C();
        delay(200);  
        dataToI2C = bitSet(PCF8574, 2);
        sendDataViaI2C();
      }
      if (inputString.charAt(1) =='b') {
        bitClear(PCF8574, 0);
        bitClear(PCF8574, 1);        
        dataToI2C = PCF8574;
        sendDataViaI2C();
        delay(120);
        dataToI2C = bitClear(PCF8574, 2); 
        sendDataViaI2C();                 
      }
    }

    if (inputString.charAt(0) =='g') { // Blue channel
      if (inputString.charAt(1) =='a') {
        dataToI2C = bitSet(PCF8574, 4);
        sendDataViaI2C();
        delay(200);
        dataToI2C = bitSet(PCF8574, 5);
        sendDataViaI2C();
        delay(200);  
        bitSet(PCF8574, 6);
        bitSet(PCF8574, 7); 
        dataToI2C = PCF8574;
        sendDataViaI2C();
      }
      if (inputString.charAt(1) =='b') {
        PCF8574 = 0b00000000;
        dataToI2C = 0;
        sendDataViaI2C();
      }
    }    

// ----------- END COMMAND PARSING ----------- //

inputString = "";
stringComplete = false;

  }
}

// ----------- FUNCTIONS ----------- //

void serialEvent() {
  while (Serial.available() ) {
    char inChar = (char)Serial.read();
    inputString += inChar;
      if (inChar == 'z') {
      stringComplete = true;
    }
  }
}

void sendDataViaI2C() {
  Wire.beginTransmission(39);
  Wire.write(dataToI2C);
  Wire.endTransmission();
}

Step 3: Application

The application has two buttons - a blue channel and a yellow channel. You can also apply this solution to railway signals, but there are better ways. Also on my site you can see how to connect servos to junctions.

Share

    Recommendations

    • Colors of the Rainbow Contest

      Colors of the Rainbow Contest
    • Woodworking Contest

      Woodworking Contest
    • Planter Challenge

      Planter Challenge
    user

    We have a be nice policy.
    Please be positive and constructive.

    Tips

    Questions

    Comments