Grade Crossing

This project uses a Launchpad to drive relays that operate the globe based crossing signals for a double track main with individual track current sensors and the need to sense any equipment that does not draw current that is over the crossing.

 

Grade Crossing

 

 

In this project a LaunchPad, powered from the 5V regulated power supply, will control the 3 12V Relays by monitoring the state of the switched outputs (J4) of two DCC Specialties Block Watchers providing track occupancy coupled with IR detection across the double track crossing operates the two sets of crossing lights and a sound module until a predetermined time is reached after all inputs are restored to an inactive state.  The crossing should operate if Track1 occupied, Track 2 occupied or the IR sensor is active.

 

Bill of Materials:

  1. 1 x LaunchPad with MSP430G2553IN20 processor.
  2. 1 x 4 way relay board ( this link ).
  3. 2 x switched output e.g. (J4) DCC Specialties Block Watcher ( link ) .
  4. 1 x 3mm Infrared phototransistor  ( link ).
  5. 1 x 3mm Infrared diode  ( link ).
  6. 1 x 150Ω ¼W resistor.
  7. 2 x Optocoupler  ( link )
  8. 1 x Innovative Train Technology Products HQ300-1 Grade Bell ( link )
  9. 1 x Innovative Train Technology Products  4″ – 8Ω Speaker SPKR4 ( link )
  10. 1 x Power supply (see below)

Notes:

  1. remember to include a resistor to limit the current in the block watcher circuit to protect the LED embedded in the optocoupler.
  2. ( links ) were valid at the time of publication.

 

Power supply bill of materials:

  1. 8 x 1N4001 Diodes.
  2. 1 x LM7812CT 12 Volt Regulator
  3. 1 x LM7805CT 5 Volt Regulator.
  4. 1 x 1000µf 50V.
  5. 2 x 10µf 50V.

 

IR sensors mounted in PVC tubes (painted black)

Scenery added (white glue applied)

 

Theory of Operation:

The Power on LED is connected to pin P1.0 and illuminates when the LaunchPad is running the program.

The switched output of each Block Watcher (J4) is connected to the LaunchPad via an optocoupler switching VCC to pins [Board (IC)] P2.0 & P2.1.  When a train is detected by a Block Watcher and its switch (J4) is closed the optocouplers operates and causes their respective pins to go “high” and the software in the LaunchPad causes relays 2 & 3 to turn on and relay 1 to cycle off and on for a predetermined time.  Similarly if the IR sensor goes “high” it has the same result.

This is achieved by monitoring 3 inputs: Block Watcher 1 – P2.0; Block Watcher 2 – P2.1; IR sensor – P2.2. If any or all of the inputs go high: set Inputs_Active (flag) to 1 and cycle light sequence 5 times with the sound module activated.  This is achieved by: setting P1.6 to ON (Light power); setting P1.7 to ON (Sound power); and cycling P1.5 ON & OFF 5 times.  If any input (P2.0, P2.1 or P2.2) remains high then the sequence is repeated.

 

Circuit Diagram:

While the diagram looks complicated, hookup is actually reasonably simple using wire wrap techniques.  It is good practice to solder wire wrapped joints for long term reliability once testing is complete.


Demonstration of the Prototype

Link to Video of prototype operation.

Link to Video of testing before installation

 

Demonstration of the Installation

Link to Video of IR operation.

Link to Video of Block & IR operation.

 

The Code

The code can be found here.

The code listing follows below.

 

/*

* Grade Crossing 1.0

* COPYRIGHT © 2013 Jim Gifford

* http://halletcovesouthern.blogspot.com.au

* Provided under a Creative Commons Attribution, Non-Commercial Share Alike,3.0 Unported License

*

* I wish to acknowledge code snippets initially written by:

* “Steve Hoffy Hofmeister” & “Terry Terrance”

*

* TARGETED TO MSP430 LANUCHPAD W/MSP430G2553N20 PROCESSOR

*

* Design Notes:

*

* This code is designed to receive an input from either of 2 DCC Specialties Block Watchers and a IR LED/Phototransistor Sensor pair that turns on the power to light Crossing lights via a relays, turn on a sound module and hold them on for a predefined period of time (currently set to about 3 seconds) after detection ceases.

*

*I have built my own power supply board that utilises one of my 18V 4 Amp AC accessory power circuits and outputs 12V & 5V regulated DC.  I drive the lamps from the 12V through four diodes to drop the voltage to just under 10V. I have connected the MSP430 to the 5V regulated supply.

*

*

* Circuit Pinout:

* PIN 1.0 = Circuit Power Indicator

* PIN 1.1 = UNASSIGNED – UART

* PIN 1.2 = UNASSIGNED – UART

* PIN 1.3 = UNASSIGNED

* PIN 1.4 = UNASSIGNED

* PIN 1.5 = Relay 1 Trigger

* PIN 1.6 = Relay 2 Trigger

* PIN 1.7 = Relay 3 Trigger

* PIN 2.0 = Input for Block Watcher 1

* PIN 2.1 = Input for Block Watcher 2

* PIN 2.2 = Input for IR sensor

* PIN 2.3 = UNASSIGNED

* PIN 2.4 = UNASSIGNED

* PIN 2.5 = UNASSIGNED

* PINS 1.1, 1.2, 1.3, 1.4, 2.3, 2.4 & 2.5 are left unused for integration into other projects.

* Note Anodes for the IR Emitter connect to VCC and Cathode to Ground

*/

