Last active
June 1, 2024 00:46
-
-
Save kosenko-max/059c125aafdc0a8a4f0c12c5cc4ab09c to your computer and use it in GitHub Desktop.
Improved version with CAN mapping in the config string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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 | |
-- ========================= CAN CONFIG ======================================= | |
local canCon ="0x7E1,0x33,10;8,SstTemp,-50,205,C@0x7E1,0x34,10;8,SstMode,1,3@0x7E1,0x36,3;8,Gear,0,11@0x7E1,0xA6;16,SstSlip1,-8500,8500,RPM,1/2,0,1;16,SstSlip2,-8500,8500,RPM,1/2,0,1@0x7E1,0xAA;16,SstPress1,0,30,Bar,1/500,0,1;16,SstPress2,0,30,Bar,1/500,0,1@0x7E1,0xA5;16,SstTemp1,-40,215,C,1/4,0,1;16,SstTemp2,-40,215,C,1/4,0,1@0x7E1,0x38;8,GearTarget,0,11@0x7E1,0xAB;16,SstPosF1,-128,128,mm,1/256,0,1;16,SstPosF2,-128,128,mm,1/256,0,1@0x7E1,0xAC;16,SstPosF3,-128,128,mm,1/256,0,1;16,SstPosF4,-128,128,mm,1/256,0,1@0x7E1,0xAD;16,SstCurF1,0,2048,mA,1/16,0,1;16,SstCurF2,0,2048,mA,1/16,0,1@0x7E1,0xAE;16,SstCurCool,0,2048,mA,1/16,0,1@0x7E1,0xAF;16,SstCurLPS,0,2048,mA,1/16,0,1@0x7E1,0xB0;16,SstShaft1,0,8500,RPM,1/2,0,1;16,SstShaft2,0,8500,RPM,1/2,0,1@0x7E1,0xB2;16,SstDamper,0,8500,RPM,1/2,0,1@0x7E1,0x1B;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;16,Steering,-420,420,deg,1/22.885,0,1;32;16,BrakeMC,0,120,bar,1/100,0,1;16,BrakeFL,0,120,bar,1/100,0,1;16,BrakeFR,0,120,bar,1/100,0,1;16,BrakeRL,0,120,bar,1/100,0,1;16,BrakeRR,0,120,bar,1/100,0,1@0x7E0,0x805100;16,Load,0,1000,load,10/32;16,RPM,0,10000,rpm,1000/256;16,MAP,0,60,psi,19.3383650667/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,0.001;8,AFR,8,18,afr,0.046872,7.3125;8,Speed,0,255,kph;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@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;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*14.5037738,1.725*14.5037738,psi,14.5037738/200,0.45*14.5037738;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;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,0x808661,2;8,FrontO2,0,1,V,5/255@" | |
local canMap = {} | |
local sb,sl,sm = string.byte,string.len,string.match | |
function readOne(pos) | |
local c = sb(canCon,pos) | |
if c==nil then return nil,pos+1 end | |
if (c > 47 and c < 58) or c==45 then -- read number | |
local nums = sm(canCon,"[-.%xxX]+",pos) | |
local num = tonumber(nums) | |
local pos2 = pos+sl(nums) | |
c=sb(canCon,pos2) | |
if c==42 or c==47 then -- MULTIPLY or DIVIDE | |
pos2=pos2+1 | |
local nums2=sm(canCon,"[-.%xxX]+",pos2) | |
local num2=tonumber(nums2) | |
pos2 = pos2+sl(nums2) | |
if c==42 then num=num*num2 else num=num/num2 end | |
end | |
return num,pos2 | |
end | |
-- Read string | |
local st = sm(canCon,"[^,;@]+",pos) | |
if st==nil then return nil,pos+1 | |
else return st, pos+sl(st) end | |
end | |
function ss(pos) | |
return string.sub(canCon,pos,pos) | |
end | |
function canRDmap() | |
local cmi,res,pos = 1,nil,1 | |
while pos <= sl(canCon) do | |
canMap[cmi]=nil -- separator of requests | |
canMap[cmi+1],pos=readOne(pos) -- address | |
canMap[cmi+2],pos=readOne(pos+1) -- pid | |
if ss(pos) =="," then | |
canMap[cmi+3],pos=readOne(pos+1) -- priority | |
else canMap[cmi+3]=1 end | |
--print("REQUEST Address: "..canMap[cmi+1].." PID: "..canMap[cmi+2].." Priority: "..canMap[cmi+3]) | |
local cmi_len = cmi+4 | |
canMap[cmi_len]=0 | |
cmi=cmi+5 | |
while ss(pos)~="@" do | |
-- Address,PID,Priority (1) | |
-- ;Bits,Name,Min,Max,Unit,Mult(1),Add(0),Signed(0/1 - default 0) | |
-- ;Bits - skip number of bits forward | |
-- @ | |
-- nil, address, pid, priority, length - request | |
-- bits, nil - skip | |
-- bits, channelId, mult, add, signed - channel | |
--print(" start char "..ss(pos)) | |
local name,minv,maxv,precision,unit,mult = "",0,0,0,"",1 | |
canMap[cmi],pos=readOne(pos+1) --bits | |
--print(" bits: "..canMap[cmi]) | |
canMap[cmi_len]=canMap[cmi_len]+canMap[cmi] -- count length | |
if ss(pos)~="," then | |
--print(" skip "..ss(pos)) | |
canMap[cmi+1]=nil -- Skip | |
cmi=cmi+2 | |
else | |
name,pos = readOne(pos+1) | |
minv,pos = readOne(pos+1) | |
maxv,pos = readOne(pos+1) | |
if ss(pos)=="," then unit,pos = readOne(pos+1) --unit | |
else unit = "" end | |
if ss(pos)=="," then mult,pos = readOne(pos+1) --mult | |
else mult=1 end | |
canMap[cmi+2]=mult | |
if ss(pos)=="," then canMap[cmi+3],pos = readOne(pos+1) --add | |
else canMap[cmi+3]=0 end | |
if ss(pos)=="," then canMap[cmi+4],pos = readOne(pos+1) --sign | |
else canMap[cmi+4]=0 end | |
while mult < 1 do | |
precision=precision+1 | |
mult=mult*10 | |
end | |
canMap[cmi+1]=addChannel(name,1000,precision,minv,maxv,unit) | |
cmi=cmi+5 | |
end | |
end | |
pos=pos+1 | |
end | |
canCon = nil -- Clean memory from large string we won't use anymore | |
end | |
function canRDall(count) | |
-- nil, address, pid, priority, length - request | |
-- bits, nil - skip | |
-- bits, channelId, mult, add, signed - channel | |
local i = 1 | |
while canMap[i+1]~=nil do | |
if (count % canMap[i+3]) == 0 then -- Priority implement | |
local data = canRD(canMap[i+1],canMap[i+2],canMap[i+4]) | |
if data ~= nil then | |
i=i+5 | |
local bit = 1 | |
while canMap[i]~=nil do -- Set Channels | |
if canMap[i+1]~=nil then | |
local val = bitsToN(data,bit,canMap[i],canMap[i+4]) | |
val=val*canMap[i+2]+canMap[i+3] | |
setChannel(canMap[i+1],val) | |
bit=bit+canMap[i] | |
i=i+5 | |
else -- skip bits | |
bit=bit+canMap[i] | |
i=i+2 | |
end | |
end | |
end | |
end | |
end | |
end | |
-- =========== UP TO 24 BIT NUMBER EXTRACTION FROM BYTE ARRAY ================== | |
local band, bxor, bnot = bit.band, bit.bxor, bit.bnot | |
local lshift, rshift = bit.lshift, bit.rshift | |
function bitsToN(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] | |
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,2^length-1) | |
if signed and bnumb > 0x7FFF then | |
bnumb = 0 - lshift(band(-bnot(0x1000+rshift(number,8)),0xFF),8) | |
- band(-bxor(0x1000+band(number,0xFF),0),0xFF) - 1 | |
end | |
return bnumb | |
end | |
--============================ READ CAN DATA AND RETURN DATA BYTE ARRAY ======== | |
function canRD(address,pid,reqLength) -- TODO: Check it works without padding | |
local req | |
if pid > 255 then -- MODE 23 | |
req = {5,0x23,rshift(pid,16),rshift(pid,8),band(pid,0xFF),reqLength} | |
else -- MODE21 | |
req={2,0x21,pid} | |
end | |
res = txCAN(0, address, 0, req, 100) -- Send request | |
if res ~= 1 then return nil end | |
local data = {} | |
local id, ext, d1 = rxCAN(0,100) -- Read Response | |
if id == nil then return nil end | |
-- for r,d in ipairs(d1) do print(d..",") end | |
-- println(" ") | |
local i = 1 | |
local s = 3 | |
if d1[1] == 0x10 then s=s+1 end -- Multimessaging | |
if pid < 256 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 d1[1] ~= 0x10 then return data end -- Not multimessaging, so quit | |
-- Read multi messages | |
res = txCAN(0, address, 0, {48,8,0},100) | |
if res ~= 1 then return nil end | |
local messages = (d1[2] + 1) / 7 | |
for m=1,messages do | |
local id, ext, d1 = rxCAN(0,100) | |
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 | |
-- ========================= MAIN CYCLE ======================================= | |
local fpChan,tgtFP,chCANHz = 3,43.5,addChannel("CAN", 1, 0, 0, 300, "Hz") | |
initCAN(0, 500000) | |
setTickRate(1000) | |
for i=1,10 do rxCAN(0,5) end -- Clear CAN buffer | |
canRDmap() | |
collectgarbage() | |
function onTick() | |
local started,mc = getUptime(),0 | |
print("START") | |
while getUptime()-started < 1000 do -- Release Tick every second | |
canRDall(mc) | |
collectgarbage() | |
mc = mc + 1 | |
end | |
setChannel(chCANHz, mc) | |
--TODO: Calculated channels: | |
-- 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 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment