Digital Dashboard: Factory Sensors and Pinouts

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


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


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: First Test Event

This past weekend I got to put the Digital Dashboard to the test. I went to a two-day track event at Palmer Motorsports Park in Palmer, MA with COMSCC. This was my first event with COM, but they turned out to be a great group and I really liked the Time Trials format they run.

For the seven session out on track, the dashboard worked really well. I’ll elaborate:


The shift light was bright even in sunlight. I did have to rely on the low end of my peripheral vision to see it though. I mostly was able to discern the color, particularly when i got into the orange and red section of the LED strip.  Currently, the left half always lights or yellow, the next quarter is orange, and the final quarter is red. I think i’m going to change it so that the entire strip changes colors as the graphs advances instead of just the region of the graph. So at first it will be yellow, as it passes halfway the entire thing will turn orange, and as it advances past 3/4 the entire thing will be red. That should make it easier to catch the color and thus general RPM out of the corner of my eye.

The LCD was also contrasty enough to read in direct sunlight. I was surprised at how often i glanced at the gear indicator. The large block number was easy to read. I didn’t try to read the small sensor values while driving, but i did glance at the bar graphs. Just like an analog gauge, you get a feel for the normal centered position and basically just look for any extremes.

I have a separate display page for real time accelerometer info, but i never bothered with it while driving. I did however, review the peak G-Force numbers after a few sessions out of curiosity. I now plan to make another display page with min and max values for all sensors that I can review after a session. That’s a lot easier than digging through the log files on a computer.


The PA6H based GPS module with external antenna did a great job.


It’s running a 5hz l ocation update rate with SBAS completely unfiltered. I’m pumped to see how clean it looks with no filtering. You can easily distinguish the pit out and pit in lines as well as a pass between T5 and T6 during this session. You can also see on the the variation along the curved front straight which is my trying to run close to a concrete wall, but being a little nervous about it.

Now that I know the data is fairly clean, i’m going to implement some lap timing features.


Whole point of this thing is to collect accurate data. I’d say it was pretty successful.  This is oil and water temp over the course of a session:


I also logged Oil Pressure and was happy to see no oil starvation indicating drop outs. It’s logging at 10hz so that should be able to catch it I think.

X-Y acceleration data looks pretty good, if not a little noisy. I have a low pass digital filter on the data but i may need to lower the cut off frequency a bit since I’m after the general force on the car while turning/braking, not high frequencies bumps/vibrations, etc.


The logged data seems to have worked well. I can’t find any skipped samples or anything. The only issue i had was more of a usability one. I have  button on the dashboard to start and stop recording. If i forgot to hit the stop button before i power off the dashboard/logger, it won’t close the file and it won’t be saved. I lost a few sessions to this.

I need to come up with a way either to incrementally save the log file or have some sort of shutdown sequence. Or maybe just a big note on the dash.

All in all, I’m really happy with how it worked out. I was able to load all the data into RaceRender 3 and generate a rather informative track video!


Digital Dashboard Dissection: Temperature Sensors

This is the first of a few posts where I’ll break down a certain subsystem of the digital dashboard and explain in more detail. First up: temp sensors.


The temperature sensing subsystem consists of a few parts. First is the sensor itself. Then, the circuitry on the PCB consists of a buffer, a filter, and an ADC. Lastly, the digitized input is processed in software on the processor.

For temp sensors, I chose the AEM 30-2012 temperature sensor.

302012Physically, it is a 1/8″ NPT thread sensor and comes with the mating connector and terminals. I chose this sensor because its fairly cheap at around $40, is quite accurate (+/- 1.5C), and comes with good support and documentation from AEM.

The sensor works as a variable resistor whose resistance varies with temperature. The datasheet provides a nice table showing how the resistance changes over a broad temperature range. This table will be discussed later in the software section.

Next up is the electrical design consisting of the sense circuit, buffering, filtering, and analog-to-digital conversion.

The easiest way to convert a variable resistor to a voltage signal is to put it into a voltage divider using a pull-up resistor. In this configuration, the output voltage will vary with resistance and thus temperature. The AEM 30-2012 datasheet even providers a reference schematic:


This is the schematic for this part of my board. I’m using a 2.2k resistor for the pull-up (R3). I also put a jumper between the sensor input (SENS1_IN) and this pullup so that i can disable it if i’m using a sensor that provides its own voltage output.


Using this configuration, the voltage will scale from 0-5V according to the temperature by:

SENS1_IN = 5V * ( Rsensor/(Rsensor + Rpullup) )


Once we have a sensor voltage signal, it’s a good idea to buffer it. A buffer provides a high impedance input that won’t load down the sensor. It also provides a low impedance output that is able to drive the next stage. Basically think of it as a divider between the outside world and your processing circuitry. The easiest way to make a buffer is to use an opamp buffer as shown below, U3A.


The next stage is a basic RC low pass filter using R11 and C5. These values create a low pass filter with a cut off at F = 1/(2*Pi*R*C) = 723hz. This is plenty high for most sensors (this circuit is used for all 8 input channels and is intended to be flexible), but is low enough to filter out most unwanted noise.

Next up is the ADC. For this project i chose the 8 channel, 12-bit, Microchip MCP3208. It’s SPI bus makes interfacing with the processor easy. 12 bits provides a max value of 2^12 = 4096 for a range of 0-4095. So each bit represents 5.0V/4096bits = 1.22mV/bit which is more than adequate resolution for this application.

Lastly, we have the software which processes this digital information. Because the temperature sensor is nonlinear, we have to use a lookup table to convert its output voltage (which represents its resistance which represents the temperature) to a temperature. The datasheet gives us:


Here is the table implemented in code using the digital representation of the voltage and degrees C:

// Temp LUT - digital, degC
short tempLUT[39][39] = {
{ 325, 150 },{ 362, 145 },{ 404, 140 },{ 451, 135 },
{ 505, 130 },{ 565, 125 },{ 634, 120 },{ 710, 115 },
{ 796, 110 },{ 892, 105 },{ 1000, 100 },{ 1118, 95 },
{ 1249, 90 },{ 1391, 85 },{ 1544, 80 },{ 1708, 75 },
{ 1882, 70 },{ 2063, 65 },{ 2248, 60 },{ 2435, 55 },
{ 2621, 50 },{ 2803, 45 },{ 2976, 40 },{ 3138, 35 },
{ 3287, 30 },{ 3421, 25 },{ 3540, 20 },{ 3644, 15 },
{ 3732, 10 },{ 3807, 5 },{ 3869, 0 },{ 3920, -5 },
{ 3961, -10 },{ 3993, -15 },{ 4018, -20 },{ 4038, -25 },
{ 4053, -30 },{ 4065, -35 },{ 4074, -40 }};

The following code converts the digitized voltage input to a temperature using the lookup table. First it searches the lookup table for the closest match that less than the input value. The input value must then be between this match and the next one higher. It then linearly interpolates between these two table entries to find the equivalent temperature.

