Here is a example
listing
of a simple script Sidings
Test - V3.lua
(this may not be as up to date as the zip file available on
the main
RFID page):
--[=[ --------------------------------------------------------------------------- Remote Train Control Program for Windows
© Copyright 2020 by Mark DiVecchio
This file is part of Remote Train Control.
Remote Train Control is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Remote Train Control is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Remote Train Control. If not, see <http://www.gnu.org/licenses/>.
Home Page : http://www.silogic.com/trains/RTC_Running.html ---------------------------------------------------------------------------]=] -- Semicolons are not required in Lua code title = "Sidings Test" require([[defines]]); require([[functions]]);
local SD = require([[Distances]]); -- Measured stopping and starting distances in inches
-- Counter Labels Counter01Label = "Engine Starts"; C1 = COUNTER01; Counter02Label = "State"; C2 = COUNTER02; Counter03Label = "#Tags"; C3 = COUNTER03; Counter04Label = "Target Distance"; C4 = COUNTER04; Counter05Label = "C5"; C5 = COUNTER05; Counter06Label = "C6"; C6 = COUNTER06; -- table to hold all of the tags detected in sequence Tags = {}; TagCount = 0; -- starting time DTOStart = 0.0; -- -- Siding entrance test -- local STOPTIME = 15; local STARTTIME = 10; BeepOn = false; SoundOff = false; SPEEDINCREMENT = 10;
-- state machine states IDLE = 10; DONE = 11; S0 = 0; S1 = 1; S2 = 2; S3 = 3; S4 = 4; S5 = 5; S6 = 6; -- starting state SM = IDLE; StartRun = false; BASESPEED = 20; Direction = "WB"; -- "WB" for all of these sidings
-- Switches local COLLEGE_WEST_AIU = 1; local COLLEGE_WEST_CHAN = 1; local COLLEGE_EAST_AIU = 1; local COLLEGE_EAST_CHAN = 2;
local STRUTHERS_WEST_AIU = 2; local STRUTHERS_WEST_CHAN = 5; local STRUTHERS_EAST_AIU = 2; local STRUTHERS_EAST_CHAN = 6;
local ALIQUIPPA_WEST_AIU = 1; local ALIQUIPPA_WEST_CHAN = 9; local ALIQUIPPA_EAST_AIU = 1; local ALIQUIPPA_EAST_CHAN = 5;
--[[---------------------------------------------------------------------------------------]] function setup(Engine, TIU) print(os.date("setup() %d %b %Y %X")); -- MyEngineNo = Engine; MyTIUNo = TIU;
SetLED(1, clRed, "LED1"); SetLED(2, clRed, "LED2"); SetLED(3, clRed, "LED3"); SetLED(4, clRed, "LED4"); -- print("setup() : TIU#" .. MyTIUNo .. " Engine#" .. MyEngineNo .. " Debug " .. Debug()); print(string.format("Run Time = %.2f Seconds", RunTime())); Name, PS = GetName(MyEngineNo); print("Engine#" .. MyEngineNo .. " " .. Name .. " PS" .. PS); Title(title .. " - " .. GetName(Engine)); Smoke(OFF, 0, MyEngineNo, MyTIUNo); StartUp(0, MyEngineNo, MyTIUNo); -- start selected engine
-- aim for the first reader Target_Station = "College"; Target_Detector = SD.STOP(Target_Station, Direction, "Detector"); Target_Reader = SD.STOP(Target_Station, Direction, "Reader"); if (MyEngineNo == 7 or MyEngineNo == 13) then Target_Distance = SD.STOP(Target_Station, Direction, "Passenger"); --Passenger StoppingDistance; else Target_Distance = SD.STOP(Target_Station, Direction, "Freight"); --Freight StoppingDistance; end Direction = "WB"; SetCounter(C4, Target_Distance);
-- let engine startup Sleep(15); SM = IDLE; SetCounter(C2, IDLE); print(string.format("Run Time = %.2f Seconds", RunTime())); DTOStart = DTO(Engine, MyTIUNo); print(string.format("Trip Odometer Start %.2f Smiles", DTOStart)); print(string.format("Run Time = %.2f Seconds", RunTime())); -- set acceleration and decelleration values Decell = 1; Rate(1, Decell, 0, MyEngineNo, MyTIUNo); print("setup : Set decelleration rate to " .. Decell); StopForwardScheduled = false; StopReverseScheduled = false; print("Please select a target station by pressing a button.........."); return true; end --[[---------------------------------------------------------------------------------------]]
function tag(Detector, Reader, EngineNo, TagLocation, CarModel, Railroad, CarNumber, TagPacket) -- this function is called each time a tag is detected if (EngineNo ~= MyEngineNo) then return true; end; if (Debug() and BeepOn) then Beep(); end; -- sound a tone -- Line below shows a different way to quote a string using brackets if (EngineNo > 0) then -- it's an engine print(string.format([[tag(%.2f) : Detector %d Reader %d Eng#%d %s %s #%s %s]], RunTime(), Detector, Reader, EngineNo, GetRailroadName(Railroad), GetEngineName(CarModel), CarNumber, GetTagLocation(TagLocation))); else -- it's a car print(string.format([[tag(%.2f) : Detector %d Reader %d Car %s %s #%s]], RunTime(), Detector, Reader, GetRailroadName(Railroad), GetCarName(CarModel), CarNumber)); end
-- The complete packet received is in TagPacket -- (some of the most used fields have already been extracted into the first parameters to tag() -- First 8 digits are the 4 byte Tag UID in hexidecimal -- Next 32 digits are the 16 bytes of Block 4 Information read from the Tag in hexidecimal -- Final 4 digits are the checksum and End of Packet character if (Debug() > 3) then print(string.format("Packet %s", string.sub(TagPacket, 1, 40))); end -- index the table Tags[] by tag ID, value is the tag packet itself Tags[string.sub(TagPacket, 1, 8)] = string.sub(TagPacket, 9, 40); -- remove checksum and EOP TagCount = TagCount + 1; -- count the number of tags BumpCounter(C3); -- display the number of tags --[[---------------------------------------------------------------------------------------]] -- STATE MACHINE --[[---------------------------------------------------------------------------------------]] if (SM == IDLE) then -- do nothing Sleep(1); return true; -- false=stop calling loop(), true=continue to call loop() end; if (SM == DONE) then -- finish up SetCounter(C2, IDLE); SM = IDLE; -- go idle print("Almost Done..."); Stop("DONE"); return false; -- false=stop calling loop(), true=continue to call loop() end; if (SM == S0) then -- run forward until the engine tag is detected over the Detector/Reader if (isEngine(EngineNo) and isDetector(Detector, Target_Detector) and isReader(Reader, Target_Reader)) then if (isTagFront(TagLocation)) then -- set stopping time delay to calculated value if (GetDirection(EngineNo, MyTIUNo) == FORWARD) then --print("S0 : Tag Detected in Forward");
-- stop the engine -- time(seconds) = d(in) * 48 Smiles/mile * 3600 sec/hr * / (12 in/ft * 5280 ft/mile * X Smiles/hr) StopDelay = (Target_Distance - SD.Stopping(EngineNo, EngSpeed)) * (48 / (12 * 5280 * EngSpeed)) * 3600; print(string.format("Target Distance = %d in - Stopping Distance = %.3f in - Speed %d Smph = Stop Delay %.3f seconds", Target_Distance, SD.Stopping(EngineNo, EngSpeed), EngSpeed, StopDelay)); EngSpeed = 0; print("S0 : Set speed to " .. EngSpeed .. " after " .. StopDelay .. " seconds") Throttle(EngSpeed, StopDelay, EngineNo, MyTIUNo); -- set Speed to EngSpeed StopForwardScheduled = true; local StartDelay = StopDelay + STOPTIME; -- set direction to reverse SetDirection(REVERSE, StartDelay, EngineNo, MyTIUNo); -- start the engine moving in reverse EngSpeed = BASESPEED; StartDelay = StartDelay + 2; print("S0 : Set speed to " .. EngSpeed .. " after " .. StartDelay .. " seconds") Throttle(EngSpeed, StartDelay, EngineNo, MyTIUNo); -- set Speed to EngSpeed BumpCounter(C1); -- bump number of engine starts -- stay in S0 return true; end; end;
if (isTagRear(TagLocation)) then if (not StopForwardScheduled) then Stop("S0 : Engine Front tag not detected"); end StopForwardScheduled = false; SetCounter(C2, S1); -- go to S1 SM = S1 return true; end end; -- Stay in S0 return true; -- false=stop calling loop(), true=continue to call loop() end;
if (SM == S1) then -- run reverse until the engine tag is detected over the Detector/Reader if (isEngine(EngineNo) and isDetector(Detector, Target_Detector) and isReader(Reader, Target_Reader)) then if (isTagRear(TagLocation)) then -- set stopping time delay to fixed value if (GetDirection(EngineNo, MyTIUNo) == REVERSE) then --print("S1 : Tag Detected in Reverse");
-- stop the engine EngSpeed = 0; local StopDelay = 5; print("S1 : Set speed to " .. EngSpeed .. " after " .. StopDelay .. " seconds"); Throttle(EngSpeed, StopDelay, EngineNo, MyTIUNo); -- set Speed to EngSpeed StopReverseScheduled = true; local StartDelay = 15; -- set direction to forward SetDirection(FORWARD, StartDelay, EngineNo, MyTIUNo); -- start the engine moving forward EngSpeed = BASESPEED; StartDelay = StartDelay + 2; print("S1 : Set speed to " .. EngSpeed .. " after " .. StartDelay .. " seconds"); Throttle(EngSpeed, StartDelay, EngineNo, MyTIUNo); -- set Speed to EngSpeed BumpCounter(C1); -- bump number of engine starts -- Stay in S1 return true; end; end; if (isTagFront(TagLocation)) then if (not StopReverseScheduled) then Stop("S1 : Engine Rear tag not detected"); end StopReverseScheduled = false; SetCounter(C2, S0); SM = S0; return true; end; end; -- Stay in S1 return true; -- false=stop calling loop(), true=continue to call loop() end; if (SM == S2) then
return true; -- false=stop calling loop(), true=continue to call loop() end; if (SM == S3) then
return true; -- false=stop calling loop(), true=continue to call loop() end; if (SM == S4) then
return true; -- false=stop calling loop(), true=continue to call loop() end; if (SM == S5) then Sleep(20); SM = DONE; -- TBD End the script return true; -- false=stop calling loop(), true=continue to call loop() end; if (SM == S6) then Sleep(20); SM = DONE; -- TBD End the script return true; -- false=stop calling loop(), true=continue to call loop() end; if (SM == S7) then Sleep(20); SM = DONE; -- TBD End the script return true; -- false=stop calling loop(), true=continue to call loop() end; if (SM == S8) then Sleep(20); SM = DONE; -- TBD End the script return true; -- false=stop calling loop(), true=continue to call loop() end; --[[---------------------------------------------------------------------------------------]] return true; -- true=continue to process tags, false=stop processing tags end --[[---------------------------------------------------------------------------------------]] function cleanup(Engine, TIU) -- this function is called once when the user presses the [STOP] button print(os.date("cleanup() %d %b %Y %X")); print("cleanup() : TIU#" .. TIU .. " Engine#" .. Engine .. " Debug " .. Debug()); StartRun = false; Throttle(0, 0, Engine, TIU); DTOFinish = DTO(Engine, TIU); -- wait for dispatch list to empty if (CountDispatchList() > 0) then ClearDispatchList(); end; print(string.format("Run Time = %.2f seconds", RunTime())); print(string.format("Trip Odometer Finish %.2f Smiles", DTOFinish)); Sleep(5); ShutDown(0, Engine, TIU); Sleep(5); if (SoundOff) then SoundOnButton(Engine, TIU) end; ShowTags(Engine, TIU); -- dump out the Tags table return true; -- false=cleanup failed, true=cleanup succeeded end; --[[---------------------------------------------------------------------------------------]] function B1(Eng, TIU) -- aim for the this reader Target_Station = "Aliquippa"; Direction = "WB"; Target_Detector = SD.STOP(Target_Station, Direction, "Detector"); Target_Reader = SD.STOP(Target_Station, Direction, "Reader"); if (MyEngineNo == 7 or MyEngineNo == 13) then Target_Distance = SD.STOP(Target_Station, Direction, "Passenger"); --Passenger StoppingDistance; else Target_Distance = SD.STOP(Target_Station, Direction, "Freight"); --Freight StoppingDistance; end
SetCounter(C4, Target_Distance); print("Aliquippa Target Distance = " .. Target_Distance); StartTheEngine(); return true; end; Function01Name, Function01Label = B1, "Aliquippa"; --[[---------------------------------------------------------------------------------------]] function B2(Eng, TIU) -- aim for the this reader Target_Station = "College"; Direction = "WB"; Target_Detector = SD.STOP(Target_Station, Direction, "Detector"); Target_Reader = SD.STOP(Target_Station, Direction, "Reader"); if (MyEngineNo == 7 or MyEngineNo == 13) then Target_Distance = SD.STOP(Target_Station, Direction, "Passenger"); --Passenger StoppingDistance; else Target_Distance = SD.STOP(Target_Station, Direction, "Freight"); --Freight StoppingDistance; end
SetCounter(C4, Target_Distance); print("College Target Distance = " .. Target_Distance); StartTheEngine(); return true; end; Function02Name, Function02Label = B2, "College"; --[[---------------------------------------------------------------------------------------]] function B3(Eng, TIU) -- aim for the this reader Target_Station = "Struthers"; Direction = "WB"; Target_Detector = SD.STOP(Target_Station, Direction, "Detector"); Target_Reader = SD.STOP(Target_Station, Direction, "Reader"); if (MyEngineNo == 7 or MyEngineNo == 13) then Target_Distance = SD.STOP(Target_Station, Direction, "Passenger"); --Passenger StoppingDistance; else Target_Distance = SD.STOP(Target_Station, Direction, "Freight"); --Freight StoppingDistance; end
SetCounter(C4, Target_Distance); print("Struthers Target Distance = " .. Target_Distance); StartTheEngine(); return true; end; Function03Name, Function03Label = B3, "Struthers"; --[[---------------------------------------------------------------------------------------]] function B4(Eng, TIU) -- aim for the this reader Target_Station = "J&L"; Direction = "WB"; Target_Detector = SD.STOP(Target_Station, Direction, "Detector"); Target_Reader = SD.STOP(Target_Station, Direction, "Reader"); if (MyEngineNo == 7 or MyEngineNo == 13) then Target_Distance = SD.STOP(Target_Station, Direction, "Passenger"); --Passenger StoppingDistance; else Target_Distance = SD.STOP(Target_Station, Direction, "Freight"); --Freight StoppingDistance; end
SetCounter(C4, Target_Distance); print("J&L Target Distance = " .. Target_Distance); StartTheEngine(); return true; end; Function04Name, Function04Label = B4, "J&&L"; -- Use "&&" to get one "&" in the label text --[[---------------------------------------------------------------------------------------]] function StartTheEngine() if (StartRun) then return true; end; -- engine already running StartRun = true; -- start engine BumpCounter(C1); EngSpeed = BASESPEED; print("StartTheEngine : Set speed to " .. EngSpeed); Throttle(EngSpeed, 0, MyEngineNo, MyTIUNo); -- set Speed to EngSpeed BumpCounter(C1); -- check that the engine has reached speed local StartTime = STARTTIME * 2; while (GetSpeed(MyEngineNo, MyTIUNo) ~= BASESPEED) do if (StartTime == 0) then EmergencyStop("StartTheEngine : Engine#" .. MyEngineNo .. " Did not Start"); -- failure return false; end Sleep(2); StartTime = StartTime - 2; end;
SetCounter(C2, S0); SM = S0; -- go wait for first tag end; --[[---------------------------------------------------------------------------------------]] function IncTarget(Eng, TIU) Target_Distance = Target_Distance + 1; print("Target Distance = " .. Target_Distance); SetCounter(C4, Target_Distance); return true; end; Function06Name, Function06Label = IncTarget, "Target +1"; --[[---------------------------------------------------------------------------------------]] function DecTarget(Eng, TIU) Target_Distance = Target_Distance -1; print("Target Distance = " .. Target_Distance); SetCounter(C4, Target_Distance); return true; end; Function07Name, Function07Label = DecTarget, "Target -1"; --[[---------------------------------------------------------------------------------------]] --[[ function B8(Eng, TIU) Direction = "EB"; return true; end; Function08Name, Function08Label = B8, "East Bound"; --]] --[[---------------------------------------------------------------------------------------]] function ShowTags(Eng, TIU) print("Tags detected:"); --if (#Tags == 0) then -- print ("none"); -- end for k,v in pairs(Tags) do -- dump out the Tags table print(k .. " " .. v); end return true; end; Function09Name, Function09Label = ShowTags, "Show Tags"; --[[---------------------------------------------------------------------------------------]] function SoundOffButton(Eng, TIU) print("Sound Off Button()"); S1 = GetVolume(MASTER_VOLUME, Eng, TIU); -- get Volume print(" Sound Off - Engine " .. Eng .. " Level was " .. S1); EngineSoundSave = S1; SoundOff = true; SetVolume(MASTER_VOLUME, 0, 0, Eng, TIU); return true; end; Function05Name, Function05Label = SoundOffButton, "Sound Off"; --[[---------------------------------------------------------------------------------------]] function SoundOnButton(Eng, TIU) print("Sound On Button()"); if (SoundOff) then S1 = EngineSoundSave; print(" Sound On - Engine " .. Eng .. " Level restored to " .. S1); SoundOff = false; SetVolume(MASTER_VOLUME, S1, 0, Eng, TIU); end; return true; end; Function10Name, Function10Label = SoundOnButton, "Sound On"; --[[---------------------------------------------------------------------------------------]]
|