Skip to content

Instantly share code, notes, and snippets.

@psallandre
Forked from kosenko-max/racecapture2.lua
Last active May 25, 2016 22:11
Show Gist options
  • Save psallandre/71bd77489d03e5d80a0f42e22019e523 to your computer and use it in GitHub Desktop.
Save psallandre/71bd77489d03e5d80a0f42e22019e523 to your computer and use it in GitHub Desktop.
Improved version of Evo X RaceCapture Pro script (WORKING)
-- Copyright 2016 Mash at boostedforums.net
-- Minify before use by https://mothereff.in/lua-minifier
-- Editor https://ace.c9.io/build/kitchen-sink.html
-- don't remove excessive commas or comments - minify will deal with it
function dump(o)
if type(o) == 'table' then
local s = '{ '
for k,v in pairs(o) do
if type(k) ~= 'number' then k = '"'..k..'"' end
s = s .. '['..k..'] = ' .. dump(v) .. ','
end
return s .. '} '
else
return tostring(o)
end
end
function initCAN( channel, baud )
end
function setTickRate(rate)
end
function getUptime()
return 0
end
local chanId = 0
function addChannel(name,sampleRate,precision,minv,maxv,unit)
print("addChannel", name,sampleRate,precision,minv,maxv, unit)
chanId = chanId + 1
return chanId
end
function txCAN(channel, id, isExtended, data, timeout )
print("txCAN", channel, id, isExtended, dump(data), timeout)
end
function rxCAN(channel, timeout )
print("rxCAN", channel, timeout)
end
function collectgarbage()
end
local afrM = 0.046872 -- AFR Multiplicator - Set own calibration
local afrA = 7.3125 -- AFR Additive - Set own calibration
local mapM = 4/3 -- Set it to 1.0 if stock MAP
local frontO2PID = 0x808661 -- Specific by ROM (this one 5305012
local bToPsi = 14.5037738 -- Set to 1 to get pressures in Bar
--========================== RAX MAIN DATA =====================================
local reqRax =
{
{ 0x7E0, 0x805100, {
{ 160 },
{ 8, "TPS", 0, 100, "%", 100/255 },
{ 8, "APP", 0, 100, "%", 1/2, -16 }, --TODO: Calibrate with MUT3
}},
}
--TODO: Calculated channels (need getChannel in firmware):
-- SSTLoadSlip, SSTMaxPressure, SSTShiftTime,
-- AfrDiff, LtftStft, IDC, Boost, FuelPressError, MivecIn/ExError,
-- MatVsIat
-- GenStatus = 0 - cold, 1 - wait warming, 2 - warming, 3 - full on,
-- 4 - warning check later, 5 - warning slow down, 6 - stop now
-- 5 and 6 go to safe map triggering in ECU
-- ========================= MAIN CYCLE =======================================
local fuelPressureChannel = 3
local targetFuelPressure = 43.5
local chCANHz = addChannel("CAN", 1, 0, 0, 300, "Hz")
initCAN(0, 500000)
setTickRate(1000)
local f = true
function onTick()
if f then -- Clear CAN buffer
for i=1,6 do rxCAN(0,5) end
f=false
end
local started = getUptime()
local mc = 0
readCAN(reqRax, mc)
collectgarbage()
mc = mc + 1
end
function readCAN(defs,count)
for i,def in ipairs(defs) do
local priority = def[3]
local rows = def[4]
if rows == nil then -- Set omitted priority
rows = priority
priority = 1
end
if (count % priority) == 0 then -- Implement priority
local reqLength = def[5]
if reqLength == nil then -- Calculate and save length
reqLength = 0
for i1,row in ipairs(rows) do
reqLength = reqLength + row[1]
end
reqLength = reqLength / 8 -- TODO: Check it works and rounded
def[5] = reqLength
end
local data = readCANdata(def[1],def[2],reqLength)
if data ~= nil then
local pos = 1
for i,row in ipairs(rows) do
local posShift = setChannelData(row,data,pos)
pos = pos + posShift
end
end
end
end
end
--============================ INITIALIZE AND POPULATE CHANNEL WITH DATA =======
function setChannelData(row, data, pos)
-- { Address, PID, Priority (1), {
-- { Bits, Name, Min, Max, Unit, Mult (1), Add (0), Signed (false) },
-- { Bits }, skip number of bits forward
-- } }
-- Length of request calculated automatically
-- Number of digits calculated from multiplicator
if row[2]==nil and row[9]==nil then return row[1] end -- Skip Bits
--TODO: Optimize
if row[9]==nil then -- Channel Undefined - Make one
if row[5]==nil then row[5] = "" end
if row[6]==nil then row[6] = 1 end
if row[7]==nil then row[7] = 0 end
if row[8]==nil then row[8] = false end
local digits = 0
if row[6]<0.001 then digits=4
elseif row[6]<0.01 then digits=3
elseif row[6]<0.1 then digits=2
elseif row[6]<1 then digits=1 end
row[9] = addChannel(row[2], 1000, digits, row[3], row[4], row[5])
row[2] = nil
row[3] = nil
row[4] = nil
row[5] = nil
end
setChannel(row[9],getBitsNumber(data,pos,row[1],row[8])*row[6]+row[7])
return row[1]
end
-- =========== UP TO 24 BIT NUMBER EXTRACTION FROM BYTE ARRAY ==================
local bits = {0x1,0x3,0x7,0xF,0x1F,0x3F,0x7F,
0xFF,0x1FF,0x3FF,0x7FF,0xFFF,0x1FFF,
0x3FFF,0x7FFF,0xFFFF,0x1FFFF,0x3FFFF,0x7FFFF,
0xFFFFF,0x1FFFFF,0x3FFFFF,0x7FFFFF,0xFFFFFF}
local band, bxor, bnot = bit.band, bit.bxor, bit.bnot
local lshift, rshift = bit.lshift, bit.rshift
function getBitsNumber(d,startBit,length,signed)
local shift = (8 - ((startBit+length-1) % 8)) % 8
local startByte = 1 + (startBit - 1 - ((startBit-1) % 8)) / 8--TODO: to //
local bnumb = d[startByte]
-- println(startBit.." "..length.." "..shift.." "..startByte)
-- println(bnumb)
if (length+shift) > 8 then
bnumb = d[startByte+1] + lshift(bnumb,8)
if (length+shift) > 16 then
bnumb = d[startByte+2] + lshift(bnumb,8)
end
end
bnumb = rshift(bnumb,shift)
bnumb = band(bnumb,bits[length])
if signed then bnumb = unsign16Bits(bnumb) end
return bnumb
end
--============================ 2 BYTES SIGNED CONVERSION =======================
function unsign16Bits(number)-- TODO: Verify it works proper and optimize
if number > 0x7FFF then
local byte1=rshift(number,8)
local byte2=band(number,0xFF)
local result = 0 - lshift(band(-bnot(0x1000+byte1),0x00FF),8)
result = result - band(-bxor(0x1000+byte2,0x0000),0x00FF) - 1
return result
end
return number
end
--============================ READ CAN DATA AND RETURN DATA BYTE ARRAY ========
function readCANdata(address,pid,reqLength) -- TODO: Check it works
local req = {2,0x21,255,255,255,255,255,255}
local reqContinue = {48,8,0,255,255,255,255,255}
local timeout = 100
-- Set PID
local mode23 = pid > 255
if mode23 then
req[1] = 5 -- 1 byte mode, 3 byte address, 1 byte length
req[2] = 0x23
req[3]=rshift(pid,16)
req[4]=band(rshift(pid,8),bits[8])
req[5]=band(pid,bits[8])
req[6]=reqLength
else -- MODE21
req[3]=pid
end
res = txCAN(0, address, 0, req, timeout) -- Send request
if res ~= 1 then return nil end
local data = {}
local id, ext, d1 = rxCAN(0,timeout) -- Read Response
if id == nil then return nil end
-- for r,d in ipairs(d1) do print(d..",") end
-- println(" ")
local multi = d1[1] == 0x10 -- Multimessaging
local i = 1
local s = 3
if multi then s=s+1 end
if not mode23 then s=s+1 end -- Mode23 has more data
while s<9 do
data[i]=d1[s]
i=i+1
s=s+1
end
if not multi then return data end
-- Read multi messages
res = txCAN(0, address, 0, reqContinue,timeout)
if res ~= 1 then return nil end
local messages = (d1[2] + 1) / 7
for m=1,messages do
local id, ext, d1 = rxCAN(0,timeout)
if id == nil then return nil end
-- print(m..": ")
-- for r,d in ipairs(d1) do print(d..",") end
-- println(" ")
local s=2
while s<9 and i<reqLength+1 do
data[i]=d1[s]
i=i+1
s=s+1
end
end
return data
end
onTick()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment