Skip to content

Instantly share code, notes, and snippets.

@flaviotoribio
Forked from kosenko-max/racecapture2.lua
Created June 1, 2024 00:44
Show Gist options
  • Save flaviotoribio/cd1721a80ef51fa627e982923e7f0008 to your computer and use it in GitHub Desktop.
Save flaviotoribio/cd1721a80ef51fa627e982923e7f0008 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
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
--========================= SST ================================================
local reqSst =
{
-- { 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
{ 0x7E1, 0x33, 10, {
{ 8, "SstTemp", -50, 205, "C" }, --TODO: Check why -50
}},
-- { 0x7E1, 0x34, 10, {
-- { 8, "SstMode", 1, 3 },
-- }},
-- { 0x7E1, 0x36, 3, {
-- { 8, "Gear", 0, 11 },
-- }},
{ 0x7E1, 0xA6, {
{ 16, "SstSlip1", -8500, 8500, "RPM", 1/2, 0, true },
{ 16, "SstSlip2", -8500, 8500, "RPM", 1/2, 0, true },
}},
{ 0x7E1, 0xAA, {
{ 16, "SstPress1", 0, 30, "Bar", 1/500, 0, true },
{ 16, "SstPress2", 0, 30, "Bar", 1/500, 0, true },
}},
{ 0x7E1, 0xA5, {
{ 16, "SstTemp1", -40, 215, "C", 1/4, 0, true },
{ 16, "SstTemp2", -40, 215, "C", 1/4, 0, true },
}},
}
--========================= SST DIAGNOSTICS ====================================
--local reqSstDiag =
--{
-- { 0x7E1, 0x38, {
-- { 8, "GearTarget", 0, 11 },
-- }},
-- { 0x7E1, 0xAB, {
-- { 16, "SstPosF1", -128, 128, "mm", 1/256, 0, true },
-- { 16, "SstPosF2", -128, 128, "mm", 1/256, 0, true },
-- }},
-- { 0x7E1, 0xAC, {
-- { 16, "SstPosF3", -128, 128, "mm", 1/256, 0, true },
-- { 16, "SstPosF4", -128, 128, "mm", 1/256, 0, true },
-- }},
-- { 0x7E1, 0xAD, {
-- { 16, "SstCurF1", 0, 2048, "mA", 1/16, 0, true },
-- { 16, "SstCurF2", 0, 2048, "mA", 1/16, 0, true },
-- }},
-- { 0x7E1, 0xAE, {
-- { 16, "SstCurCool", 0, 2048, "mA", 1/16, 0, true },
-- }},
-- { 0x7E1, 0xAF, {
-- { 16, "SstCurLPS", 0, 2048, "mA", 1/16, 0, true },
-- }},
-- { 0x7E1, 0xB0, {
-- { 16, "SstShaft1", 0, 8500, "RPM", 1/2, 0, true },
-- { 16, "SstShaft2", 0, 8500, "RPM", 1/2, 0, true },
-- }},
-- { 0x7E1, 0xB2, {
-- { 16, "SstDamper", 0, 8500, "RPM", 1/2, 0, true },
-- }},
--TODO: More codes from CBF
-- https://drive.google.com/file/d/0B2hhlN7v68k8dnN6bnVUUkUxeTQ/view
-- 04: Engine torque
-- 06: Dynamic engine torque
-- 07: Expected engine torque
-- 08: Maximum possible engine torque
-- 09: Minimum engine torque
-- 12: Ambient temperature
-- 2F: Transmission loss torque
-- 2C: Output shaft speed
-- 42: Clutch torque: #1, #2, #1 desired, #2 desired
-- 43: Clutch pressure: #1, #2, #1 desired, #2 desired
-- 44: Acceleration and Deceleration m/sec2
-- B1: Output shaft speed
-- B3: Transmission oil temperature
-- B4: Mechatronic unit temperature
-- B5: Line pressure solenoid
-- B6: Clutch cooling flow solenoid
-- B7: Clutch shift pressure solenoid CSPS1
-- B8: Clutch shift pressure solenoid CSPS2
-- BA: Clutch 1 boost pressures
-- BB: Clutch 2 boost pressures
-- BC: Clutches stroke: 1 pressure, 2 pressure,
-- 1 stroke delta pressures (1,2,3), 2 stroke delta pressures (1,2,3)
-- C3: Valve CSPS1 and CSPS2 : #1 (0-12), #2 (0-12)
-- C4: Valve LPS - part 1: values 0-19
-- C5: Valve LPS - part 2: values 20-32
-- C6: Valve CCFS: Clutch cooling flow solenoid valve #1(0-8),#2(0-8),#3(0-2)
-- C7: Clutches gain: 1,2
--}
--========================= WHEELS, STEERING AND BRAKES ========================
--local reqWheels =
--{
-- { 0x7E1, 0x1B, { --TODO: Verify again
-- { 16,"WheelFR", 0, 3000, "RPM", 1/2 },
-- { 16,"WheelRR", 0, 3000, "RPM", 1/2 },
-- { 16,"WheelFL", 0, 3000, "RPM", 1/2 },
-- { 16,"WheelRL", 0, 3000, "RPM", 1/2 },
-- }},
-- { 0x784, 0x02, { --TODO: Verify again
-- { 16,"Steering", -420, 420, "deg", 1/22.885, 0, true },--TODO: Verify
-- { 32 }, --TODO: Unrecognized or wrong shifts (compare to old version)
-- { 16,"Brakes", 0, 120, "bar", 1/100, 0, true }, --TODO: Check order
-- { 16,"BrakeFL", 0, 120, "bar", 1/100, 0, true },
-- { 16,"BrakeFR", 0, 120, "bar", 1/100, 0, true },
-- { 16,"BrakeRL", 0, 120, "bar", 1/100, 0, true },
-- { 16,"BrakeRR", 0, 120, "bar", 1/100, 0, true },
-- }},
--}
--======================== TEPHRA X MOD V3 LOGGING =============================
local reqXmod3 =
{
{ 0x7E0, 0x805100, {
{ 16,"Load", 0, 1000, "load", 10/32 },
{ 16,"RPM", 0, 10000, "rpm", 1000/256 },
{ 16,"MAP", 0, 10000, "psi", bToPsi*mapM/300 },
{ 16,"MivecIn", -2.5, 37.5, "deg", -10/512, 80 },
{ 16,"MivecEx", -37.5, 2.5, "deg", -10/512, 80 },
{ 16,"IPW", 0, 32, "ms", 1/1000 },
{ 8, "AFR", 8, 20, "afr", afrM, afrA },
{ 8, "Speed", 0, 255, "kph" }, -- "Meh, if you're doing 255, who cares about logging speed:)"
{ 8, "Timing", -20, 107, "deg", 1, -20 },
{ 8, "KnockSum", 0, 255 },
{ 8, "TPS", 0, 100, "%", 100/255 },
{ 8, "WGDC", 0, 100, "%", 1/2 },
{ 8, "ECT", -40, 215, "C", 1, -40 },
{ 8, "MAT", -40, 215, "C", 1, -40 },
{ 8, "IAT", -40, 215, "C", 1, -40 },
{ 8, "STFT", -25, 25, "%", 100/512, -25 },
{ 8, "LTFT", -25, 25, "%", 100/512, -25 },
{ 8, "MAF", 0, 5, "V", 5/255 },
{ 16,"LoadMAP", 0, 1000, "load", 100/16384 },
{ 16,"LoadMAF", 0, 1000, "load", 100/16384 },
{ 8, "KnockBase", 0, 255 },
{ 8, "KnockFilter", 0, 255 },
}},
}
--========================== RAX MAIN DATA =====================================
--local reqRax =
--{
-- { 0x7E0, 0x805100, {
-- { 8, "Load", 0, 398, "load", 100/64},
-- { 8, "IPW", 0, 25.5, "ms", 1/10},
-- { 8, "AfrMap", 8, 20, "afr", 1/14.7/128},
-- { 8, "AFR", 8, 20, "afr", afrM, afrA},
-- { 8, "STFT", -25, 25, "%", 100/512, -25},
-- { 8, "LTFT", -25, 25, "%", 100/512, -25},
-- { 8, "LtftIdle", -25, 25, "%", 100/512, -25},
-- { 8, "LtftCruise", -25, 25, "%", 100/512, -25},
-- { 8, "LoadTiming", 0, 398, "load", 100/64},
-- { 7, "Timing", -20, 107, "deg", 1, -20},
-- { 6, "KnockSum", 0, 63 },
-- { 11,"RPM", 0, 10000, "rpm", 1000/128 },
-- { 9, "MAP", 0, 58, "psi", 0.09200831631*mapM },--TODO: Fix to bar, check evoscan
-- { 7, "Baro", 0.45*bToPsi, 1.725*bToPsi, "psi", bToPsi/200, 0.45*bToPsi},
-- { 8, "WGDC", 0, 100, "%", 1/2 },
-- { 8, "MAF", 0, 5, "V", 5/255 },
-- { 8, "MivecInTar", -2.5, 37.5, "deg", 10/64, -2.5 },
-- { 8, "MivecExTar", -37.5, 2.5, "deg", -10/64, 2.5 },
-- { 8, "MivecIn", -2.5, 37.5, "deg", 10/64, -2.5 },
-- { 8, "MivecEx", -37.5, 2.5, "deg", -10/64, 2.5 },
-- { 8, "TPS", 0, 100, "%", 100/255 },
-- { 8, "APP", 0, 100, "%", 1/2, -16 }, --TODO: Calibrate with MUT3
-- { 8, "IAT", -40, 215, "C", 1, -40 },
-- { 8, "WgdcCorr", -64, 128, "%", 1/2 },
-- { 8, "SpeedH", 0, 330, "kph", 2 },
-- { 8, "EcuVolt", 0, 18.7, "V", 18.7/255 },
-- { 8, "ECT", -40, 215, "C", 1, -40 },
-- { 8, "MAT", -40, 215, "C", 1, -40 },
-- { 8, "LoadMAP", 0, 398, "load", 100/64},
-- { 8, "LoadImap", 0, 398, "load", 100/64},
-- { 8, "LoadMAF", 0, 398, "load", 100/64},
-- { 8, "LoadChosen", 0, 398, "load", 100/64},
-- }},
--
-- { 0x7E0, frontO2PID, 2, {
-- { 8, "FrontO2", 0, 1, "V", 5/255},
-- }},
--
--}
--========================== RAX LEFTOVERS =====================================
--local reqRaxMod3 =
--{
-- { 0x7E0, 0x805110, 5, {
-- { 8, "AfrMap", 8, 20, "afr", 1/14.7/128},
-- {24},
-- { 8, "LtftIdle", -25, 25, "%", 100/512, -25},
-- { 8, "LtftCruise", -25, 25, "%", 100/512, -25},
-- { 8, "LoadTiming", 0, 398, "load", 100/64},
-- {33},
-- { 7, "Baro", 0.45*bToPsi, 1.725*bToPsi, "psi", bToPsi/200, 0.45*bToPsi},
-- {16},
-- { 8, "MivecInTar", -2.5, 37.5, "deg", 10/64, -2.5 },
-- { 8, "MivecExTar", -37.5, 2.5, "deg", -10/64, 2.5 },
-- {24},
-- { 8, "APP", 0, 100, "%", 1/2, -16 }, --TODO: Calibrate with MUT3
-- {8},
-- { 8, "WgdcCorr", -64, 128, "%", 1/2 },
-- { 8, "SpeedH", 0, 330, "kph", 2 },
-- { 8, "EcuVolt", 0, 18.7, "V", 18.7/255 },
-- {24},
-- { 8, "LoadImap", 0, 398, "load", 100/64},
-- {8},
-- { 8, "LoadChosen", 0, 398, "load", 100/64},
-- }},
--
-- { 0x7E0, frontO2PID, 2, {
-- { 8, "FrontO2", 0, 1, "V", 5/255},
-- }},
--}
--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
repeat
readCAN(reqSst, mc)
-- readCAN(reqSstDiag, mc)
-- readCAN(reqWheels, mc)
readCAN(reqXmod3, mc)
collectgarbage()
-- readCAN(reqRaxMod3, mc)
mc = mc + 1
until getUptime() > started + 1000
-- Release Tick every second to allow refresh of scripts
setChannel(chCANHz, mc)
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment