Category Archives: Project M3

RaceCapture Pro

Over the winter I decided to switch from my homemade digital dashboard solution to the Autosport Labs RaceCapture Pro.

In terms of logging hardware, it includes a ton of features:

  • 8 12bit analog inputs
  • 3 digital I/O
  • 4 timer inputs
  • 10Hz GPS
  • 3-axis accelerometer
  • 2 CANBUS busses
  • RS-232
  • WiFi
  • Bluetooth
  • SD card storage

The other cool thing is that its designed for you to use a tablet as the dashboard display. The tablet connects to the main unit via bluetooth and looks something like this:

There are many configuration options and you can have as many “screens” as you want so you can cycle through different displays as needed.

In terms of software, the RaceCapture app can be run on a PC or even on the tablet itself. The idea is that after a session, you can pull out the dashboard tablet and check out the data. You can plot channels and compare laps.

I ended up using the RaceCapture Pro mk3 connected to my water temp, oil temp, oil pressure, and TPS sensors. I used an Amazon Fire HD8 tablet as the dash as you can see here:

The RCP system uses LUA scripting to configure much of the hardware and also to allow you to write custom vitual channel scripts. Here is the LUA script i wrote to setup my hardware as well as the ShiftX2 shift light. It also calculates speed based off of the E36’s differential speed sensor and gear based on speed and RPM.

setTickRate(10) --10Hz 
-- What CAN bus ShiftX2 is connected to. 0=CAN1, 1=CAN2
sxCan = 1
-- 0=first ShiftX2 on bus, 1=second ShiftX2 (if ADR1 jumper is cut)
sxId=0
--Brightness, 0-100. 0=automatic brightness
sxBright=0
sxCanId = 0xE3600 + (256 * sxId)
println('shiftx2 base id ' ..sxCanId)
--virtual channels 
--addChannel("name",SR,prec,min,max,"unit") 
speeddiff_id = addChannel("Speed_",10,0,0,160,"MPH") 
gear_id = addChannel("Gear",5,0,0,5,"gear") 
brakeg_id = addChannel("BrakeG",10,2,0,2,"G")
--global constants 
first = 4.20 
second = 2.49 
third = 1.66 
fourth = 1.24 
fifth = 1.00 
final = 3.46 
tirediameter = 24.7 
--global variables 
rpm = 0 
rpm_diff = 0 
speed = 0 
function updateSpeedDiff() 
   rpm_diff = getTimerRpm(1) 
   speed = rpm_difftirediameter0.002975 
   speed = speed + 0.5 -- round because 0 prec. truncates 
   setChannel(speeddiff_id, speed) 
end 
function updateGear() 
   rpm = getTimerRpm(0) 
   local gearErr = 0.15 
   local gear = 0 
if speed > 2 then 
      ratio = rpm/(rpm_diff*final) 
      if ((first  - ratio)^2) < (gearErr^2) then gear = 1 end 
      if ((second - ratio)^2) < (gearErr^2) then gear = 2 end 
      if ((third  - ratio)^2) < (gearErr^2) then gear = 3 end 
      if ((fourth - ratio)^2) < (gearErr^2) then gear = 4 end 
      if ((fifth  - ratio)^2) < (gearErr^2) then gear = 5 end 
   end 
   setChannel(gear_id, gear) 
end 
function autoLog() 
   if speed > 10 and rpm > 500 then 
      startLogging() 
   end 
   if speed < 5 and rpm < 100 then 
      stopLogging() 
   end 
end 
function sxOnUpdate()
  --add your code to update ShiftX2 alerts or linear graph during run time.
  --Runs continuously based on tickRate.
--uncomment the below for Direct RPM on input 0
  sxUpdateLinearGraph(getTimerRpm(0))
--update engine temp alert
  sxUpdateAlert(0, getAnalog(0))
--update oil pressure alert
  sxUpdateAlert(1, getAnalog(2))
end
function sxOnInit()
  --config shift light
  sxCfgLinearGraph(0,0,0,7000) --left to right graph, linear style, 0 - 7000 RPM range
sxSetLinearThresh(0,0,4000,0,255,0,0) --green at 3000 RPM
  sxSetLinearThresh(1,0,5400,255,255,0,0) --yellow at 5000 RPM
  sxSetLinearThresh(2,0,6800,255,0,0,10) --red+flash at 6500 RPM
--configure first alert (right LED) as engine temperature (F)
  sxSetAlertThresh(0,0,215,255,255,0,5) --yellow warning at 215F
  sxSetAlertThresh(0,1,225,255,0,0,10) -- red flash at 225F
--configure second alert (left LED) as oil pressure (PSI)
  sxSetAlertThresh(1,0,0,255,0,0,10) --red flash below 8 psi
  sxSetAlertThresh(1,1,8,255,255,0,5) --yellow flash 8-12 PSI
  sxSetAlertThresh(1,2,12,0,0,0,0) --above 12, no alert
end
function sxOnBut(b)
  --called if the button state changes
  println('button: ' ..b)
end
---ShiftX2 functions
function sxSetLed(i,l,r,g,b,f)
  sxTx(10,{i,l,r,g,b,f})
end
function sxSetLinearThresh(id,s,th,r,g,b,f)
  sxTx(41,{id,s,spl(th),sph(th),r,g,b,f})
end
function sxSetAlertThresh(id,tid,th,r,g,b,f)
  sxTx(21,{id,tid,spl(th),sph(th),r,g,b,f})
end
function setBaseConfig(bright)
  sxTx(3,{bright})
end
function sxSetAlert(id,r,g,b,f)
  sxTx(20,{id,r,g,b,f})
end
function sxUpdateAlert(id,v)
  if v~=nil then sxTx(22,{id,spl(v),sph(v)}) end
end
function sxCfgLinearGraph(rs,ls,lr,hr) 
  sxTx(40,{rs,ls,spl(lr),sph(lr),spl(hr),sph(hr)})
end
function sxUpdateLinearGraph(v)
  if v ~= nil then sxTx(42,{spl(v),sph(v)}) end
end
function sxInit()
  println('config shiftX2')
  setBaseConfig(sxBright)
  if sxOnInit~=nil then sxOnInit() end
end
function sxChkCan()
  id,ext,data=rxCAN(sxCan,0)
  if id==sxCanId then sxInit() end
  if id==sxCanId+60 and sxOnBut~=nil then sxOnBut(data[1]) end
end
function sxProcess()
  sxChkCan()
  if sxOnUpdate~=nil then sxOnUpdate() end
end
function sxTx(offset, data)
  txCAN(sxCan, sxCanId + offset, 1, data)
  sleep(10)
end
function spl(v) return bit.band(v,0xFF) end
function sph(v) return bit.rshift(bit.band(v,0xFF00),8) end
function onTick()
  updateSpeedDiff()
  updateGear()
  autoLog()
  sxProcess()
end
sxInit()

See my latest RaceCapture LUA scripts on my Github.


Update: Digital Dashboard

I used the dashboard through the rest of 2015 and 2016 and it worked great. The hardware was solid and never skipped a beat. The display worked well and the shift light was particularly useful. I was also able to use the exported data to create track videos using RaceRender such as seen here:

However, I sort of hit a wall once the data was collected. I was able to make GPS plots and certain calculations in Excel, but besides screening for low oil pressures and high temps, it left a lot to be desired. A huge part of data analysis is using it to learn where and why you were fast or slow on a given lap. This requires much more advanced displaying and calculation of data to make it easier to pickup the clues and to develop as a driver. The problem is that all of the professional analysis software is locked to their proprietary data formats so there’s no way to use my data with their software.

This led me to eventually abandon my home-brew solution and look into the RaceCapture system from Autosport Labs. It’s a highly customizable, open source solution, that includes solid hardware PLUS pretty decent software. Their platform is growing fast and very receptive to community feedback so what’s not to like? I’ll make a another post with my latest data logging setup.


M3 Updates for Spring 2016

I’m getting really bad about documenting what i’m doing and even updating the blog. But here’s a brief recap of what went on over the winter:

  • Oiling System
  • Power Steering System
    • New reservoir and hoses. Used a custom hose for the reservoir to cooling trumpet to eliminate the weak factory crimp connection
  • New shocks/struts/springs
    • TCKline DA shocks/struts with 450/500# springs
    • I got these used for a pretty good deal and had them rebuilt
  • Front subframe reinforcements installed
  • Cooling System
    • New thermostat and housing
    • New S54 Z3M radiator
    • Spal electric fan
    • Custom ducting
  • New belt tensioner (converted to hydraulic) and belt
  • Deleted all A/C components, washer, other misc bits
  • Thinned wiring harness to remove unneeded wiring

 

Digital Dashboard: Factory Sensors and Pinouts

Here is a summary of the connections I made to the factory E36 sensors.

RPM

The RPM signal is a clean 12V pulse train who’s frequency is proportional to the engine speed. If you setup a rising edge interrupt and a timer, it is easy to measure the signal’s period. Be sure to scale the 12V appropriately for your devices I/O levels. It gives one pulse per cylinder fire and there are three pulses per rotation so the equation boils down to:

So RPM = MeasuredPeriod(micros) / 20000000(micros)

The RPM signal can be found at three fairly convenient locations that I know of. The wire is always solid black:

  1. Pin 1 on the round diagnostic connector under the hood on the passenger side
  2. Pin 20 on connector X16 to the back of the gauge cluster
  3. Pin 8 on connector X22 to the cruise control module behind the glove box

Speed

The Speed signal is also a clean 12V pulse train who’s frequency is proportional to the vehicle’s speed. Be sure to scale the 12V appropriately for your devices I/O levels. The sensor is in the rear differential and outputs 9 pulses per revolution.

Speed = 6313.13 * TireCircumference / MeasuredPeriod(micros)

The Speed signal is black with a white stripe and can be found on:

  1. Pin 2? on connector X16 to the back of the gauge cluster
  2. Pin 10 on connector X22 on the cruise control module behind the glove box
  3. Pin 10 on radio connector

Throttle Position

The TPS signal comes form a potentiometer mounted on the throttle body. It’s middle pin/wire outputs 0-5V proportional to the throttle position. Note that there is about a half a volt of deadband on both ends resulting in an effective range of about 0.5V to 4.5V. I ran this into an ADC and scaled to provide a percentage.

 

Digital Dashboard Installed!

It’s not super pretty, but it works!image1 (3)

Over the past few months I installed the following sensors:

  • Water Temp (AEM 30-2012) installed where the throttle body heater coolant bung used to be in the head. It threads right in with an adapter i got from TRM.
  • Oil Temp (AEM 30-2012) installed into Bimmerworld oil distribution block mounted to oil filter housing
  • Oil Pressure (AEM 30-2131) also installed into the Bimmerworld ODB.
  • Throttle Position I get by tapping into the factory sensor at the throttle body. It is a 0-5V signal.

I loomed up the wiring and ran it through the firewall behind the glove box nice and neat. Everything still looks neat and clean in the engine bay. Once through the firewall, I crimped Molex MicroFit contacts on the wires and inserted them into the connector which mates to the “Main Unit”.

The Main Unit is installed in the glove box. For the moment its just the raw PCBs mounted on stand offs screwed to the bottom of the glove box. I need to work on an enclosure for this, but for now at least its secure and neat. (I’ll add a pic of this soon).

I then made another harness with the MiniFit connector and ran it behind the dashboard to connect between the Display and the Main Unit. the Display is secured via its bottom stand-offs with velcro. Again, not pretty, but its secure enough for the time being.

Functionally, everything is working great. I’m happy with the legibility of the display. The shift light is awesome. All sensors are behaving. It’s logging data well. It’s really pretty cool!

My intention is that over the next few weeks, I’ll write posts detailing each subsystem of the device including the sensor, circuit, and software, etc. Here’s the first one:

Digital Dashboard Dissection: Temperature Sensors

The M3, rollbars, subframes, cracks…

Last fall I was prepping for the install of a bolt-in 4-point roll bar when i noticed a crack under my back seats…

IMG_1114 IMG_1113

That couldn’t be good so I had an excellent local race shop, Vintage Sports & Restoration, take a look. And they found a cracked subframe.

image2_small image1_small

 

This is a fairly uncommon failure on an E36. Typically it is the stubframe *mounts*, which are a part of the unibody of the car, that crack. My mounts were fine, but it was this ear of the subframe itself that cracked.

The shop also noticed that the previous owner had installed solid aluminum differential mounts, but kept the original rubber subframe mounts in place. With no isolation between the diff and the subframe, all that driveline energy was being applied to the rubber bushings. They quickly died and eventually fatigued the subframe and it cracked. At the point, the driveline energy was being coupled to the unibody asymmetrically through three instead of the four mounting points and that probably caused the stress crack under the seats. So the moral of the story is to understand how bushings/mounts work and make sure they’re being used as a system.

So VSR installed a new freshly painted subframe with 75D mounts. Being the foundation of the rear suspension, we wanted a firm interface here. We opted against going full aluminum because we do want to reduce some of the high frequency energy that can be rough on a street driven car both in sound and metal fatigue.

We then used 95A poly diff mounts so that there is some give to the driveline, but it it still much stiffer than stock to sharpen the response a bit.

If that wasn’t enough, the shop said my diff was making a lot of noise and the left side output shaft bearing was shot. That snow balled into a brand new 3.46 2-clutch, 40%, 45/45 LSD from Dan at diffsonline.com. Dan’s work is top notch and his diffs are very common among the club racers. I rebuilt the LSD in my old E30, but I decided to let the pros handle this one.  Since the car is still driven to and from tracks as far a way as 6-9 hrs, I chose the 3.46. The more racey 3.64 is perfect for a trailered race car but it revs too high for comfortable highway driving.

So as of yesterday the car is home again. Here’s a final rundown of what’s new:

  • 4-pt bolt-in roll bar with custom harness bar height (I’m tall)
  • Repaired crack under rear seats
  • Refurbished subframe w/ AKG 75D bushings
  • Rebuilt 3.46 LSD from diffsonline.com. 95A bushings

IMG_1306

Next up is:

  • Install seats (Cobra Suzukas w/ VAC hardware)
  • Install harnesses (Schroth ProFi 6-pts)
  • Install new valve cover gasket (I have quite a leak now) and spark plugs
  • Install oil temp, water temp, oil pressure sensors (for digital dashboard)
  • Break in new diff!

 

 

M3 Updates

I’m doing a lousy job of keeping this updated, but here’s an update on the M3.

So far I’ve done:

  • Installed Cobra Suzuka racing seats for head room and control
    • VAC Motorsport adapters, mounts, and hardware
  • Removed headliner and sunroof, installed fiberglass delete panel for headroom and future rollbar height
  • Replaced the H&R Race springs with Sport, better ride height and geometry
  • Front wheel bearings
  • Front control arms and Bimmerworld TrackCAB delrin bushings
  • Bimmerworld Group N rep motor mounts
  • Rogue Engineering transmission mounts
  • Secondary Air Pump delete

Right now the car is solid and I’m just having fun driving it. So far I’ve done four track days and two autocrosses with it and its been a blast. I have the last track day at NHMS coming up this weekend.

The next item on the list is to install a 4pt roll bar and get the harnesses I have sitting on a shelf installed. I hope to document this project a little more thoroughly!

Project M3

Well a lot has happened in the six months since i last posted anything about cars. Last fall I sold the GTI. It was a good car and consistently exceeded my expectations both on and off track. Despite VW’s somewhat tarnished reputation for reliability, it never so much as hiccup’ed, even running an extra 100ftlbs of torque and 75 additional horsepower on track.

However the track bug was coming back with a vengeance and I knew i should get something older, cheaper, with more track/race support going forward. I decided on an E36 M3. Since I’ve owned one before, I know them well. They have tremendous aftermarket race tech/support and a great community. I was even running BMWCCA track events in the GTI!

Previously, i had a sedan, but this time i wanted a coupe. There isn’t a performance difference, but the larger coupe doors make getting in and out easier with race seats easier for a tall guy like me. Alpine White is the only color a BMW should be in my opinion and a black interior would be ideal.

It took me over six months to find the right car, but I finally did. And lucky enough, it was a local car and BMWCCA-Boston club member.

1997 BMW M3

1997 BMW M3

It’s a southern car brought up here by the previous owner as a weekend/track car. It’s lived a comfy life and is really clean. It came with a great maintenance/mod history. The previous owner definitely loved this car.

In my next post, I’ll go over where the car stands, what I’ve done recently, and what my goals for the car are.