Introduction: Smart Train System

Designed to increase safety, prevent accidents, and increase positive and productive response to help if accidents do occur.

Step 1: Parts and Materials

The pictures above are placed in the order of the Parts List below:

Parts List

1) One Raspberry PI 3 - Model B

2) One Breadboard

3) Cables (from Top to Bottom) - One Power, One Ethernet, One Adapter

4) One Servo Motor

5) One 3D Printed Railroad Gate

6) Two LEDs (Preferably Red and Green)

7) One Push Button

8) Ten Jumper Wires

9) Four Resistors

10) Laptop or Desktop with MATLAB

Step 2: Configuration

Above are pictures of the configuring from multiple angles:

Pin locations(lower case letter followed by a row number) are listed below in order following the current flow.

Wires:

j19 to i47

j8 to b50

b5 to Servo

c6 to Servo

b7 to servo

a13 to j7

a17 to LED

LED to a37

e40 to j20

j53 to j18

j7 to LED

LED to j6

Button:

e54 to h51

Resistors:

d40 to b37

c50 to d54

i51 to j47

Step 3: Code and Logic

Our train system's goal is to increase safety and lower the risk of potentially deadly accidents at railroad crossings. In order to achieve this, our system has a train warning system for drivers, a physical barrier that is lowered to prevent cars from crossing the track, and a backup emergency button for the conductor to press if the early warning system fails.

GUI Conductor Operating System:

The GUI, shown above, was created for the use of the conductor as they are driving the train through areas of track that have car traffic railroad crossings.

In the upper right hand corner, there is a light that notifies the conductor if an upcoming railroad crossing gate is closed and allows the conductor to open or close the gate if needed. Below that, the feed from cameras the train passes is shown. In the bottom left corner, the location of the train is continuously plotted on a graph and below the graph, the number of laps the train had completed in a day is stated. Above the position graph, There is an emergency button and status statement. This allows the conductor to signal for an emergency if there is a car on the track or the safety gate is not working properly.

Code:

classdef micro < matlab.apps.AppBase
% Properties that correspond to app components

properties (Access = public)

UIFigure matlab.ui.Figure

RailwaygatestatusLampLabel matlab.ui.control.Label

gateLamp matlab.ui.control.Lamp

OpenGateButton matlab.ui.control.Button

CloseGateButton matlab.ui.control.Button

UIAxes matlab.ui.control.UIAxes

EmergencyButtonStatusLampLabel matlab.ui.control.Label

EmergencyButtonStatusLamp matlab.ui.control.Lamp

UndernormalconditionsLabel matlab.ui.control.Label

UIAxes2 matlab.ui.control.UIAxes

EF230Group6Label matlab.ui.control.Label

IanAllishKellyBondIanDaffronLabel matlab.ui.control.Label

LoopsCompletedLabel matlab.ui.control.Label

Label matlab.ui.control.Label

end

properties (Access = private)

counter int16

end

methods (Access = public)

function timerCallback(app, src, event)

app.Temp.Text = int2str(app.counter);

app.counter = app.counter + 1;

%call all the variables the program needs - - - - - - - - - - - - -

global rpi

global s

global open

global close

global cam

global m

global ems

global t_count

%------------------------- Train Arm Section ------------------------------

if open == 0

writePosition(s,50)

app.gateLamp.Color = 'green';

end

if close == 0

writePosition(s,120)

app.gateLamp.Color = 'red';

end

%---------------------- Motion Detection via Camera -----------------------

while true

img = snapshot(cam);

image(img);

app.UIAxes(drawnow)

end

%---------------------- Arm open/close -------------------------------------

if readDigitalPin(rpi,20)>1 %reads pin 17(button) and checks for signal

for i=40:.5:150 %raises bridge

writePosition(s,i)

end

for i= 1:10 %loops blinking red light x amount of times

writeDigitalPin(rpi,13,1)

pause(.5)

writeDigitalPin(rpi,13,0)

pause(.5)

end

writePosition(s,50)%put gate down

end

%-------------------- Mobile Phone Support/Plot --------------------------

m.AccelerationSensorEnabled=1

m.logging=1

data=zeros(200,1); %intialize data for rolling plot

figure(app.UIAxes2)

p=plot(data)

axis([xbounda,ybounds])

pause(1)

tic

while toc <30 %run for 30 seconds

[a,~]=accellog(m);

if length(a) >200

data=a(end-199:end,3);

else

data(1:length(a))=a(:,3);

end

%redraw plot

p.YData=data;

drawnow

end

%------------------ Sudden Pixel Change ----------------------------------

x1=img; % reads the camera off of the pi

red_mean = mean(mean(x1(:,:,1))); % reads the mean amount of red pixels

green_mean = mean(mean(x1(:,:,2))); % reads the mean amount of green pixels

blue_mean = mean(mean(x1(:,:,3))); % reads the mean amount of blue pixels

if red_mean > 150 && green_mean > 150 && blue_mean > 150

t_count = t_count + 1;

end

app.LoopsCompletedLabel.Text = num2str(t_count)

%------------------ Button EMS programming -------------------------------

configurePin(rpi, 12, 'DigitalOutput'); %sets the led pin, pin 16, as an output

configurePin(rpi, 16, 'DigitalInput'); %sets the button pin, pin 24, as an input

buttonPressed = readDigitalPin(rpi, 16); % Reads the button press value on pin 16

if buttonPressed == 1

while buttonPressed == 1

writeDigitalPin(rpi, 12, 1)

buttonunPressed = writeDigitalPin(rpi, 12,0); %

end % Ends ‘while buttonPressed==1’ loop

end

writeDigitalPin(rpi, 16, 0) %Sets the led to off when the button is no longer pressed setpref('Internet','SMTP_Server','smtp.gmail.com'); setpref('Internet','E_mail','ef230roomba2019@gmail.com'); % mail account to send from setpref('Internet','SMTP_Username','ef230roomba2019@gmail.com'); % senders username setpref('Internet','SMTP_Password','efgroup6'); % Senders password

props = java.lang.System.getProperties;

props.setProperty('mail.smtp.auth','true'); props.setProperty('mail.smtp.socketFactory.class','javax.net.ssl.SSLSocketFactory'); props.setProperty('mail.smtp.socketFactory.port','465');

sendmail('iallish@vols.utk.edu','Emergency Status!','The conductor has activated the manual override switch, requesting immediate response!')

app.UndernormalconditionsLabel.Text = ems

end

end

%app.Label_4.Text = num2str(curr_temp);

methods (Access = private)

% Code that executes after component creation

function startupFcn(app)

%----------All variables needed for this function--------------------

global rpi %arduino

rpi = raspi('169.254.0.2','pi','raspberry');

global s %servo

s = servo(rpi,17,'MinPulseDuration',5e-4,'MaxPulseDuration',2.5e-3);

global open

open = 1;

global closed

closed = 1;

global cam

cam = cameraboard(rpi);

global m

m=mobiledev;

global ems

ems = 'An emergency has been reported, notifying EMS';

global t_count

t_count = 0;

connector on %password is EFGroup6

% Timer Function for Loop --------------------------------

app.counter = 0;

t = timer( ...

'TimerFcn', @app.timerCallback, ...

'StartDelay', 1, ... 'Period', 1, ...

'ExecutionMode', 'fixedSpacing', ...

'TasksToExecute', inf);

start(t);

end

% Callback function

function ManualOverrideSwitchValueChanged(app, event)

end

% Button pushed function: OpenGateButton

function OpenGateButtonPushed(app, event)

global close

close = 0;

end

% Button pushed function: CloseGateButton

function CloseGateButtonPushed(app, event)

global open

open = 0;

end

end

% App initialization and construction

methods (Access = private)

% Create UIFigure and components

function createComponents(app)

% Create UIFigure

app.UIFigure = uifigure;

app.UIFigure.Position = [100 100 640 480];

app.UIFigure.Name = 'UI Figure';

% Create RailwaygatestatusLampLabel

app.RailwaygatestatusLampLabel = uilabel(app.UIFigure);

app.RailwaygatestatusLampLabel.HorizontalAlignment = 'right'; app.RailwaygatestatusLampLabel.Position = [464 422 110 22]; app.RailwaygatestatusLampLabel.Text = 'Railway gate status';

% Create gateLamp

app.gateLamp = uilamp(app.UIFigure);

app.gateLamp.Position = [589 422 20 20];

app.gateLamp.Color = [0.9412 0.9412 0.9412];

% Create OpenGateButton

app.OpenGateButton = uibutton(app.UIFigure, 'push');

app.OpenGateButton.ButtonPushedFcn = createCallbackFcn(app, @OpenGateButtonPushed, true); app.OpenGateButton.Position = [474 359 100 22];

app.OpenGateButton.Text = 'Open Gate';

% Create CloseGateButton

app.CloseGateButton = uibutton(app.UIFigure, 'push');

app.CloseGateButton.ButtonPushedFcn = createCallbackFcn(app, @CloseGateButtonPushed, true); app.CloseGateButton.Position = [474 285 100 22];

app.CloseGateButton.Text = 'Close Gate';

% Create UIAxes

app.UIAxes = uiaxes(app.UIFigure);

title(app.UIAxes, 'Camera Feed')

app.UIAxes.Position = [341 43 300 185];

% Create EmergencyButtonStatusLampLabel

app.EmergencyButtonStatusLampLabel = uilabel(app.UIFigure); app.EmergencyButtonStatusLampLabel.HorizontalAlignment = 'right'; app.EmergencyButtonStatusLampLabel.Position = [97 323 142 22]; app.EmergencyButtonStatusLampLabel.Text = 'Emergency Button Status';

% Create EmergencyButtonStatusLamp

app.EmergencyButtonStatusLamp = uilamp(app.UIFigure); app.EmergencyButtonStatusLamp.Position = [254 323 20 20];

% Create UndernormalconditionsLabel

app.UndernormalconditionsLabel = uilabel(app.UIFigure);

app.UndernormalconditionsLabel.Position = [108 285 248 22];

app.UndernormalconditionsLabel.Text = 'Under normal conditions';

% Create UIAxes2

app.UIAxes2 = uiaxes(app.UIFigure);

title(app.UIAxes2, 'Position of Train')

xlabel(app.UIAxes2, 'X Position')

ylabel(app.UIAxes2, 'Y Position')

app.UIAxes2.Box = 'on';

app.UIAxes2.XGrid = 'on';

app.UIAxes2.YGrid = 'on';

app.UIAxes2.Position = [18 43 300 185];

% Create EF230Group6Label

app.EF230Group6Label = uilabel(app.UIFigure);

app.EF230Group6Label.HorizontalAlignment = 'center';

app.EF230Group6Label.FontSize = 28;

app.EF230Group6Label.FontWeight = 'bold';

app.EF230Group6Label.Position = [-4 401 379 64];

app.EF230Group6Label.Text = 'EF 230 Group 6';

% Create IanAllishKellyBondIanDaffronLabel

app.IanAllishKellyBondIanDaffronLabel = uilabel(app.UIFigure); app.IanAllishKellyBondIanDaffronLabel.Position = [94 380 184 22]; app.IanAllishKellyBondIanDaffronLabel.Text = 'Ian Allish, Kelly Bond, Ian Daffron';

% Create LoopsCompletedLabel

app.LoopsCompletedLabel = uilabel(app.UIFigure);

app.LoopsCompletedLabel.Position = [18 10 103 22];

app.LoopsCompletedLabel.Text = 'Loops Completed:';

% Create Label

app.Label = uilabel(app.UIFigure);

app.Label.Position = [120 10 178 22];

app.Label.Text = '####';

end

end

methods (Access = public)

% Construct app

function app = micro

% Create and configure components

createComponents(app)

% Register the app with App Designer

registerApp(app, app.UIFigure)

% Execute the startup function

runStartupFcn(app, @startupFcn)

if nargout == 0

clear app

end

end

% Code that executes before app deletion

delete(app)

% Delete UIFigure when app is deleted

delete(app.UIFigure)

end

end

end

Step 4: Final Step

Once the code has been written and the Raspberry Pi has been wired, attach the servo motor to the 3-D printed railroad track gate as it is attached in the picture above.

Now, the project is complete. Connect the raspberry PI to the train track and observe the new system creating safer railroad crossings for both car drivers and conductors. Play with the system by interacting with the GUI to trigger fail safes set in place to prevent accidents.

That's the end of the tutorial, enjoy your new Smart Train System!