Automated Railroad Crossing
Last Modified: 2006-12-15
find:

basket

Acroname Robotics PDF webpage version Automated Railroad Crossing PDF

Related
Products

Product image for Brainstem GP 1.0 Module
Brainstem GP 1.0 Module
Product image for Standard Servo
Standard Servo
Product image for Sharp GP2D120 IR Sensor
Sharp GP2D120 IR Sensor
Product image for Sharp IS471F IR Detector Pkg
Sharp IS471F IR Detector Pkg

Contents

Overview

This tutorial goes through the process of designing an automated model railroad crossing. 

In real life, when a train is approaching a traffic crossing, warning lights flash to warn drivers that a train is coming and a crossing gate lowers to block traffic.  How would you implement an automated model railroad crossing using the BrainStem?

Sensors

The first task is to find some way to detect a train.  An ideal sensor would require no modification to any train cars and be small enough to fit easily in a scale model scene.  The Sharp GP2D120 is a good choice.  It is a short range infrared proximity sensor.  Its output voltage is proportional to the distance between it and an object directly in front of it.  It works well in a variety of lighting conditions and has a package that is small enough to fit in a structure in a model railroad scene.  When pointing sideways, it can detect passing trains. 

Getting the best results with the sensor will require some adjustment.  It works best to mount the sensor horizontally about 1/2 inch above the plane of the railroad track.  If the sensor is mounted too high it may not detect flat railroad cars.  The sensor should stare across the railroad track.  Although the sensor has a very narrow beam width, it may still detect the railroad track itself.  Tilting the sensor up at a slight angle can prevent this.  The sensor may also interpret the gaps between cars as the absence of a train.  Mounting the sensor so that it points across the track at an angle will give more consistent results. 

Visual Outputs

The next step is implementing flashing lights.  Hobby and model train shops sell scale replicas of railroad crossing lights.  The lights are usually small high-efficiency red LEDs.  A digital output on a Stem can drive one LED or several at once with an appropriate series resistor.  Sometimes model railroad scenery may use small incandescent bulbs.  Since they use more current than an LED, a transistor may be required to switch them on and off. 

The diagram below shows the LED driver circuit for the prototype.  It works well when turning on one LED at a time.  The single resistor will limit the current to both LEDs which will make each LED dimmer if both are turned on.  If a display has several LEDs that may be on or off, each LED will need its own series resistor to produce constant brightness. 

Circuit schematic for wiring LEDs up to a BrainStem GP digital pin.

Source Code - TEA Program to Flash LEDs

The following program alternately blinks LEDs connected to digital outputs 0 and 1.  Instead of simply blinking the lights all the time when the program is running, the program checks a scratch pad value to determine when to flash the lights.  Writing a value of 1 to scratch pad byte 1 will enable the flashing lights.  Writing a value of 0 to scratch pad byte 1 will turn the lights off.  This is useful for testing, but also provides a means for another TEA program to control the blinking lights.  This will come in handy later. 

/* file: rrlights.tea */ #include <aCore.tea> #include <aDig.tea> #include <aPad.tea> #define LIGHTA 0 #define LIGHTB 1 #define LIGHTCTRL 1 #define FLASHRATE 2500 void main() { aDig_Config(LIGHTA,ADIG_OUTPUT); aDig_Config(LIGHTB,ADIG_OUTPUT); while (1) { if (aPad_ReadChar(LIGHTCTRL)==1) { aDig_Write(LIGHTA,1); aDig_Write(LIGHTB,0); aCore_Sleep(FLASHRATE); aDig_Write(LIGHTA,0); aDig_Write(LIGHTB,1); aCore_Sleep(FLASHRATE); } else { aDig_Write(LIGHTA,0); aDig_Write(LIGHTB,0); } } }

The program uses defined constants for the flash rate and digital IO pin IDs.  This is good programming practice.  It enables a user to change a value in one location instead of trying to find a value and replace it throughout an entire program. 

Download that file and save it to the "aUser" subdirectory in the brainstem folder.  Run the Console and enter the following commands to steep the program, load it into file slot 1, and launch the program on the BrainStem. 

steep "rrlights" load "rrlights" 2 1 launch 2 1

The lights should not blink.  Change scratch pad byte 1 to a value of 1 with the following cmdPAD_IO command and the lights should begin blinking:

2 51 1 1

Change scratch pad byte 1 to a value of 0 with the this cmdPAD_IO command and the lights should stop blinking:

2 51 1 0

With the blinking light program completed, the next step is to add some means of controlling the gates.  A standard RC hobby servo such as the SN03 Standard Servo is ideal.  The BrainStem has 4 hardware-driven servo control outputs with 8-bit (0-255) positioning resolution.  Each servo output has its own limit settings for starting position and range of travel.  Each servo also has a configuration setting that can turn the servo output on or off, invert the motion, or set the servo speed.  The servo speed feature can slow down the servo motion to add extra realism. 

In a railroad scene, the servo might be mounted under the surface of the display and move a tiny linkage rod or wire to raise and lower the crossing gate.  In this example, a Popsicle stick mounted directly on a servo acts as a substitute for a model crossing gate.  To make the speed as slow and smooth as possible, the gate servo is configured so that a position of 0 is fully down and a position of 255 is fully up.  The servo settings may be adjusted and saved with the GP program.  Once they are set, a TEA program can move the servo with an aServo_SetAbsolute command. 

Source Code - TEA Program for Creating Control Logic

The next task is to figure out the control logic for the sensors, gate, and flashing lights.  For this example, the logic is quite simple.  The gate must lower and the lights must blink when a train is approaching.  After the train leaves, the gate must rise and the lights should stop blinking. 

The control logic can be implemented with an endless "while" loop that checks the train sensor.  When the train is detected, a subroutine will lower the gate and turn on the lights.  Then a second "while" loop within the first loop will run until the train has passed.  Once the train has passed, a subroutine will raise the gate and turn off the lights.  Then the process repeats. 

The blinking light routine listed above and the control program listed below will run as a separate processes.  They will work together to implement the gate control, lights, and logic.  It is possible to do everything with one program, but the code to keep the lights blinking at a fixed rate while simultaneously checking the status of the train sensor would be much more complicated.  With a separate process for the blinking lights, all the control program has to do to flash the lights is write to the scratch pad. 

/* file: rrlogic.tea */ #include <aCore.tea> #include <aPrint.tea> #include <aServo.tea> #include <aA2D.tea> #include <aPad.tea> #define TRAINSENSOR 0 #define TRAINLIMMAX 300 #define TRAINLIMMIN 140 #define GATEDELAY 50000 #define GATESERVO 0 #define LIGHTCTRL 1 int train() { int r=0; int val=0; r=r+aA2D_ReadInt(TRAINSENSOR); r=r+aA2D_ReadInt(TRAINSENSOR); r=r+aA2D_ReadInt(TRAINSENSOR); r=r/3; if (r>TRAINLIMMIN && r<TRAINLIMMAX) val=1; return val; } void lowergate() { aPad_WriteChar(LIGHTCTRL,1); aServo_SetAbsolute(GATESERVO,(unsigned char)0); aCore_Sleep((unsigned int)GATEDELAY); } void raisegate() { aServo_SetAbsolute(GATESERVO,(unsigned char)255); aCore_Sleep((unsigned int)GATEDELAY); aPad_WriteChar(LIGHTCTRL,0); } void test() { int r; while (1) { r=aA2D_ReadInt(TRAINSENSOR); aPrint_IntDec(r); aPrint_Char('\n'); aCore_Sleep(2000); } } void main(void) { int r=0; //test(); raisegate(); while (1) { if (train()) { lowergate(); while (train()) {} raisegate(); } } }

The train() function takes an A2D reading from analog input 0 and checks if it falls within a specified range.  The sensor readings can have some jitter so the the routine takes an average of 3 samples to filter out some noise.  Since the GP2D120 output voltage is proportional to distance, the range at which it detects a train may be adjusted.  This can prevent the sensor from detecting objects beyond the tracks.  If the reading is within the desired range, the function returns a 1, otherwise it returns a 0.  This is a "boolean" function.  It can be used as the condition in a "while" or "if" statement. 

The lowergate() routine starts the lights flashing and issues a command to make servo 0 lower the gate.  When using speed-controlled servo motion, a delay is required to give the gate enough time to lower completely.  The raisegate() routine issues a command to make servo 0 lift the gate, waits for the gate to rise completely, then turns off the flashing lights. 

The test() routine prints out the reading from the train sensor to the Console.  It can be used to check the sensor readings in order to test the alignment of the sensor and determine limits for the train() function.  For normal operation, the line that calls the test routine can be commented out. 

Download that file and save it to the "aUser" subdirectory in the brainstem folder.  Run the Console and enter the following commands to steep the program, load it into file slot 0. 

steep "rrlogic" load "rrlogic" 2 0

Physical Prototype

A prototype of the crossing system is shown below.  A GP2D120 is connected to analog input 0, the gate (servo with Popsicle stick) is connected to servo 0, and the flashing lights are connected to digital IO pins 0 and 1.  The gate, lights, and sensor are temporarily mounted with poster putty.  A section of HO scale track with two train cars gives a better idea of what a complete railroad crossing might look like. 

Physical setup of the model train, railroad, gate, sensors and flashing lights.
HO Scale Model Railroad Crossing

The circuitry is minimal.  The two LEDs require a single series resistor and the servo and sensor plug directly into the BrainStem.  In a large model railroad layout, the crossing may be far from the controller.  All these devices may be connected with fairly lengthy wiring if necessary.  The power supply for the prototype is a 6V battery.  The BrainStem can handle a wide range of supply voltages with 6V to 9V being typical.  However, the servo needs a 4.8V to 6V supply.  A standard 5-6V AC-to-DC wall adapter could power the whole project but the output voltage can vary.  When testing an adapter, make sure the voltage falls within the specified range for both the servos and BrainStem. 

Now that everything is in place, it's time to try it out.  The following commands launch the two TEA programs that control the crossing. 

launch 2 0 launch 2 1

The gate goes up and the sensor looks for a train.  An object in the detection range of the sensor will make the gate go down and the lights flash.  When the object is gone, the gate will go back up and the lights will stop flashing. 

The last step is to configure the BrainStem to run the control programs when it is powered-up.  This may be accomplished by using some cmdVAL_SET and cmdVAL_SAV commands.  Enter the following commands at the Console prompt:

2 18 15 0 2 18 16 1 2 19

The first two commands tell the BrainStem to run programs 0 and 1 the next time the BrainStem is turned on.  The final command saves this data to the EEPROM so it will not be lost when the Stem is turned off. 

Alternative Approaches

There are many possibilities with this type of project.  Other sensors may be used to detect a train.  A short-range reflective IR sensor such as the Sharp IS471F may be mounted under the tracks to detect a train moving overhead.  The control program could check a second sensor farther down the tracks to make sure the train has passed completely through the crossing.  If the crossing has trains going in both directions, the control program could use two sensors to detect trains approaching from either direction.  Instead of using a second TEA program to control the lights, a reflex could be used instead. 

Going Further

This tutorial demonstrated a simple model railroad crossing.  Similar approaches could be used to automate several portions of a model train layout.  Some possibilities include street lights that come on when the room gets dark enough, traffic lights, an amusement park with functioning rides, manufacturing plants, drawbridges, etc. 

Revision History:

  • 2002-08-22: Tutorial Created

BrainStem
Resources

 

Related Links:

BrainStem Overvew and Features

voice: 720-564-0373, email: sales@acroname.com, address: 4822 Sterling Dr., Boulder CO, 80301-2350, privacy
© Copyright 1994-2008 Acroname, Inc., Boulder, Colorado. All rights reserved.