RegisterSearchFAQMemberlistUsergroupsLog in
Reply to topic Page 1 of 1
Multicolour Shiftx2 bar memory errors
Author Message
Reply with quote
Post Multicolour Shiftx2 bar memory errors 
The startup works for this but soon has memory errors. Are these from the multiple calls to sxSetLed or Virtual channels. The script is only 4kB. So what do I need to do to get it to run?

Code:

println("---Shift Light Twin Alert---")
sxCan=0
sxId=0
tickRate=30
sxBright=0  --0=automatic

L=7
--rpm0,rpm4=4000,6800
rpm0,rpm4=2000,4800
inc0=(rpm4-rpm0)/(L+1)
inc4=inc0/L
rpm1,rpm2,rpm3=rpm0+3*inc0,rpm0+5*inc0,rpm0+7*inc0

function sxShiftBar(rpm)
   if rpm<rpm0 then
      sxSetLed(0,L,0,0,0,0)
   elseif rpm<rpm1 then
      n=math.floor((rpm-rpm0)/inc0+1)
      sxSetLed(0,n,0,255,0,0) --green
      sxSetLed(n,L-n,0,0,0,0)
   elseif rpm<rpm2 then
      n=math.floor((rpm-rpm1)/inc0+1)
      sxSetLed(0,3,0,255,0,0) --green
      sxSetLed(3,n,255,255,0,0) --yellow
      sxSetLed(n+3,L-n-3,0,0,0,0)
   elseif rpm<rpm3 then
      n=math.floor((rpm-rpm2)/inc0+1)
      sxSetLed(0,3,0,255,0,0) --green
      sxSetLed(3,2,255,255,0,0) --yellow
      sxSetLed(5,n,255,0,0,0) --red
      sxSetLed(n+5,L-n-5,0,0,0,0)
   elseif rpm<rpm4 then
      n=math.floor((rpm-rpm3)/inc4+1)
      sxSetLed(0,n,255,255,255,0) --white
      sxSetLed(n,L-n,255,0,0,0)
   else
      sxSetLed(0,L,255,0,0,5) --red flash
   end
end

st,stend=0,7000/30

--Virtual Channel ID's
IDopr = addChannel("Pres-rpm",25,0,0,30,"psi")
--IDkph = addChannel("KPH",25,0,0,300,"kph")
--IDcnr = addChannel("CnR",25,0,0,300,"m")
--IDcmb = addChannel("AccComb",25,0,0,3,"g")

function sxOnUpdate()
   if st<stend then
      --Startup Sequence
      if st<stend/2 then
         ut=st/stend*2.2
      else
         ut=(stend-st)/stend*2.2
      end
      sxShiftBar(rpm4*ut)
      sxUpdateAlert(0, 150*ut)
      sxUpdateAlert(1, 50*ut)
      st=st+1
   else
      rpm=getChannel("RPM")
      if rpm==nil then rpm=100 end
      sxShiftBar(rpm)
      oilp=getAnalog(0)
      sxUpdateAlert(1, oilp) --lhs alert
      sxUpdateAlert(0, getChannel("OilTemp")) --rhs Alert

      --update Virtual Channels
      if rpm>0 then setChannel(IDopr,oilp/rpm*1000) end
      --setChannel(IDkph,getGpsSpeed()*1.60934)
      --setChannel(IDcnr,getGpsSpeed()^2/getImu(0)*0.020378)
      --setChannel(IDcmb,math.sqrt(getImu(0)^2+getImu(1)^2))
   end
end

function sxOnInit()
   --configure first alert (right LED) as engine temp
   sxSetAlertThresh(0,0,  0, 70,240,240,0) --cyan
   sxSetAlertThresh(0,1, 60,  0,255,  0,0) --l.green
   sxSetAlertThresh(0,2, 95,255,165,  0,0) --yellow
   sxSetAlertThresh(0,3,115,255,  0,  0,0) --red
   sxSetAlertThresh(0,4,120,255,  0,  0,5) --flash

   --configure second alert (left LED) as oil pressure
   sxSetAlertThresh(1,0, 0,255,  0,  0,5) --red flash
   sxSetAlertThresh(1,1,15,255,165,  0,0) --yellow
   sxSetAlertThresh(1,2,20,  0,255,  0,0) --green
   sxSetAlertThresh(1,3,60,230,140, 50,0) --orange

end

function sxOnBut(b)
   println('button: ' ..b)
end

---ShiftX2 functions---

function sxSetLed(i,l,r,g,b,f)
   sxTx(10,{i,l,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 sxInit()
   println('config shiftX2')
   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

---End Shiftx2 functions---

function onTick()
    sxProcess()
    collectgarbage()
end

sxCanId = 0xE3600 + (256 * sxId)
println('shiftx2 base id ' ..sxCanId)

setTickRate(tickRate)
sxInit()


View user's profile Send private message
Reply with quote
Post  
Try eliminating your global variables and just hardcode the RPM values and so on.

Also, in your onTick() function you can try adding calling the garbage collector, to ensure Lua has cleaned up all available memory:


function onTick()
collectgarbage()

...
...

end

Hope this helps!


_________________
Brent Picasso
Founder, Autosport Labs
Facebook | Twitter
View user's profile Send private message Send e-mail
Reply with quote
Post Lua Newbie 
Found there was a bit of a learning curve for the RC Lua Scripting. Very annoying to debug but it's very flexible and worthwhile. Really like that the ShiftX2 Leds are individually controllable. Brentp, I didn't want to hard code the rpm as I wanted it adjustable. Maybe fixed shift lights is all I need, I'll find out Sunday. Think code below is working I need to fit in a trial before Sunday.

Here are some Newbie things that helped me:

- Using SciTE on windows for scripting. Can't run scripts but gives line numbers to interpret debug warnings and it is far easier and quicker than doing it through the Windows app.

- Cut and pasting code between it and RC

- Memory errors: Avoid Global variables, Reduce function calls, use local variables, garbage collection and sometimes need to delete script and reset RC.

- Not all the Lua functions are available along with custom RC functions. The reduced Lua on the RC needs a link to reference guide.

- Debugging messages aren't very verbose.

- 'nil' values in variables or function returns can cause issues.

- Where you can test small snipets in SciTE, or cut and past small trials into RC. Mst code can only run on RC.

- OBD and Analog are easy. CAN is to if you have the ID's. Scanning CAN is possible to.

I think this code is now working. Temptation is to keep fiddling but I do need to focus on driving. The overhead of controlling individual Leds doesn't seem to bad. Though offloading this to the ShiftX2 functions would be better.

Next things I might look at:
- Add multiple warning sources on the 2 warning lights.
- I have the button acting as mode switch, so might add road mode to disable logging or predictive timer mode.
- Tidying it up, it's full of hit and miss coding.

Code:

println("--OilP--Shift Bar--Temp--")
--By: S.S.Nash Sept'18
--ShiftX2 3/2/2 Shift Bar with Shift point flash
--by Direct control of Leds
--State change on ShiftX2 button
--Virtual Channels
--ShiftX2 Led numbers [9] [0,1,2,3,4,5,6,7] [8]

local sxCan=0
local sxId=0
local tickRate=25
local sxBright,sxScale=0,50  --0=automatic, Scaling

--local rpm0,rpm1,rpm2=4050,6500,7200
local rpm0,rpm1,rpm2=4000,6300,7000
local inc0,inc1=(rpm1-rpm0)/7,(rpm2-rpm1)/7
local State=0
local function sxOnBut(b)
   if b==1 then
      State=(State+1)%2
      if State==0 then
         rpm0,rpm1,rpm2=4000,6300,7000
         sxTx(10,{State,1,255,0,0,0}) --signal State change
      elseif State==1 then
         rpm0,rpm1,rpm2=2050,4500,5200
         sxTx(10,{State,1,0,255,0,0}) --signal State change
      end
      --println('button: ' ..b.." State:"..State%2)
      inc0,inc1=(rpm1-rpm0)/7,(rpm2-rpm1)/7
      println("Shift:"..rpm0..",["..inc0.."],"..rpm1..",["..inc1.."],"..rpm2)
      sleep(150)
   end
end


--Virtual Channel ID's
local IDopr = addChannel("Pres-rpm",25,1,0,30,"psi")
local IDkph = addChannel("KPH",25,0,0,300,"kph")
local IDcnr = addChannel("CnR",25,0,0,300,"m")
local IDcmb = addChannel("AccComb",25,2,0,3,"g")

local function sxShiftBar(rpm)
    local n
    if rpm<rpm0 then
        sxTx(10,{0,7,0,0,0,0})
    elseif rpm<rpm1 then
        n=math.floor((rpm-rpm0)/inc0+1)
        if n<=3 then
            sxTx(10,{0,n  ,  0,255,  0,0}) --green
        elseif n<=5 then
            sxTx(10,{3,n-3,255,128,  0,0}) --yellow
            --if n==5 then -- reset on rev drop
            --    sxTx(10,{0,3  ,  0,255,  0,0}) --green
            --end
        elseif n<=7 then
            if n==7 then -- reset on rev drop
                sxTx(10,{0,3  ,  0,255,  0,0}) --green
                sxTx(10,{3,2  ,255,128,  0,0}) --yellow
            end
            sxTx(10,{5,n-5,255,  0,  0,0}) --red
        end
    if n<7 then sxTx(10,{n,7-n,0,0,0,0}) end
    elseif rpm<rpm2 then
        n=math.floor((rpm-rpm1)/inc1+1)
        sxTx(10,{0,n,255,255,255,0}) --white
        if n<7 then sxTx(10,{n,7-n,255,0,0,0}) end
    else
        sxTx(10,{0,7,255,0,0,10}) --red flash
    end
    --if n~=nil then print(math.floor(rpm)..":"..n.." ") end
end

local st=0
local rpml=0
local function sxOnUpdate()
    local ut
    local stend=4000/30
    if st<stend then
        --Startup Sequence--
        if st<stend/2 then
            ut=st/stend*2.2
        else
            ut=(stend-st)/stend*2.2
        end
        sxShiftBar(rpm0+(rpm2-rpm0)*ut)
        sxUpdateAlert(0, 150*ut)
        sxUpdateAlert(1, 20*ut)
        st=st+1
        --print(math.floor(rpm2*ut).." ")
    else
      --println("--Start ShiftX2--")
      local kph=getGpsSpeed()*1.60934
      local rpm=getChannel("RPM")
        local oilp=getAnalog(0)
      local t1=getChannel("OilTemp")
      local gx,gy=getImu(0),getImu(1)
        if rpm==nil then rpm=rpml else rpml=rpm end
      --local t1,t2,t3=getChannel("OilTemp"),getAnalog(1),getChannel("Coolant")
        --update Virtual Channels
        if rpm>0 then setChannel(IDopr,math.min(40,oilp/rpm*1000)) end
        setChannel(IDkph,kph)
        setChannel(IDcnr,math.min(300,kph^2/math.abs(gx)*0.007868))
        setChannel(IDcmb,math.sqrt(gx^2+gy^2))
        --update Alerts
        sxShiftBar(rpm)
        sxUpdateAlert(1, oilp/rpm*1000)     --LHS Alert
        sxUpdateAlert(0, t1) --RHS Alert
        --sxUpdateAlert(0, math.max(t1,t2,t3)) --RHS Alert
    end
end

---ShiftX2 functions---

function sxSetAlertThresh(id,tid,th,r,g,b,f)
    sxTx(21,{id,tid,spl(th),sph(th),r,g,b,f})
end

function sxUpdateAlert(id,v)
    if v~=nil then sxTx(22,{id,spl(v),sph(v)}) end
end

function sxInit()
    println('config shiftX2')
    --setBaseConfig(sxBright,sxScale)
    sxTx(3,{sxBright,sxScale})

   --sxOnInit()
    --configure first alert (right LED) as engine temp
    sxSetAlertThresh(0,0,  0, 70,240,240,0) --cyan
    sxSetAlertThresh(0,1, 60,  0,255,  0,0) --l.green
    sxSetAlertThresh(0,2,110,255,128,  0,0) --yellow
    sxSetAlertThresh(0,3,120,255,  0,  0,0) --red
    sxSetAlertThresh(0,4,125,255,  0,  0,10) --flash
    --configure second alert (left LED) as oil pressure
    sxSetAlertThresh(1,0,  0,255,  0,  0,10) --red flash
    sxSetAlertThresh(1,1,7.5,255,128,  0,0) --yellow
    sxSetAlertThresh(1,2,15,  0,255,  0,0) --green
    --sxSetAlertThresh(1,3,30,255,128,  0,0) --orange
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

---End Shiftx2 functions---

function onTick()
   --local ut=getUptime()
    collectgarbage()
    --sxProcess()
    --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

    if sxOnUpdate~=nil then sxOnUpdate() end
   --println(string.format("Duty time: %f",getUptime()-ut))
end

sxCanId = 0xE3600 + (256 * sxId)
println('shiftx2 base id ' ..sxCanId)

setTickRate(tickRate)
sxInit()



View user's profile Send private message
Display posts from previous:
Reply to topic Page 1 of 1
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum