Help with shift light script
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=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
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)
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=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
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)
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:
Hope this helps!
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: Select all
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
}
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?
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?
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)
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)
-
- Posts: 138
- Joined: Fri Apr 07, 2017 3:47 pm
- Location: Oakland, CA
Yes, the RPM on the tablet is working fine.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
I will try your changes and see if it works.
-
- Posts: 138
- Joined: Fri Apr 07, 2017 3:47 pm
- Location: Oakland, CA
Sorry, I looked back at my edits and realized this won't work.PopKorn78 wrote:Yes, the RPM on the tablet is working fine.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
I will try your changes and see if it works.
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().
-
- Posts: 138
- Joined: Fri Apr 07, 2017 3:47 pm
- Location: Oakland, CA
I'm learning too.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
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.
-
- Posts: 138
- Joined: Fri Apr 07, 2017 3:47 pm
- Location: Oakland, CA