Introduction: Railroad Crossing and Lap Counter

This code is intended for miniature train sets and reflects a very basic usage of real-world coding. The purpose of this microcontroller is to monitor a railroad crossing for an oncoming train. When a train arrives, the microcontroller will close the railroad crossing gates, flash some LED's, play a sound, and increase the lap counter. This guide will explain how to build it and provide the necessary code.

Required Materials:

· Raspberry Pi

· MATLAB

· Assortment of Wires

· LED’s

· IR Receiver/Emitter

· Resistors

· Servo Motor

Step 1: Prepare MATLAB

The Raspberry Pi support package is needed for the code to run on MATLAB. To get the support package you will need to open MATLAB. With MATLAB open, make sure you are on the HOME tab. Then click on Add-Ons. Once the new window is open (it may take a while), click on the search bar and search for MATLAB Support Package for Raspberry Pi Hardware. Click on the package and click on install (install will show up in the top right corner where the screenshot says Manage.) Once you do that follow the installation steps.

Step 2: Build Breadboard

Build the Breadboard as shown in the picture above. Refer to the key and its respective wiring diagram to build each circuit.

The wiring looks intimidating, but it is not that bad. It is just seven circuits working in conjunction. The circuits that need to be built are shown below in wiring diagrams. The GPIO ports you use DO NOT have to be the exact same as the ones we used. If you decide to change the ports, make sure you change the code in the respective areas.

Step 2a: Wire three IR receivers against the railroad track on breadboards. These receivers do not have to be right next to each other as shown in the photo above, they only need to have a clear view of their respective emitters. A key for the symbols used in the wiring diagrams is given above. Three GPIO ports will need to be chosen for the receivers to interface with. The ports listed are the ones we used. The receivers are RED and the emitters are YELLOW.

Step 2b: Wire the emitters. The emitters need to be directly across from the receivers. If there is a misalignment, some receivers may pick up mixed signals or not sense the IR beam at all. The emitters do not have to be within the same circuits. If needed you can split this circuit up into 3 different circuits and place them along farther stretches of track.

Step 2c: Wire two different LED circuits each interfacing with a different GPIO port. These serve as the rail lights that come on when the train passes by.

Step 2d: Lastly the servo motor that closes and opens the gate. This is an output of the IR receivers and will close when a train passes by and open after the train leaves. The motor has a third input for a separate power wire as the servo motor is an analog device. Running out of the servo motor will be three wires, a five-volt power wire, a GPIO wire, and a ground wire. Place the servo motor so that the gate is parallel with the track.

Once you have wired up everything according to the wiring diagrams make sure that there is nothing obstructing the space between the IR emitters and receives. Do not forget to place resistors where needed, to decode the resistor bands search google for a band color sheet.

Step 3: Coding

Once the Breadboard is built in a similar fashion to what is pictured above, copy the code below into MATLAB. Change the GPIO Ports as needed. To change the GPIO ports you will have to change the numbers in the code that correspond to configuring pins (lines that have the command configurePin). Whenever you begin using the code after restarting MATLAB this command must be put into the command window. This must be done every time you disconnect and reconnect the Raspberry Pi.

mypi=raspi(‘169.254.0.2’,’pi’,’raspberry’)

After running the initialization code, copy and paste the code below into MATLAB.

configurePin(mypi,12,'DigitalOutput') %sets the first LED pin, pin 12, as an output

configurePin(mypi,16,'DigitalOutput') %sets the second LED pin, pin 16, as an output

configurePin(mypi,19,'DigitalInput') %sets the first IR pin, pin 19, as an input

configurePin(mypi,13,'DigitalInput') %sets the second IR pin, pin 13, as an input

configurePin(mypi, 25, 'DigitalInput'); %sets the button pin, pin 25, as an input

i = 0; % sets an initial lap count of 0

while true %creates an unbroken loop for the code to run in

IRBeamBroken = readDigitalPin(mypi,19) %reads the signal coming from the IR pin, 19

if IRBeamBroken == 1

writeDigitalPin(mypi,12,0) %Keeps LED shut off when IR beam is connected

writePosition(s,176) % Keeps Gate open

elseif IRBeamBroken == 0

IRBeam2Broken = readDigitalPin(mypi,13) %Reads the signal from the 2nd set of IR's pin, 13

while IRBeam2Broken == 1

writePosition(s,8) % closes gate

filename = 'RR_Bell.wav'; % assigns a sound to the variable 'filename'

[y,Fs] =audioread(filename); % reads the sound in order for matlab to use it

sound(y*.5,Fs) % plays the sound

filename2 = 'train_whistle.wav'; % assigns a sound to the variable 'filename2'

[y,Fs] =audioread(filename2); % reads said sound in order for matlab to use it

sound(y*.37,Fs) % plays the sound

writeDigitalPin(mypi,12,1) % turns on LED 1

writeDigitalPin(mypi,16,0) % keeps LED 2 off

pause(0.5) % waits 0.5 seconds

writeDigitalPin(mypi,12,0) %turns off LED 1

writeDigitalPin(mypi,16,1) % turns on LED 2

pause(0.01) % waits 0.01 seconds

IRBeam2Broken = readDigitalPin(mypi,13) %reads signal from the 2nd set of IR's pin, 13

if IRBeam2Broken == 0

writeDigitalPin(mypi,16,0) %shuts off LED 2

clear sound % stops playing the sounds

break %stops the eternal 'while loop' and resets it for the next pass through the IR system

end % ends the 'if IRBeam2Broken == 1' statement

end % ends the 'while IRBeam2Broken == 0' loop

end %ends the 'if IRBeamBroken == 1' statement

LapCounter = readDigitalPin(mypi,25); % reads the IR pin 25

if LapCounter == 1

i = i; %stores the laps counted as i

if i == 0

axes('Color','none','XColor','none','YColor','none') % Clears the plot window of the axes and chart

y=0.5; % sets the y-position of the text in the plotting window

x=0.36; % sets the x-position of the text in the plotting window

title('Lap Number:','fontsize',32) % Adds a title to the plotting window

quadeqtxt = '0'; % Sets the variable 'quadeqtxt' to output 0

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120); % displays the quadeq text in the plotting window

end %ends the 'if i == 0' statement

elseif LapCounter == 0

pause(5) % stops the code from running for 5 seconds so the train can pass and it only counts one pass instead of multiple

i = i+1; % adds a lap to the variable 'i' counting a lap

% The following 21 if statements are coded the same way as the 'if i == 0' if statement above, the only difference being the number displayed

if i == 1

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '1';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 2

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '2';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 3

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '3';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 4

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '4';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 5

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '5';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 6

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '6';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 7

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '7';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 8

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '8';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 9

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '9';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 10

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '10';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 11

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '11';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 12

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '12';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 13

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '13';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 14

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '14';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 15

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '15';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 16

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '16';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 17

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '17';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 18

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '18';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 19

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '19';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 20

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '20';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

elseif i == 21

close all

axes('Color','none','XColor','none','YColor','none')

y=0.5;

x=0.36;

title('Lap Number:','fontsize',32)

quadeqtxt = '21';

text(x,y,quadeqtxt,'interpreter','latex','fontsize',120);

end % ends the 'if i == 1' statement

end % ends the 'if LapCounter == 1' statement

end % ends the 'while true' loop

After copying this code and running it you should have a working railroad crossing, if the lights or gate are not functioning, look at the wiring first and make sure that you have the LED's and IR receivers connected to GPIO ports and not the power. Also make sure you have changed the code to the correct GPIO ports.