I am trying to implement some Shift2X stuff and my program has begun to behave weirdly. I was getting sporadic out of memory errors and I cut out some stuff - but the program will run for a while and then act up oddly which I am assuming means out of memory stuff.
I'm pretty novice at LUA and I was wondering if you had any suggestions on streamlining this to reduce memory usage.
I am running this through a minifier - so that strips out all the comments and such.
I was thinking of abandoning the Shift2X routines and simply writing to the LEDs. That would be a bummer but it seems like the Shift2X stuff is when I started to get issues.
Is there any way to determine how much memory this program will use and how close I am to running into memory errors?
Any suggestions (that sort of maintain functionality) would be really appreciated.
Code: Select all
--Udder Chaos Lua Script File
-- Revision Log
-- Version Date Description
-- 1 April 17 Road America - first Race
-- 2 August 17 Gingerman Race
-- Removed piggy back gages
-- Added brake sensor
-- Adding CAN bus functionalty to OBDII
-- Adding shift light sensor
-- 8-15 added can Sniffer
-- brake light script
-- 3 Road America Second Race
-- added virtual channel for brakes and gears
-- 4 April 2018 Road America - First Race
-- Adding in Shift2X LED display
-- Debug of brake light delay and trying to add the CAN bus back in
-- Remove can bus
-- Useful Reference Stuff: - channels start at 0 (i.e. AN1 = channel 0)
-- AN1 = OIL PRESSURE
-- AN2 = TRANS TEMP
-- AN3 = OIL TEMP
-- AN4 = H20 TEMP
-- AN5 = FUEL
-- AN6 = 02
-- AN7 = MAP
-- RPM1 = TACH
-- Shift2X is on CAN1
-- debug = true -- flag used to turn on various rountines when debugging the program - uncomment if needed
-- Adding virtual Channels
fuel_damped = addChannel("Fuel_Level", 10, 1, 0,12.6,"%") -- Fuel_damped is a virtual channel that smooths out fuel sloshing
brake_status = addChannel("Brake_stat", 10, 0) --- A virtual channel used to report when the brake is pressed for logging.
gearId = addChannel("Gear",5) -- A virtual channel used to track which gear we are in.
-- Fuel Anti-sloshing routine stuff
maxAvg = 75 --change this to make a bigger averaging window
fuelAvg={} -- define fuelAvg as a LUA array
fuel_damped_Index = 1
-- Function updateFuelAverage - called by tick - smooths out fuel
function updateFuelAvg(value)
local i
if #fuelAvg == 0 then
--initialize averaging table
for i = 1, maxAvg do fuelAvg[i]=0 end
end
fuelAvg[fuel_damped_Index] = value
fuel_damped_Index = fuel_damped_Index + 1
if fuel_damped_Index > maxAvg then fuel_damped_Index = 1 end
local sum = 0
for i = 1, #fuelAvg do
sum = sum + fuelAvg[i]
end
setChannel(fuel_damped, sum / maxAvg)
end
-- Function check_gear updates the gear position - called every tick
function check_gear()
-- Constants for Gear Determination
-- Put these directly into code to save memory
-- local _1stGear = 3.54
-- local _2ndGear = 2.13
-- local _3rdGear = 1.36
-- local _4thGear = 1.03
-- local _5thGear = .81
-- local FinalDrive = 3.94
local TireDia = 23.0 -- in inches
local gearErr = 0.1--allowable error of gear ratio to allow for measurement variation
local rpmSpeedRatio = 0
local gearPos = 0 --initialized to 0 so if it doesn't work you know
local speed = getGpsSpeed()
local rpm = getTimerRpm(0)
if speed > 10 then
--makes sure your rolling so as not to divide by 0
rpmSpeedRatio = (rpm/speed)/(FinalDrive*1056/(TireDia*3.14159))
if ((3.54 - rpmSpeedRatio)^2) < (gearErr^2) then gearPos = 1 end
if ((2.13 - rpmSpeedRatio)^2) < (gearErr^2) then gearPos = 2 end
if ((1.36 - rpmSpeedRatio)^2) < (gearErr^2) then gearPos = 3 end
if ((1.03 - rpmSpeedRatio)^2) < (gearErr^2) then gearPos = 4 end
if ((.81 - rpmSpeedRatio)^2) < (gearErr^2) then gearPos = 5 end
else gearPos = 0 end
setChannel(gearId, gearPos) --outputs to virtual channel
end
-- ShiftX2 is connected to CAN1. 0=CAN1, 1=CAN2
sxCan = 0
-- 0=first ShiftX2 on bus, 1=second ShiftX2 (if ADR1 jumper is cut)
sxId=0
--how often ontick is updated
tickRate=10
--Brightness, 0-100. 0=automatic brightness
sxBright=0
function sxOnUpdate()
-- To keep things simple for the driver we are not attempting to map LEDs to specific warnings or danger conditions. If ANY
-- threshold is exceeded, the two end LEDs on the ShiftX will light up (yellow for warning - red for danger). The driver
-- should be able to see what the specific problem is by looking at the gages.
local warning = false -- Boolean variable tracking warning threshold has been exceeded.
local danger = false -- Boolean variable tracking that danger threshold has been exceeded.
-- Thresholds These are in here for convenience and must be updated in the code below
-- Warning Danger
-- AN1 (Channel 0) = OIL PRESSURE 35 20 (PSI)
-- AN2 (Channel 1) = TRANS TEMP 185 200 (Degrees F)
-- AN3 (Channel 2) = OIL TEMP 220 250 (Degrees F)
-- AN4 (Channel 3) = H20 TEMP 212 230 (Degrees F)
-- Go get the readings from the analog gages for Oil pressure, Trans Temp, Oil Temp and coolant temp
oil_pressure = getAnalog(0)
trans_temp = getAnalog(1)
oil_temp = getAnalog(2)
H20_temp = getAnalog(3)
if debug then println('oilpressure = '..oil_pressure) end
if oil_pressure < 35 then warning = true
end
if oil_pressure < 20 then danger=true
end
if trans_temp > 185 then warning=true
end
if trans_temp > 200 then danger=true
end
if oil_temp > 220 then warning=true
end
if oil_temp > 250 then danger=true
end
if H20_temp > 212 then warning=true
end
if H20_temp > 230 then danger=true
end
-- If one of the warning flags has been set - set the two end LEDS (7 and 8) to yellow.
if warning and (not danger ) then
sxSetLed(8,1,255,255,0,0)
sxSetLed(7,1,255,255,0,0)
-- If one of the danger flags has been set - set the two end LEDs (7 and 8) to red and flash them.
elseif danger and warning then
sxSetLed(8,1,255,0,0,0)
sxSetLed(7,1,255,0,0,0)
-- Otherwise set the two end LEDs to green (no warning and no danger)
else
sxSetLed(8,1,0,255,0,0)
sxSetLed(7,1,0,255,0,0)
end
-- Update the linear graph with the current RPM
sxUpdateLinearGraph(getTimerRpm(0))
end
function sxOnInit()
--config shift light
sxCfgLinearGraph(0,0,0,7000) --left to right graph, linear style, 0 - 7000 RPM range
sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
sxSetLinearThresh(1,0,5800,255,255,0,0) --yellow at 5800 RPM
sxSetLinearThresh(2,0,6200,255,0,0,10) --red+flash at 6200 RPM
end
---ShiftX2 functions
function sxSetLed(i,l,r,g,b,f)
sxTx(10,{i,l,r,g,b,f})
end
function sxSetLinearThresh(id,s,th,r,g,b,f)
sxTx(41,{id,s,spl(th),sph(th),r,g,b,f})
end
function sxSetAlertThresh(id,tid,th,r,g,b,f)
sxTx(21,{id,tid,spl(th),sph(th),r,g,b,f})
end
function setBaseConfig(bright)
sxTx(3,{bright})
end
function sxSetAlert(id,r,g,b,f)
sxTx(20,{id,r,g,b,f})
end
function sxUpdateAlert(id,v)
if v~=nil then sxTx(22,{id,spl(v),sph(v)}) end
end
function sxCfgLinearGraph(rs,ls,lr,hr)
sxTx(40,{rs,ls,spl(lr),sph(lr),spl(hr),sph(hr)})
end
function sxUpdateLinearGraph(v)
if v ~= nil then sxTx(42,{spl(v),sph(v)}) end
end
function sxInit()
setBaseConfig(sxBright)
if sxOnInit~=nil then sxOnInit() end
end
function sxChkCan()
id,ext,data=rxCAN(sxCan,0)
if id==sxCanId then sxInit() end
if id==sxCanId+60 and sxOnBut~=nil then sxOnBut(data[1]) end
end
function sxProcess()
sxChkCan()
if sxOnUpdate~=nil then sxOnUpdate() end
end
function sxTx(offset, data)
txCAN(sxCan, sxCanId + offset, 1, data)
sleep(10)
end
function spl(v) return bit.band(v,0xFF) end
function sph(v) return bit.rshift(bit.band(v,0xFF00),8) end
-- Function onTick is the main loop for the program.
-- Ontick will call update fuel average to create a smoothed out fuel level
function onTick()
collectgarbage() -- This deletes objects in LUA that are unsuable
updateFuelAvg(getAnalog(4))-- call the fuel average routine and pass it the current fuel tank reading to smooth out.
check_gear() -- call the routine that checks to see what gear we are in
sxProcess() -- Process the shift-2X routines to update the LED dashboard display
-- Turn on logging anytime the speed of the car is >10mph. Otherwise stop logging.
if getGpsSpeed() > 10 then
startLogging()
else
stopLogging()
end
-- Check Input a and see if the brake lights have been pushed. if so, set a virtual channel to 1
if getGpio(1) == 0 then
setChannel(brake_status,0)
else
setChannel(brake_status,1)
end
end
sxCanId = 0xE3600 + (256 * sxId)
setTickRate(tickRate)
sxInit()