/* Temp Sensor Look Up Table
* Returns Temp in C
float ToTemperature(unsigned short adcIn) {

short lowerI = 0;
short upperI = 0;
for(short i=0; i<39; i++) {
   if(tempLUT[i][0] <= adcIn ){
      lowerI = i;
      upperI = i;
return tempLUT[lowerI][1] + (float)( tempLUT[upperI][1] - tempLUT[lowerI][1] )*( adcIn - tempLUT[lowerI][0] )/(float)( tempLUT[upperI][0] - tempLUT[lowerI][0] );

And that’s about how it works, from sensor to computed value.

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

Digital Dashboard – Shield is up!

A few weeks ago my PCBs for the “Main Unit Shield” came in. Again, OSH Park delivered ahead of schedule and they look great.



Seeing that i’m doing more and more builds with small surface mount parts, I decided to get a hot-air rework station. It turns out that Microcenter down the street carries a cheap unit so i picked one up and got to work. It was actually pretty easy to use. I slobbed solder paste over the pads, placed the part, and applied the heat. After about a minute the tiny solder balls in the paste would start to melt and cling together. The solder mask did its job, all the molten solder blobs found their homes on pads, the part self centered, and voila. It turned out great and was far more forgiving than I would have thought. (or so I thought).

This board was a bit more of a headache than the last board. When i first powered on the board, the ADCs were all over the place. I couldn’t get accurate readings, they should shift and wonder, it was a mess. The only good news was that the I2C pullups and connection out to the dashboard worked fine.

The ADC trouble boiled down to three issues. First, I specified the wrong opamp parts. I designed the ADC input opamp buffers as requiring rail-to-rail input (common mode voltage) and the parts I specified didn’t allow this. I replaced the Microchip MCP604s with TI OPA4342s.

Second, I found a short between two input channels which occurred because i had a via too close to a resistor pad. I removed the solder bridge and filed it away as a lesson learned for the next PCB i layout.

Even after doing the above two fixed, i was getting strange results. I think having the short killed an opamp, so i replaced it. Then that seemed to work, but then the ADC wasn’t reading correctly. I wasn’t sure if it was hardware or software at this point so i broke out the Saleae Logic Analyzer and verified the SPI bus communication. It all looked good. So I ordered more parts, replaced more parts. Still no luck.

Finally I realized that I might be cooking these parts with the heat gun. I had a couple spare parts so I decided to remove the bad parts with hot air, but solder the new ones in with the iron… and it worked. So I spun my wheels for a couple weeks mostly due to my own workmanship mistakes. Looking back on it, i think that rather than blasting the part with heat, i need to more closely mimic the temperature profile of a reflow oven. Ie, warm the board/part up for a few minutes first at a safe temperature, and then relatively quickly ramp up the heat to melt the solder and then drop it back down again.

But in the end, the board works.


At this point this prototype hardware is pretty solid. I’ll continue to fine tune the software, but I’m mostly waiting for the M3 to thaw out so I can install the sensors and this unit in the car and do some field testing.

Digital Dashboard – Display Ideas

The dashboard/logger is starting to come together. Most of the sensor functionality I want is in place, it logs well, etc. The tricky part now is how to display all this info in a way that is useful and clear while driving the car.

One of the most import visual outputs is the shift light itself. The setup i’m using is fairly large and clear with enough length and resolution to hopefully make it clear where you are in the rev band and how its trending. I do hope that they are bright enough to see in the sunlight, but I think having it mounted in the factory dash area under the dash hood should make this ok.

The second most important indication is for the warning messages. If my oil pressure drops or I start to overheat, i want it to be very clear very quickly. As of now, if there is an alarm condition, the whole display changes to a warning message screen:

achtung“Warning”, “Achtung!”, “Danger to the Manifold”, would all be appropriate. At the same time the shift lights will all blink red. I can display up to three alarms at once should hopefully be enough, even for a German car.

Lastly, i thought it would be cool to have a large number display for the gear indicator. While i generally know what gear I’m in, i’m moving to a 3.46 rear end in the E36 this year and will be shifting more often so it may come in handy.

IMG_1211Working with an old school character display is pretty clunky, but it at least allows you to program 8 custom characters. I used five of the custom characters for the I, II, III, IIII, and IIII characters for the bar graph. I used the remaining three slots for the large number characters- basically an upper block, lower block, and full block. There are prettier 4 line characters out there, but I don’t have the memory for them with the bar graph.

The mbed microcontroller i’m using does have a built in controller for a 7″ 800×480 full color TFT display, but that’s for another day.

In addition to the main screen, I can scroll through different screens using the buttons on the right side of the display. As of now I have a screen showing the raw ADC data for the 8 analog inputs, a screen with all processed sensors, a screen with GPS status, a screen with some basic setup stuff. I’ll post more info on those when i get them sorted out.


Digital Dashboard – GPS

Another thing that i like about the EA LPC4088 board is that it has Xbee formfactor headers on it. EA also makes a GPS accessory that plugs into using the popular PA6H module so there is lots of community support out there for it.

The unit itself is pretty slick and has a 10hz update rate which is helpful for tracking high speed things like race cars. The device talks over a UART using standard NMEA protocol so there are plenty of parsing libraries out there. I literally had this running in a couple hours.

I also soldered on a UFL connector and attached an active external antenna. It has a magnet mount which will work well on the roof of the car.


The precision shown on the display is only enough to get you in my  general metro area. The data logger logs six decimal places of info which is more meaningful for tracking a car on track.

This hasn’t yet left my house. I’m super eager to actually drive around with this and see how the data looks. I’m hoping it doesn’t require too elaborate of filtering.

Digital Dashboard – Main Unit Shield PCB

I went around in circles for a few weeks trying to figure out the best way to deal with the main unit. My initial thought was to spin an entirely new PCB to house the LPC4088 Quickstart board, SDcard interface, accelerometer, ADCs, buffer opamps, etc, etc. Basically it would replace the LPC4088 QSB Base Board and add the additional components I needed. Nice and clean.

After thinking a bit, however, I came to the conclusion that this would be pretty redundant, entail a much more complicated design effort, and cost more to build. I might as well use what’s been done for me and simply add what I need. Fortunately, the Base Board has an Arduino shield interface. I can just build a shield! It will plug into the empty shield header interface shown here:


The other benefit of this reduced scope is that I can actually get the design done and built in a timely manner. I decided on using a Microchip 8-channel MP3208 12-bit ADC. This will cover 8 channels of 0-5V analog input, plenty for my logger. I’m using MCP604 opamps and basic RC filters for input buffering/filtering.

Here’s an example of one of the analog input circuits. It has an optional 5V pullup via jumper, buffer, and antialiasing filter.


The other main purpose of the shield is two connectors. One for all my sensors to connect to as inputs and the other to connect to the Remote Display.

The board looks like this:


I just placed the order today so the PCBs should be here in a couple weeks. In the mean time i need to gather up the BOM and  order the parts.

In the meantime I plan to focus on the software a bit and get that decent shape. More to come!


Digital Dashboard – The Remote Display is Built

I received the “Remote Display” PCBs from OSHPark before Christmas. This was my first time using OSHPark, but i must say it was a pretty great experience. It was very easy to upload my Eagle board design, it processed quickly, and they gave detailed renders of the final boards and all the layers – all easily viewable right on their website. They also arrived ahead of schedule.

IMG_1223I had some time off for the holidays and managed to get one board built up.


It’s funny how I already see things that I wish I had done differently. Why didn’t i label the trim pots and the buttons?!? (The pots control contrast and the R, G, and B backlight). But what matters most came through, it works!


It still looks like a science fair project, but at least all the hardware is set and physically stable. One less bread board to deal with.

Now that this is done I need to focus on both the “Main Unit” PCB and polish up the software.


PCBs for the digital dashboard!

I finally got moving again on the digital dashboard project. I was held up a bit not being able to find device models using DipTrace. I made a few from scratch, but it was tedious and was bogging me down. I also knew that when it came time to do the layout, I’d have to shell out for a paid version of DipTrace. This got me researching options and I finally decided to give Eagle another go. It has a clunky UI, but the community support can’t be beat. There are libraries for everything out there. For example Adafruit and Sparkfun both share their schematics in Eagle and offer their libraries up for public use.

After about 30 minutes of getting used to the UI, I was rolling. I was able to find a few obscure device models such as the 12 LED bargraph in the Adafruit library. I also found that making new device models from scratch was a breeze in Eagle so I soon found myself cranking them out myself rather than hunting for them.

Using Eagle, i was able to finalize the design for the remote display PCB. This will serve as the “dashboard” part of this project. The other half will be the “main unit” where the processor is housed along with all the sensor inputs, etc.

Due to all the LED and LCD I/O, I decided to go with a four layer board. It costs twice as much, but everything is neater and more electrically sound. There isn’t much too critical with regards to signal speed or integrity on this board, but its still fun to do things right.



5V power and ground planes are on the inner layers with traces on the outter layers. All components are on top. You can see the four 12 bar LEDs along the top that will act together as the shift light and also blink warning statuses. In the middle is a good old fashioned 20×4 character LCD. It has an RGB backlight so the four trim pots on the left control its contract and background color. On the right are three push buttons. As of now the top button is to start/stop data logging and the other two are for menu scrolling. The connector on the left is a Molex Microfit which is easy to use, has good density, and has cheap off-brand crimp tooling.

The middle chip is the MCP23008 demux that is running the LCD off the I2C bus. The two chips toward the outside are HT16K33 LED controllers and each drive a pair of the 12bar LEDs on the I2C bus as well. Oh and there’s a power LED too!

I decided to go with OSH Park for the PCBs. They have a ton of great feedback and good prices as well. In about two weeks i should have my boards!


I’ll get the parts on order soon and if all goes well, I’ll have a functioning PCB assembly in the next few weeks. My plan is to use this assembly with the LPC4088 dev base board acting as the main unit. This way I’m only introducing one major variable at a time. When all the kinks are worked out with this Remote Display assembly, I’ll move on to ordering the Main Unit boards.