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

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

Picture of 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

Picture of 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.

Comments

About This Instructable

712views

4favorites

License:

Bio: Hello. Main name is Steve. I'm designer and former engineer from Moscow.
More by Steve Massikker:Let's Add a Few New Parts to the Diagram Model Train Control on ArduinoSensor for Railway Layout AutomationModel Train Control on Arduino
Add instructable to: