Linear graph script/behavior

Q&A For ShiftX2, RGB sequential shift light <a href="https://wiki.autosportlabs.com/ShiftX2">Installation and Operation Guide</a>
Post Reply
psfp
Posts: 49
Joined: Mon Aug 21, 2017 10:40 pm
Location: DF - Brazil

Linear graph script/behavior

Post by psfp »

Hi guys,

I'm using a 1000 to 2000 rpm range to test my ShiftX2 in my garage, but when I reach the first threshold, the first 4 leds light up at the same time. I was expecting a smooth transition from the very first led.

See a video in the link below:

https://youtu.be/w1ct4EyeX4s

Here is my script:

Code: Select all

sxTx&#40;40,&#123;0,0,0,0,0,1&#125;&#41;
sxTx&#40;41,&#123;0,0,128,0,0,255,0,0&#125;&#41; --green at 1000 RPM
sxTx&#40;41,&#123;1,0,192,0,255,255,0,0&#125;&#41; --yellow at 1500 RPM
sxTx&#40;41,&#123;2,0,0,1,255,0,0,10&#125;&#41; --flashing red at 2000 RPM

local function updateShiftX2&#40;&#41;
    sxTx&#40;42,&#123;vRPM_L,vRPM_H&#125;&#41;
end
No bitwise operation, as the RPM data is already separated in two bytes when I get it.

The formula to convert the raw value to RPM is RPM = raw * 125/16

I tried to use different values in the low range areas of linear graph configuration (CAN id + 40), but I had no luck.

Any ideas?

TXBDan
Posts: 69
Joined: Sat Mar 25, 2017 1:43 am

Post by TXBDan »

Mine behaves the same and I also wonder why. That said I've never had a real/pro type shift light. Maybe that's how they work? I'd still like more information in the green zone though and I think having more leds sequence would be better.

brentp
Site Admin
Posts: 6281
Joined: Wed Jan 24, 2007 6:36 am

Post by brentp »

Hi , can you post your full script so we can check it out?

If you want the LED to show up at the first segment, try setting your first threshold at 0 RPM.
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

psfp
Posts: 49
Joined: Mon Aug 21, 2017 10:40 pm
Location: DF - Brazil

Post by psfp »

Hi Brent,

I got it "fixed". Now the shift light represents the 4000 to 7000 range. The first LED turns on at 4000 rpm. Anything below 4000 rpm is ignored by the script.

Basically, the ShiftX2 is configured to work from 0 to 3000 rpm and my script converts the RPM value by subtracting 4000 from the real value. If RPM is below 4000, ShiftX2 receives 0 as value.

Here is my full script, before minifier and using a static oil pressure value as temporary solution, because I didn't have time to install the sensor. Sorry about the comments in portuguese.

Code: Select all

--======================================================Main data======================================================
--Inicializa CAN e define TickRate==

collectgarbage&#40;&#41;

--println&#40;"start.."..collectgarbage&#40;"count"&#41;*1024&#41;

initCAN&#40;0, 500000&#41;
initCAN&#40;1, 500000&#41;
setTickRate&#40;50&#41;
sleep&#40;5000&#41;

--==Declaracao de variaveis==

local vIPW, vRPM_H, vRPM_L, vRPM, vCoolant, vSSTTemp, vBoost = 0,0,0,0,0,0,0

--==Linha comentada traz todos os canais de RAX. Linha seguinte traz apenas os utilizados==
--local cSTFT, cLTFTcurrent, cLTFTidle, cLTFTcruise, cLoad, cAFR, cIPW, cAFRMAP, cLoadTiming, cTiming, cKnock, cRPM, cIDC, cBaro, cMAP, cBoost, cWGDC, cMAF, cInVVTtarget, cInVVTcurr, cExVVTtarget, cExVVTcurr, cTPS, cAPP, cIAT, cWGDCcorr, cSpeed, cBatteryECU, cCoolant, cMAT, cMAPcalc, cIMAPcalc, cMAFcalc, cChosenCalc, cSSTTemp

local cSTFT, cLTFTcurrent, cLTFTidle, cLTFTcruise, cLoad, cAFR, cIPW, cAFRMAP, cLoadTiming, cTiming, cKnock, cRPM, cIDC, cBaro, cMAP, cBoost, cWGDC, cMAF, cTPS, cAPP, cIAT, cWGDCcorr, cSpeed, cBatteryECU, cCoolant, cMAT, cMAPcalc, cIMAPcalc, cMAFcalc, cChosenCalc, cSSTTemp

--==Variaveis de canal auxiliar para acompanhamento de taxa de atualizacao==

--local counter = 0
--local cRefresh = addChannel&#40;"Refresh", 50,0&#41;

--==Criacao de canais RAX==

--==RAX A==

cSTFT = addChannel&#40;"STFT", 50,2&#41;
cLTFTcurrent = addChannel&#40;"LTFTcurrent", 50,2&#41;
cLTFTidle = addChannel&#40;"LTFTidle", 50,2&#41;
cLTFTcruise = addChannel&#40;"LTFTcruise", 50,2&#41;

--==RAX B==

cLoad = addChannel&#40;"Load", 50,2&#41;
cAFR = addChannel&#40;"AFR", 50,2&#41;
cIPW = addChannel&#40;"IPW", 50,1&#41;
cAFRMAP = addChannel&#40;"AFRMAP", 50,2&#41;

--==RAX C==

cLoadTiming = addChannel&#40;"LoadTiming", 50,2&#41;
cTiming = addChannel&#40;"Timing", 50,0&#41;
cKnock = addChannel&#40;"Knock", 50,0,0,20,"count"&#41;
cRPM = addChannel&#40;"RPM",50,0,0,8000,"RPM"&#41;
cIDC = addChannel&#40;"IDC", 50,1&#41;

--==RAX D==

cBaro = addChannel&#40;"Baro", 50,2&#41;
cMAP = addChannel&#40;"MAP", 50,2&#41;
cBoost = addChannel&#40;"Boost", 50,2&#41;
cWGDC = addChannel&#40;"WGDC", 50,1&#41;
cMAF = addChannel&#40;"MAF", 50,2&#41;

--==RAX E==

--cInVVTtarget = addChannel&#40;"InVVTtarget", 50,1&#41;
--cInVVTcurr = addChannel&#40;"InVVTcurr", 50,1&#41;
--cExVVTtarget = addChannel&#40;"ExVVTtarget", 50,1&#41;
--cExVVTcurr = addChannel&#40;"ExVVTcurr", 50,1&#41;

--==RAX F==

cTPS = addChannel&#40;"TPS", 50,1&#41;
cAPP = addChannel&#40;"APP", 50,1&#41;
cIAT = addChannel&#40;"IAT", 50,0&#41;
cWGDCcorr = addChannel&#40;"WGDCcorr", 50,1&#41;

--==RAX G==

cSpeed = addChannel&#40;"Speed", 50,0&#41;
cBatteryECU = addChannel&#40;"BatteryECU", 50,2&#41;
cCoolant = addChannel&#40;"Coolant", 50,0&#41;
cMAT = addChannel&#40;"MAT", 50,0&#41;

--==RAX H==

cMAPcalc = addChannel&#40;"MAPcalc", 50,2&#41;
cIMAPcalc = addChannel&#40;"IMAPcalc", 50,2&#41;
cMAFcalc = addChannel&#40;"MAFcalc", 50,2&#41;
cChosenCalc = addChannel&#40;"ChosenCalc", 50,2&#41;

--==Criacao de canais SST==

--println&#40;"after rax.."..collectgarbage&#40;"count"&#41;*1024&#41;

cSSTTemp = addChannel&#40;"SSTTemp",1,0&#41;

--==Funcao para fazer a chamada e receber os valores de RAX==

local function getRAXCAN&#40;RAXaddress&#41;
    local res, id, ext, data
    res = txCAN&#40;0,2016,0,&#123;5,35,128,81,RAXaddress,4,255,255&#125;,100&#41;
    if res == 1 then
        id,ext,data = rxCAN&#40;0,100&#41;
    else
        data = nil
    end
    return data
end

--println&#40;"aftersst.."..collectgarbage&#40;"count"&#41;*1024&#41;

--==Rotina para atualizar os canais RAX==

local function getRAX&#40;&#41;

    local data,vMAP,vBaro

    --==RAX A==

    data = getRAXCAN&#40;172&#41;
    if data ~= nil then
        setChannel&#40;cSTFT,&#40;data&#91;3&#93;* 25/128&#41;-25&#41;
        setChannel&#40;cLTFTcurrent,&#40;data&#91;4&#93;* 25/128&#41;-25&#41;
        setChannel&#40;cLTFTidle,&#40;data&#91;5&#93;* 25/128&#41;-25&#41;
        setChannel&#40;cLTFTcruise,&#40;data&#91;6&#93;* 25/128&#41;-25&#41;
    end

    --==RAX B==

    data = getRAXCAN&#40;168&#41;
    if data ~= nil then
        setChannel&#40;cLoad,data&#91;3&#93;*25/16&#41;
        setChannel&#40;cAFR,data&#91;6&#93;*0.0392+9.8&#41;
        vIPW = data&#91;4&#93;/10
        setChannel&#40;cIPW,vIPW&#41;
        setChannel&#40;cAFRMAP,&#40;14.7*128&#41;/data&#91;5&#93;&#41;
    end

    --==RAX C==

    data = getRAXCAN&#40;176&#41;
    if data ~= nil then
        --data&#91;6&#93; = data&#91;6&#93; + &#40;&#40;data&#91;5&#93;%8&#41;*256&#41; Esta linha traz a definicao antes da separacao em High e Low Byte para Shift Light
        vRPM_H = data&#91;5&#93;%8
        vRPM_L = data&#91;6&#93;
        data&#91;5&#93; = math.floor&#40;data&#91;5&#93;/8&#41; + &#40;&#40;data&#91;4&#93;%2&#41;*32&#41;
        data&#91;4&#93; = math.floor&#40;data&#91;4&#93;/2&#41;
        vRPM = &#40;&#40;vRPM_H*256&#41;+vRPM_L&#41;*125/16
        setChannel&#40;cLoadTiming,data&#91;3&#93;* 25/16&#41;
        setChannel&#40;cTiming,data&#91;4&#93; - 20&#41;
        setChannel&#40;cKnock,data&#91;5&#93;&#41;
        setChannel&#40;cRPM,vRPM&#41;
        setChannel&#40;cIDC,vIPW*vRPM/1200&#41;
    end

    --==RAX D==

    data = getRAXCAN&#40;180&#41;
    if data ~= nil then
        data&#91;3&#93; = &#40;data&#91;3&#93;*2&#41; + math.floor&#40;data&#91;4&#93;/128&#41;
        if data&#91;4&#93; > 128 then
            data&#91;4&#93; = data&#91;4&#93; - 128
        end
        vMAP = data&#91;3&#93;* 0.096487
        vBaro = &#40;data&#91;4&#93;+90&#41;* 0.072519
        vBoost = vMAP - vBaro
        setChannel&#40;cBaro,vBaro&#41;
        setChannel&#40;cMAP,vMAP&#41;
        setChannel&#40;cBoost,vBoost&#41;
        setChannel&#40;cWGDC,data&#91;5&#93;/2&#41;
        setChannel&#40;cMAF,data&#91;6&#93;*5/255&#41;
    end

    --==RAX E==

    --    data = getRAXCAN&#40;184&#41;
    --    if data ~= nil then
    --        setChannel&#40;cInVVTtarget,&#40;data&#91;3&#93;-16&#41;*5/32&#41;
    --        setChannel&#40;cInVVTcurr,&#40;data&#91;5&#93;-16&#41;*5/32&#41;
    --        setChannel&#40;cExVVTtarget,&#40;16-data&#91;4&#93;&#41;*5/32&#41;
    --        setChannel&#40;cExVVTcurr,&#40;16-data&#91;6&#93;&#41;*5/32&#41;
    --    end

    --==RAX F==

    data = getRAXCAN&#40;188&#41;
    if data ~= nil then
        setChannel&#40;cTPS,data&#91;3&#93;*100/255&#41;
        setChannel&#40;cAPP,&#40;data&#91;4&#93;-32&#41;*129/255&#41;
        setChannel&#40;cIAT,data&#91;5&#93;-40&#41;
        setChannel&#40;cWGDCcorr,&#40;data&#91;6&#93;/2&#41;-64&#41;
    end

    --==RAX G==

    data = getRAXCAN&#40;192&#41;
    if data ~= nil then
        vCoolant = data&#91;5&#93;-40
        setChannel&#40;cSpeed,data&#91;3&#93;*2&#41;
        setChannel&#40;cBatteryECU,data&#91;4&#93;*18.7/255&#41;
        setChannel&#40;cCoolant,vCoolant&#41;
        setChannel&#40;cMAT,data&#91;6&#93;-40&#41;
    end

    --==RAX H==

    data = getRAXCAN&#40;196&#41;
    if data ~= nil then
        setChannel&#40;cMAPcalc,data&#91;3&#93;*25/16&#41;
        setChannel&#40;cIMAPcalc,data&#91;4&#93;*25/16&#41;
        setChannel&#40;cMAFcalc,data&#91;5&#93;*25/16&#41;
        setChannel&#40;cChosenCalc,data&#91;6&#93;*25/16&#41;
    end
end

--==Rotina para atualizar os canais SST==

local function getSST&#40;&#41;
    local res, id, ext, data
    res = txCAN&#40;0, 2017, 0, &#123;2,33,51,255,255,4,255,255&#125;,100&#41;
    if res == 1 then
        id,ext,data = rxCAN&#40;0,100&#41;
    else
        data = nil
    end
    if data ~= nil then
        vSSTTemp = data&#91;4&#93;-50
        setChannel&#40;cSSTTemp,vSSTTemp&#41;
    end
end

--==Rotina para atualizar os canais analogicos e demais valores para o ShiftX2==

local function UpdateAlerts&#40;&#41;
    local AlertL, AlertR, vOilTemp, vFuelPress, vFuelTemp, vOilPress, vFuelPressDelta, OilPressWarning

    --==Alerta Esquerda==

    --vOilTemp = getAnalog&#40;5&#41;
    vOilTemp = 80

    AlertL = 1
    if &#40;vCoolant < 75 or vOilTemp < 75 or vSSTTemp < 75&#41; then AlertL = 2 end
    if &#40;vCoolant > 100 or vOilTemp > 100 or vSSTTemp > 120&#41; then AlertL = 3 end
    if &#40;vCoolant > 110 or vOilTemp > 110 or vSSTTemp > 130&#41; then AlertL = 4 end

    --==Alerta Direita==

    vFuelPress, vFuelTemp, vOilPress = getAnalog&#40;0&#41;,getAnalog&#40;1&#41;,getAnalog&#40;4&#41;
    vFuelPressDelta = vFuelPress - vBoost

    --==Explicacao da logica==
    --Oilpresswarning
    --se RPM >= 4000, Oilpress > 80
    --se RPM < 4000, Oilpress / RPM > 0.02

    OilPressWarning = false
    if vRPM >= 4000 and vOilPress < 80 then OilPressWarning = true end
    if vRPM < 4000 and vOilPress/vRPM < 0.02 then OilPressWarning = true end

    AlertR = 1
    if &#40;vFuelTemp > 45 or vFuelPressDelta < 45&#41; then AlertR = 2 end
    if &#40;vFuelTemp > 50 or vFuelPressDelta < 40 or OilPressWarning&#41; then AlertR = 3 end

    --==Retorno==
    return AlertL, AlertR

end

--======================================================Main data======================================================



--=======================================================ShiftX2=======================================================

local function sxTx&#40;offset, data&#41;
    txCAN&#40;1, 0xE3600 + offset, 1, data&#41;
    --sleep&#40;10&#41;
end

--==Inicio Configuracao de start==

--==Configuracao do Shift Light==

--Configuracao considerando inicio em 4000 RPM
sxTx&#40;40,&#123;0,0,0,0,128,1&#125;&#41; -- Corte em 7000 RPM
sxTx&#40;41,&#123;0,0,0,0,0,255,0,0&#125;&#41; --verde em 4000 RPM
sxTx&#40;41,&#123;1,0,0,1,255,255,0,0&#125;&#41; --amarelo em 6000 RPM
sxTx&#40;41,&#123;2,0,128,1,255,0,0,10&#125;&#41; --vermelho piscante em 7000 RPM


--==Configuracao do alerta da esquerda==
sxTx&#40;21,&#123;1,0,2,0,0,0,255,0&#125;&#41; --azul
sxTx&#40;21,&#123;1,1,3,0,255,255,255,0&#125;&#41; --branco
sxTx&#40;21,&#123;1,2,4,0,255,0,0,10&#125;&#41; --vermelho piscante

--==Configuracao do alerta da direita==
sxTx&#40;21,&#123;0,0,2,0,255,255,255,0&#125;&#41; --branco
sxTx&#40;21,&#123;0,1,3,0,255,0,0,10&#125;&#41; --vermelho piscante

--==Fim Configuracao de start==

--==Inicio Configuracao de update==

local function updateShiftX2&#40;&#41;

    local left, right
    left, right = UpdateAlerts&#40;&#41;
    if vRPM_H < 2 then
      sxTx&#40;42,&#123;0,0&#125;&#41;
    else
      sxTx&#40;42,&#123;vRPM_L,vRPM_H-2&#125;&#41;
    end


    sxTx&#40;22,&#123;1,left,0&#125;&#41;

    sxTx&#40;22,&#123;0,right,0&#125;&#41;

end

--==Fim Configuracao de update==

--=======================================================ShiftX2=======================================================

--println&#40;"antes de onTick.."..collectgarbage&#40;"count"&#41;*1024&#41;

--==Funcao onTick==

function onTick&#40;&#41;

    if getGpio&#40;0&#41; == 0 then startLogging&#40;&#41; else stopLogging&#40;&#41; end
    local UpTime
    getSST&#40;&#41;
    UpTime = getUptime&#40;&#41;
    repeat
        getRAX&#40;&#41;
        updateShiftX2&#40;&#41; -- Funcao do ShiftX2

        --==Linhas abaixo para canal auxiliar para acompanhamento de taxa de atualizacao==

        --setChannel&#40;cRefresh,counter&#41;
        --counter = counter + 1
        --if counter == 2000 then
        --    counter = 0
        --end

        --==Continuacao de onTick&#40;&#41;==

    until getUptime&#40;&#41; > UpTime + 1000

    collectgarbage&#40;&#41;
    --println&#40;"em onTick.."..collectgarbage&#40;"count"&#41;*1024&#41;

end
I can't run all RAX logging values because of the memory limit, so I removed the MIVEC channels. It's currently very tight. Besides that, everything seems to be running fine.

brentp
Site Admin
Posts: 6281
Joined: Wed Jan 24, 2007 6:36 am

Post by brentp »

Glad you got it working!
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

Post Reply