RegisterSearchFAQMemberlistUsergroupsLog in
Reply to topic Page 1 of 2
Goto page 1, 2  Next
Help with shift light script
Author Message
Reply with quote
Post Help with shift light script 
Hi all, I need help to get my shift light to work.

With my script, I get this error:
[lua] Script error: [string "tickrate = 30..."]:35.0: attempt to compare number with nil

If I change line 35 from "local r = rpm" to "local r = rpmId", I'm not getting any errors, but the shift light do not work.

Here is the script:
tickRate = 30
--the CAN baud rate
CAN_baud = 250000
--CAN channel to listen on. 0=first CAN channel, 1=second
CAN_chan = 0

ledState = 0
--change this to make a bigger averaging window
maxAvg = 300
--300 = 10 seconds averaging at 30Hz tick rate

--do not change
fuelAvg={}
fuel2Index = 1

--add your virtual channels here
rpmId = addChannel("RPM", 25, 0, 0, 8000, "RPM")
vltId = addChannel("EcuVolts", 10, 1, 0, 20, "volts")
gearid = addChannel("Gear", 25, 0, 0, 6)
iatId = addChannel("IAT", 1, 0, 0, 120, "F")
ectId = addChannel("EngineTemp", 1, 0, 80, 250, "F")
tpsId = addChannel("TPS", 10, 0, 0, 100, "%")
mapId = addChannel("MAP", 10, 2, -15, 25, "PSI")
injId = addChannel("InjectorPW", 10, 3, 0, 100, "ms")
ignId = addChannel("Ignition", 10, 0, -20, 20, "D")
knkId = addChannel("Knock", 1, 0, 0, 15, "count")
camId = addChannel("CamTiming", 10, 0, -20, 20, "D")
fuel2Id = addChannel("FuelLevel", 10, 0, 0,100,"%")

function toF(value)
return value * 1.8 + 32
end

function Shift()
local r = RPM
if r > 6300 then setGpio(2,1) else setGpio(2,0) end
if r > 6800 then setGpio(1,1) else setGpio(1,0) end
if r > 7300 then setGpio(0,1) else setGpio(0,0) end
end

function updateFuelAvg(value)
local i
if #fuelAvg == 0 then
--initialize averaging table
for i = 1, maxAvg do fuelAvg[i]=0 end
end
fuelAvg[fuel2Index] = value
fuel2Index = fuel2Index + 1
if fuel2Index > maxAvg then fuel2Index = 1 end
local sum = 0
for i = 1, #fuelAvg do
sum = sum + fuelAvg[i]
end
setChannel(fuel2Id, sum / maxAvg)
end

function Logging()
if getGpsSpeed() > 10 then
startLogging()
else
stopLogging()
end
end

--customize here for CAN channel mapping
--offset/length in bytes?
--format is: [CAN Id] = function(data) map_chan(<channel id>, data, <CAN offset>, <CAN length>, <multiplier>, <adder>)
CAN_map = {
--did not bother logging gear speed and target cam angle
[1632] = function(data) map_chan(rpmId, data, 0, 2, 1, 0) map_chan(vltId, data, 5, 1, 0.1, 0) map_chan(gearid, data, 0, 1, 1, 0) end,
[1633] = function(data) map_chan(iatId, data, 0, 2, 1, 0, toF) map_chan(ectId, data, 2, 2, 1, 0, toF) end,
[1634] = function(data) map_chan(tpsId, data, 0, 2, 1, 0) map_chan(mapId, data, 2, 2, 0.0145037738, -14.7) end,
[1635] = function(data) map_chan(injId, data, 0, 2, 0.001, 0) map_chan(ignId, data, 2, 2, 1, 0) end,
[1637] = function(data) map_chan(knkId, data, 0, 2, 1, 0) end,
[1638] = function(data) map_chan(camId, data, 2, 2, 1, 0) end
}

function onTick()
processCAN(CAN_chan)
Shift()
updateFuelAvg(getAnalog(0))
Logging()
end



--===========do not edit below===========
function processCAN(chan)
repeat
local id, e, data = rxCAN(chan)
if id ~= nil then
local map = CAN_map[id]
if map ~= nil then
map(data)
end
end
until id == nil
end

--Map CAN channel, big endian format
function map_chan(cid, data, offset, len, mult, add, filter)
offset = offset + 1
local value = 0
while len > 0 do
value = (value * 256) + data[offset]
offset = offset + 1
len = len - 1
end
local cv = value * mult + add
if filter ~= nil then cv = filter(cv) end
setChannel(cid, cv)
end

initCAN(CAN_chan, CAN_baud)
setTickRate(tickRate)

View user's profile Send private message
Reply with quote
Post  
Looks like your error is happening in the Shift() function.

The nil value it's complaining about is RPM, which never gets set in the script; so it's nil by default, and Lua refuses to compare a number with nil.

You can set the local RPM value by including a filter in the CAN mapping, which can call a custom function. Similar to the toF() function already being used. Example:

Code:
function setRpm(value)
RPM = value
return value
end

--customize here for CAN channel mapping
--offset/length in bytes?
--format is: [CAN Id] = function(data) map_chan(<channel id>, data, <CAN offset>, <CAN length>, <multiplier>, <adder>)
CAN_map = {
--did not bother logging gear speed and target cam angle
[1632] = function(data) map_chan(rpmId, data, 0, 2, 1, 0, setRpm) map_chan(vltId, data, 5, 1, 0.1, 0) map_chan(gearid, data, 0, 1, 1, 0) end,
[1633] = function(data) map_chan(iatId, data, 0, 2, 1, 0, toF) map_chan(ectId, data, 2, 2, 1, 0, toF) end,
[1634] = function(data) map_chan(tpsId, data, 0, 2, 1, 0) map_chan(mapId, data, 2, 2, 0.0145037738, -14.7) end,
[1635] = function(data) map_chan(injId, data, 0, 2, 0.001, 0) map_chan(ignId, data, 2, 2, 1, 0) end,
[1637] = function(data) map_chan(knkId, data, 0, 2, 1, 0) end,
[1638] = function(data) map_chan(camId, data, 2, 2, 1, 0) 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  
It kind of work, I don't get the message, but shift light are not working

View user's profile Send private message
Reply with quote
Post  
I ran other test.

When I try with a testRpm line, light works fine, but when I use the scipt for the CAN, the lights stay on the last setting I tryed with the testRpm. The RPM on the App works fine, but it looks like the script for the lights does not get the value of the RPM virtual channel. I have tryed two diffrent light script with the same results.

Any ideas LUA gurus?

View user's profile Send private message
Reply with quote
Post  
Hi, Post your latest script and we'll see if we can tease anything out of it.


_________________
Brent Picasso
Founder, Autosport Labs
Facebook | Twitter
View user's profile Send private message Send e-mail
Reply with quote
Post  
Here it is

tickRate = 30
--the CAN baud rate
CAN_baud = 250000
--CAN channel to listen on. 0=first CAN channel, 1=second
CAN_chan = 0

--virtual channels
--addChannel( name, sampleRate, [precision], [min], [max], [units] )
rpmId = addChannel("RPM", 100, 0, 0, 8000, "RPM")
vltId = addChannel("EcuVolts", 10, 1, 0, 20, "volts")
gearid = addChannel("Gear", 25, 0, 0, 6)
iatId = addChannel("IAT", 1, 0, 0, 120, "F")
ectId = addChannel("EngineTemp", 1, 0, 80, 250, "F")
tpsId = addChannel("TPS", 10, 0, 0, 100, "%")
mapId = addChannel("MAP", 10, 2, -15, 25, "PSI")
injId = addChannel("InjectorPW", 10, 3, 0, 100, "ms")
ignId = addChannel("Ignition", 10, 0, -20, 20, "D")
knkId = addChannel("Knock", 1, 0, 0, 15, "count")
camId = addChannel("CamTiming", 10, 0, -20, 20, "D")
fuel2Id = addChannel("FuelLevel", 10, 0, 0,100,"%")

function toF(value)
return value * 1.8 + 32
end

function setRpm(value)
RPM = value
return value
end

--testRPM = 2301
function Shift()
local r = RPM
if r > 1300 then setGpio(1,1) else setGpio(1,0) end
if r > 1800 then setGpio(0,1) else setGpio(0,0) end
if r > 2300 then setGpio(2,1) else setGpio(2,0) end
end

--offset/length in bytes?
--format is: [CAN Id] = function(data) map_chan(<channel id>, data, <CAN offset>, <CAN length>, --<multiplier>, <adder>)
CAN_map = {
[1632] = function(data) map_chan(rpmId, data, 0, 2, 1, 0, setRpm) map_chan(vltId, data, 5, 1, 0.1, 0) map_chan(gearid, data, 0, 1, 1, 0) end,
[1633] = function(data) map_chan(iatId, data, 0, 2, 1, 0, toF) map_chan(ectId, data, 2, 2, 1, 0, toF) end,
[1634] = function(data) map_chan(tpsId, data, 0, 2, 1, 0) map_chan(mapId, data, 2, 2, 0.0145037738, -14.7) end,
[1635] = function(data) map_chan(injId, data, 0, 2, 0.001, 0) map_chan(ignId, data, 2, 2, 1, 0) end,
[1637] = function(data) map_chan(knkId, data, 0, 2, 1, 0) end,
[1638] = function(data) map_chan(camId, data, 2, 2, 1, 0) end
}

function onTick()
--RPM=testRPM
processCAN(CAN_chan)
Shift()
end



--===========do not edit below===========
function processCAN(chan)
repeat
local id, e, data = rxCAN(chan)
if id ~= nil then
local map = CAN_map[id]
if map ~= nil then
map(data)
end
end
until id == nil
end

--Map CAN channel, big endian format
function map_chan(cid, data, offset, len, mult, add, filter)
offset = offset + 1
local value = 0
while len > 0 do
value = (value * 256) + data[offset]
offset = offset + 1
len = len - 1
end
local cv = value * mult + add
if filter ~= nil then cv = filter(cv) end
setChannel(cid, cv)
end

initCAN(CAN_chan, CAN_baud)
setTickRate(tickRate)

View user's profile Send private message
Reply with quote
Post  
Does someone as a clue to what I'm doying wrong?

View user's profile Send private message
Reply with quote
Post  
A couple things:

Does your RPM show up on the dashboard when you select RPM? I didn't see anything passing the RPM value back to the channel.

Try these changes:

function setRpm(value)
RPM = value
setChannel(rpmId, RPM)
end


function onTick()
processCAN(CAN_chan)
Shift()
end

View user's profile Send private message
Reply with quote
Post  
boggie1688 wrote:
A couple things:

Does your RPM show up on the dashboard when you select RPM? I didn't see anything passing the RPM value back to the channel.

Try these changes:

function setRpm(value)
RPM = value
setChannel(rpmId, RPM)
end


function onTick()
processCAN(CAN_chan)
Shift()
end


Yes, the RPM on the tablet is working fine.

I will try your changes and see if it works.

View user's profile Send private message
Reply with quote
Post  
PopKorn78 wrote:
boggie1688 wrote:
A couple things:

Does your RPM show up on the dashboard when you select RPM? I didn't see anything passing the RPM value back to the channel.

Try these changes:

function setRpm(value)
RPM = value
setChannel(rpmId, RPM)
end


function onTick()
processCAN(CAN_chan)
Shift()
end


Yes, the RPM on the tablet is working fine.

I will try your changes and see if it works.


Sorry, I looked back at my edits and realized this won't work.

The idea is that the can_map passes a value to setRpm. You should try to add a print to see what value you are actually getting inside the setRpm function. You can even at print functions inside your shift function too. Check to see what value is getting passed in and make sure it matches what you expect.

Last idea:
Take out the shift() in your ontick.
Make your setRPM() function call your shift() function.

function setRpm(value)
RPM = value
shift(RPM)
end

function shift(RPM)
local r = RPM
if r > 1300 then setGpio(1,1) else setGpio(1,0) end
if r > 1800 then setGpio(0,1) else setGpio(0,0) end
if r > 2300 then setGpio(2,1) else setGpio(2,0) end
end

Then shift is automatically done in conjunction with your processCan().

View user's profile Send private message
Reply with quote
Post  
Thanks, will try that.

Can you give me an example for the print for the RPM please? I tried it once, but could not get it to work. Real newb at LUA here

View user's profile Send private message
Reply with quote
Post  
PopKorn78 wrote:
Thanks, will try that.

Can you give me an example for the print for the RPM please? I tried it once, but could not get it to work. Real newb at LUA here


I'm learning too.

Printing is the easiest way to make sure values are getting passed into the function.

The print command is used like this:
println()

println("hello") will echo hello when you poll the log.
println(RPM) will echo the value of the variable RPM when you poll the log.


The other thing to remember is when you call a function, ie shift(). The value inside parenthesis is passed to the function.

For example:
function setRpm(value)
RPM = 5
shift(RPM)
end

The above function is passing the value RPM to the function shift(). That value is 5. Now you can actually define what is received by the function as a new variable. That variable is then carried into the function. For example:

function shift(rpm2)
local r = rpm2
if r > 1300 then setGpio(1,1) else setGpio(1,0) end
if r > 1800 then setGpio(0,1) else setGpio(0,0) end
if r > 2300 then setGpio(2,1) else setGpio(2,0) end
end

shift(RPM) calls the function shift(), and copies the value of RPM to a variable rpm2. That variable is carried as rpm2 through the entire function. Remember RPM = 5, therefore rpm2 = 5.

I'm not 100% sure how the can_map function shares a variable with setRpm(), but the setRpm() function is called from inside can_map. The function setRpm() is setup to receive a variable, and store it to "value". I'd add a print command inside setRpm to see what that value actually is and whether or not it even has anything to do with RPM.

function setRpm(value)
println(value)
RPM = value
shift(RPM)
end

Again, not a programmer at all, just what I've gathered in the last week from play around with the RCP3.

View user's profile Send private message
Reply with quote
Post  
Good news, light works.

Bad news, I lost RPM on the tablet

View user's profile Send private message
Reply with quote
Post  
Post the scrip.

Probably need this:
setChannel(rpmId, RPM)

Add it to the end of setRpm().

View user's profile Send private message
Reply with quote
Post  
Got it to work, needed to add a return value.

Now I need to figure out a way to have the lights to blink 😄

Thanks for the help

View user's profile Send private message
Display posts from previous:
Reply to topic Page 1 of 2
Goto page 1, 2  Next
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