The Kpro4 supports CAN and the protocol is well documented on the hondata website and kpro help file. Below is a script that implements logging of most of the KPro CAN output. I left a few out that i don't need, but it is trivial to add to the script. You can upgrade your older Kpro to the new Kpro4 for $250, well worth it. This works like a champ!
Code: Select all
--This example configured for E46 CAN, adopted to Hondata KPro4 CAN output
--how frequently we poll for CAN messages, 30Hz is the max
tickRate = 30
--the CAN baud rate
CAN_baud = 250000
--CAN channel to listen on. 0=first CAN channel, 1=second
CAN_chan = 0
--1 for Big Endian (MSB) mode; 0 for Little Endian mode (LSB)
be_mode = 1
--add your virtual channels here
rpmId = addChannel("RPM", 10, 0, 0, 9000, "RPM")
vltId = addChannel("VLT", 10, 1, 0, 20, "volts")
iatId = addChannel("IAT", 1, 0, 0, 100, "C")
ectId = addChannel("ECT", 1, 0, 0, 150, "C")
tpsId = addChannel("TPS", 10, 0, 0, 100, "%")
mapId = addChannel("MAP", 10, 1, 0, 15, "PSI")
injId = addChannel("INJ", 10, 3, 0, 100, "ms")
ignId = addChannel("IGN", 10, 0, -20, 20, "D")
lmdId = addChannel("LMD", 10, 3, 0, 2, "lambda")
knkId = addChannel("KNK", 1, 0, 0, 15, "count")
camId = addChannel("CAM", 10, 0, -20, 20, "D")
--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) end,
[1633] = function(data) map_chan(iatId, data, 0, 2, 1, 0) map_chan(ectId, data, 2, 2, 1, 0) end,
[1634] = function(data) map_chan(tpsId, data, 0, 2, 1, 0) map_chan(mapId, data, 2, 2, 0.0145037738, 0) end,
[1635] = function(data) map_chan(injId, data, 0, 2, 0.001, 0) map_chan(ignId, data, 2, 2, 1, 0) end,
[1636] = function(data) map_chan(lmdId, data, 0, 2, 0.00003051757, 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)
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, little endian format
function map_chan_le(cid, data, offset, len, mult, add)
offset = offset + 1
local value = 0
local shift = 1
while len > 0 do
value = value + (data[offset] * shift)
shift = shift * 256
offset = offset + 1
len = len - 1
end
setChannel(cid, (value * mult) + add)
end
--Map CAN channel, big endian format
function map_chan_be(cid, data, offset, len, mult, add)
offset = offset + 1
local value = 0
while len > 0 do
value = (value * 256) + data[offset]
offset = offset + 1
len = len - 1
end
setChannel(cid, (value * mult) + add)
end
map_chan = (be_mode == 1) and map_chan_be or map_chan_le
initCAN(CAN_chan, CAN_baud)
setTickRate(tickRate)