KevinMcArthur
Published © GPL3+

Model Railroad Grade Crossing Controller

Arduino and easy to use photo occupancy sensors simplify control of the grade crossing signals and sound effects on a model railroad.

BeginnerWork in progress7,197
Model Railroad Grade Crossing Controller

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
RAM Track 111 or 117 Dual Optical Detector PCB
×1
LED Flasher PCB
×1
Sound Replay PCB
×1
DFRobot 4 Relay Shield
×1
9 volt Power Supply
×1
Screw Terminal Shield
×1

Story

Read more

Schematics

Model Railroad Grade Crossing Controller

Model Railroad Grade-crossing Controller

Code

Capreol Museum Rail / Road Crossing Controller

Arduino
// set pin numbers:
const int buttonAPin = A1;     // the number of the pushbutton pins
const int buttonBPin = A2;
 
const int ledPin =  13;      // the number of the LED pin
const int RelayA = 2;     // the number of the relay coil drive pin
const int RelayB = 3;
const int RelayC = 11;
 
// Define Variables
int buttonAState = HIGH;
int lastButtonAState = HIGH;

int RUNNING  = LOW;
int OCCUPIED = LOW;

int buttonBState=HIGH;
int lastButtonBState = HIGH;


// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.

unsigned long lastDebounceTimeA = 0;
unsigned long lastDebounceTimeB = 0;

unsigned long debounceDelay = 50;
unsigned long loopdelayA = 500;
unsigned long looptriggerA;
unsigned long loopdelayB = 500;
unsigned long looptriggerB;
unsigned long RUNNINGtime = 3000;
unsigned long RUNNINGtrigger;

#include <LiquidCrystal.h>

// Select the pin used on LCD
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() { 

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("KEVino 2017");
  lcd.setCursor(0, 1);
  lcd.print("RAILCROSS");
  delay(1000);
  // scroll 16 positions (string length) to the left
  // to move it offscreen left:
  for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
    // scroll one position left:
    lcd.scrollDisplayRight();
    // wait a bit:
    delay(30);
  }
  {
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Railcross");
  }  
  Serial.begin(9600);
 
  pinMode(ledPin, OUTPUT);
  pinMode(RelayA, OUTPUT);
  pinMode(buttonAPin, INPUT_PULLUP);
  pinMode(RelayB, OUTPUT);
  pinMode(buttonBPin, INPUT_PULLUP);
  pinMode(RelayC, OUTPUT);
 
}

void debounceA()                         
{
  int readingA = digitalRead(buttonAPin);

  if (readingA != lastButtonAState)
  {
    lastDebounceTimeA = millis();
    looptriggerA = millis();
  }
  if ((millis() - lastDebounceTimeA) > debounceDelay)
  {
    if (readingA != buttonAState)
    {
      buttonAState = readingA;
    }
  }
  lastButtonAState = readingA;
  lastDebounceTimeA = 0;
  return;
}

void debounceB()                        // Debounce A2 input
{
  int readingB = digitalRead(buttonBPin);

  if (readingB != lastButtonBState)
  {
    lastDebounceTimeB = millis();
    looptriggerB = millis();
  }
  if ((millis() - lastDebounceTimeB) > debounceDelay)
  {
    if (readingB != buttonBState)
    {
      buttonBState = readingB;
    }
  }
  lastButtonBState = readingB;
  lastDebounceTimeB = 0;
  return;
}

void START()                      // 1/2 second pulse on Relay A,
{                                 // RUNNING set HIGH,, Relay C set.
  RUNNINGtrigger = millis();
  digitalWrite(RelayA, HIGH);
  digitalWrite(RelayC, HIGH);
  delay (500);
  digitalWrite(RelayA, LOW);
  RUNNING = HIGH;
}
void STOP()                       // 1/2 second pulse on Relay B,
{                                 // RUNNING set LOW,, Relay C cleared.
  RUNNINGtrigger = millis();
  digitalWrite(RelayB, HIGH);
  digitalWrite(RelayC, LOW);
  delay (500);
  digitalWrite(RelayB, LOW);
  RUNNING = LOW;

}

void loop()
{
  lcd.setCursor(13, 0);                            // Display seconds elapsed
  lcd.print(millis() / 1000);
 
   
  debounceA();                                     //Debounce the sensor inputs
  debounceB();                
  digitalWrite(ledPin, OCCUPIED);                  // Use LED to indicate OCCUPIED
  
  if (buttonAState == LOW || buttonBState == LOW) 
  {
    OCCUPIED = HIGH;
    RUNNINGtrigger = millis();     
    Serial.write("OCCUPIED");
    Serial.println();
     lcd.setCursor(0, 1);
     lcd.print("Occupied");  
  }
  else
  {
    OCCUPIED = LOW;
    lcd.setCursor(0, 1);
    lcd.print("        ");  
  }

  if (OCCUPIED == HIGH && RUNNING == LOW)
  {
    START();
    Serial.write("START");
    Serial.println();
      lcd.setCursor(8, 1);
      lcd.print("RUNNING"); 
  }

  if (RUNNING == HIGH)
    if ((millis() - RUNNINGtrigger) > RUNNINGtime)
    {
      STOP();
      Serial.write("STOP");
      Serial.println(); 
      lcd.setCursor(8, 1);
      lcd.print("       "); 
    }

}

Credits

KevinMcArthur

KevinMcArthur

3 projects • 11 followers

Comments