PE3 CAN

Introduction

The following script integrates the Performance Electronics PE3 ECU.

Performance-electronics-PE3 ECU.jpg

Reference Documentation

Supported Channels

This integration supports the following channels:

  • RPM
  • TPS (Throttle Position)
  • InjectorPw (Injector Pulse Width)
  • Ignition (Ignition Advance)
  • Baro (Barometer)
  • MAP (Manifold Absolute Pressure)
  • Lambda
  • IAT (Air inlet temperature)
  • EngineTemp

Wiring

Connect the PE3 CAN High / CAN Low to the corresponding CAN High / CAN Low on the RaceCapture/Pro CAN 1 channel. See the [CAN_Bus_Integration|CAN integration guide]] for wiring details.

  • Note: The PE3 ECU is already terminated with a 120 ohm resistor.

CAN integration script

Once wiring is complete, you can enable the CAN bus channel mapping by enabling the following script.

Under the RaceCapture/Pro scripting configuration, copy and paste (ctrl-c / ctrl-v) this script into the scripting window of RaceCapture/Pro. Ensure any existing script is removed.

-- RaceCapture/Pro CAN mapping for Performance Electronics PE3 ECU
-- Automatically starts logging with engine 'on' (RPM triggered)
-- see rpmFilter() function
--
--how frequently we poll for CAN messages
tickRate = 30
--the CAN baud rate
CAN_baud = 250000
--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])
rpmId = addChannel("RPM", 25, 0, 0, 10000)
tpsId = addChannel("TPS", 25, 0, 0, 100, "%")
fuelTimeId = addChannel("InjectorPw", 25, 2, 0, 30, "ms")
ignId = addChannel("Ignition", 25, 0.1, -20, 100, "deg") 
baroId = addChannel("Baro", 1, 1, 0, 105, "kpa")
mapId = addChannel("MAP", 25, 1, 0, 255, "kpa")
lambdaId = addChannel("Lambda", 25, 3, -2, 2, "")
iatId = addChannel("IAT", 25, 1, 0, 255, "F")
tempId = addChannel("EngineTemp", 1, 0, 0, 255, "F")

--only start logging / telemetry if engine is running
function rpmFilter(value)
 if value > 500 then startLogging() else stopLogging() end
 return value
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 = {
[0x0CFFF048] = function(data) map_chan(rpmId, data, 0, 2, 1, 0, rpmFilter)
                              map_chan_s(tpsId, data, 2, 2, 0.1, 0)
                              map_chan_s(fuelTimeId, data, 4, 2, 0.01, 0)
                              map_chan_s(ignId, data, 6, 2, 0.1, 0)
               end, 
[0x0CFFF148] = function(data) map_chan_s(baroId, data, 0, 2, 0.01, 0)
                              map_chan_s(mapId, data, 2, 2, 0.01, 0)
                              map_chan_s(lambdaId, data, 4, 2, 0.001, 0)
               end,
[0x0CFFF548] = function(data) map_chan_s(iatId, data, 2, 2, 0.1, 0)
                              map_chan_s(tempId, data, 4, 2, 0.1, 0)
               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

--Map CAN channel, little endian format
function map_chan_s(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
    --adjust for sign
    if value > 32767 then value = value - 65536 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)