Last active
January 26, 2020 18:12
-
-
Save brentpicasso/982ec5de85066b82c92e to your computer and use it in GitHub Desktop.
E46 expanded channels using 2.8.7 firmware and bitOp library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--This example configured for E46 CAN | |
-- Automatically starts logging with engine 'on' (RPM triggered) | |
--how frequently we poll for CAN messages | |
tickRate = 30 | |
--the CAN baud rate | |
CAN_baud = 500000 | |
--CAN channel to listen on. 0=first CAN channel, 1=second | |
CAN_chan = 0 | |
--add your virtual channels here | |
--format addChannel(<name>, <sample rate>, <precision>, <min>, <max>, [units]) | |
tpsId = addChannel("TPS", 10, 0, 0, 100, "%") | |
tempId = addChannel("EngineTemp", 1, 0, 0, 255, "F") | |
oilTempId = addChannel("OilTemp", 1, 0, 0, 255, "F") | |
rpmId = addChannel("RPM", 10, 0, 0, 10000) | |
steerId = addChannel("Steering", 10, 0, -360, 360, "Deg.") | |
brakeId = addChannel("BrakeSw", 10, 0, 0, 1) | |
brakePressId = addChannel("Brake", 10, 0, 0, 255, "Bar") | |
clutchId = addChannel("Clutch", 10, 0, 0, 1) | |
lfWheelId = addChannel("LFWheelSpd", 10, 0, 0, 200, "MPH") | |
rfWheelId = addChannel("RFWheelSpd", 10, 0, 0, 200, "MPH") | |
lrWheelId = addChannel("LRWheelSpd", 10, 0, 0, 200, "MPH") | |
rrWheelId = addChannel("RRWheelSpd", 10, 0, 0, 200, "MPH") | |
gearTempId = addChannel("GearboxTmp", 10, 0, 0, 400, "F") | |
fuelId = addChannel("Fuel", 1, 0, 0, 100, "%") | |
extTempId = addChannel("ExtTemp", 1, 0, 0, 120,"F") | |
--Convert C to F | |
function toF(value) | |
return value * 1.8 + 32 | |
end | |
--E46 TPS, correct your throttle here for true 100% | |
function e46_tps(value) | |
return value + 0.0 | |
end | |
--only start logging / telemetry if engine is running | |
function rpmFilter(value) | |
if value > 500 then startLogging() else stopLogging() end | |
return value | |
end | |
function brakeFilter(value) | |
return bit.rshift(bit.band(value, 0x10), 4) | |
end | |
function clutchFilter(value) | |
return bit.band(value, 0x01) | |
end | |
function processWheel(id, data, offset) | |
--wheel speed is 13 bits long, little endian | |
--low byte high byte | |
--76543210 76543210 | |
--11111111 11111XXX | |
local highByte = bit.band(data[offset + 2], 0x1F) | |
local lowByte = data[offset + 1] | |
local value = highByte * 256 + lowByte | |
value = value * 0.0625 | |
--convert to MPH. comment to keep KPH | |
value = value * 0.621371 | |
setChannel(id, value) | |
end | |
function processSteering(data) | |
local steer = 0 | |
if data[2] > 127 then | |
steer = -1*(((data[2]-128)*256)+data[1]) | |
else | |
steer = (data[2]*256)+data[1] | |
end | |
setChannel(steerId, (steer*0.045)) | |
end | |
function fuelFilter(value) | |
--adjust for 7 bit value | |
value = bit.band(value, 0x7F) | |
--convert liters to %. tank holds 62.83 liters | |
return value / 0.6283 | |
end | |
function extTempFilter(value) | |
local temp = bit.band(value, 0x7F) | |
if value > 127 then | |
temp = -1 * temp | |
end | |
temp = toF(temp) | |
return temp | |
end | |
---------------------------------------- | |
--customize here for CAN channel mapping | |
--format is: | |
--[CAN Id] = function(data) map_chan(<chan_id>, <data>, <CAN offset>, <CAN length>, <multiplier>, | |
-- <adder>, [filter]) | |
---------------------------------------- | |
CAN_map = { | |
[496] = function(data) processWheel(lfWheelId, data, 0) | |
processWheel(rfWheelId, data, 2) | |
processWheel(lrWheelId, data, 4) | |
processWheel(rrWheelId, data, 6) | |
end, | |
[339] = function(data) map_chan(brakeId, data, 0, 1, 1, 0, brakeFilter) end, | |
[504] = function(data) map_chan(brakePressId, data, 2, 1, 1, 0) end, | |
[809] = function(data) map_chan(tpsId, data, 5, 1 , 0.392156863, 0, e46_tps) | |
map_chan(tempId, data, 1, 1, 0.75, -48, toF) | |
map_chan(clutchId, data, 3, 1, 1, 0, clutchFilter) | |
end, | |
[1349] = function(data) map_chan(oilTempId, data, 4, 1, 1, -48, toF) end, | |
[1083] = function(data) map_chan(gearTempId, data, 0, 1, 1, -55, toF) end, | |
[790] = function(data) map_chan(rpmId, data, 2, 2, 0.15625, 0, rpmFilter) end, | |
[501] = function (data) processSteering(data) end, | |
[1555] = function (data) map_chan(fuelId, data, 2, 1, 1, 0, fuelFilter) end, | |
[1557] = function (data) map_chan(extTempId, data, 3, 1, 1, 0, extTempFilter) end | |
} | |
function onTick() | |
processCAN(CAN_chan) | |
end | |
--===========do not edit below=========== | |
function processCAN(chan) | |
local msg = 0 | |
repeat | |
local id, e, data = rxCAN(chan, 0) | |
if id ~= nil then | |
local map = CAN_map[id] | |
if map ~= nil then | |
map(data) | |
end | |
end | |
msg = msg + 1 | |
until id == nil or msg > 100 | |
end | |
--Map CAN channel, little endian format | |
function map_chan(cid, data, offset, len, mult, add, filter) | |
if offset + len > #data then return end | |
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 | |
local cv = value * mult + add | |
if filter ~= nil then cv = filter(cv) end | |
setChannel(cid, cv) | |
end | |
initCAN(CAN_chan, CAN_baud) | |
setTickRate(tickRate) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment