Smart Train System
Designed to increase safety, prevent accidents, and increase positive and productive response to help if accidents do occur.
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
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
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
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!