#include <msp430g2553.h>

/////////////////////////////////////////////

//  Define variables

////////////////////////////////////////////

volatile unsigned long Relay_1_Timer = 30000;  //Define time for outputs to stay on

volatile int Active = 0;

volatile int Inputs_Active = 0;

volatile unsigned long Counter = 0;

// delay macros

#define DELAY_FLASHER(delay) doDelayFlasher(delay)

// routine definitions

void doDelayFlasher(unsigned long delay);

void main(void) {

WDTCTL = WDTPW + WDTHOLD;        // Stop watchdog timer

P2OUT = 0;                                            // Set All P2 to Off

//Configure Outputs

P1DIR |= BIT5;                                     // Port P1.5 (Relay 1 Trigger) as output

P1OUT &= ~BIT5;                                 // Port P1.5 (Relay 1 Trigger) Set to off State

P1DIR |= BIT6;                                     // Port P1.6 (Relay 2 Trigger) as output

P1OUT &= ~BIT6;                                 // Port P1.6 (Relay 2 Trigger) Set to off State

P1DIR |= BIT7;                                     // Port P1.7 (Relay 3 Trigger) as output

P1OUT &= ~BIT7;                                // Port P1.7 (Relay 3 Trigger) Set to off State

// Configure Inputs

P2DIR &= ~BIT0;                                  // sets Port 1, bit 7 to input from Blockwatcher

P2OUT &= ~BIT0;                                // sets pull-up resistor on Port 1, bit 7 to pull-up

P2REN |= BIT0;                                    // pull up bit0

P2DIR &= ~BIT1;                                  // sets Port 1, bit 7 to input from Blockwatcher

P2OUT &= ~BIT1;                                 // sets pull-up resistor on Port 1, bit 7 to pull-up

P2REN |= BIT1;                                    // pull up bit1

P2REN |= BIT2;                                    // Port 2 Resistor enable

P2OUT |= BIT2;                                    // pull up bit2

// Show Launchpad Active

P1DIR |=  BIT0;                                  //  Circuit Power Indicator

P1OUT |=  BIT0;                                  //  sets Port 1, bit 0 to on – use onboard LED

// Let’s Get Down to Business

while( 1 )                                               // begin infinite loop

{

// Do while any of 3 inputs are active

//              1              Block Watcher 1 (J4 closes & goes high) P2.0

//              2              Block Watcher 2 (J4 closes & goes high) P2.1

//              3              IR sensor detection active (goes high)   P2.2

// & if so activate the crossing signals

if ( ((P2IN&BIT0) == 0) && ((P2IN&BIT1) == 0) && ((P2IN&BIT2) == 0) )                // No inputs active

{

// Set to Relays to off

P1OUT &= ~BIT5;   // Port P1.5 (Relay 1 Trigger) Set to off State

P1OUT &= ~BIT6;   // Port P1.6 (Relay 2 Trigger) Set to off State

P1OUT &= ~BIT7;   // Port P1.7 (Relay 3 Trigger) Set to off State

}

else                                         // At least 1 input active

{

Inputs_Active = 1;

while (Inputs_Active < 6)  // Go through 5 cycles

{

// Start crossing working

P1OUT |= BIT6;                                       // Set Relay 2 Trigger to ON – Light power

P1OUT |= BIT7;                                       // Set Relay 3 Trigger to ON – Sound power

DELAY_FLASHER(Relay_1_Timer);     // Let lights 1 stay on for value of Relay_1_Timer

P1OUT |= BIT5;                                       // Set Relay 1 Trigger to ON

DELAY_FLASHER(Relay_1_Timer);     // Let lights 2 stay on for value of Relay_1_Timer

P1OUT &= ~BIT5;                                   // Set Relay 1 Trigger to OFF

Inputs_Active ++;                                    // Index the counter

}               // End of input detected While

}               // End of Input(s) active if

}  // End of While (while( 1 ))

}  // END OF MAIN

// Function Delay_Flasher

void doDelayFlasher (unsigned long x)

{

Counter = 0;

while (Counter < x)

{

Counter ++;             // Index the counter

}

}