Skip to the content
2 layers101.6 × 53.3 mmBMW E46 Cluster Interface Board, the printed circuit board in 3D

BMW E46 Cluster Interface Board

KSullivan20221/SimHub-BMW-E46-Cluster-Module9

This repo contains all of the circuitry, code, and resources used to create a shield board for an Arduino Mega that could be used to communicate with a BWM E46 instrument cluster from a PC. The main application of this project was in using the cluster in conjunction with SimHub in order to show the values from the supported video games on the cluster's gauges.

Size
101.6 × 53.3 mm
Copper layers
2
Thickness
1.6 mm
Parts
120
Nets
178
Pads
471
Tracks, vias
1,090, 84
Pours
1
Routed
Yes
KiCad
KiCad 5 (file 20171130)
Created
14 Nov 2021
Updated
23 Nov 2021

Overview

BMW E46 Cluster Interface Board is an open-source printed circuit board by KSullivan20221, from the KSullivan20221/SimHub-BMW-E46-Cluster-Module repository on GitHub. It is a 2-layer board of 101.6 × 53.3 mm with 120 parts on 178 nets, routed with 1,090 tracks and 84 vias.

It is built around the MCP6002T-I/SN(MS), DMN67D8L-7 and TP0610K-T1-E3. Its parts include 57 resistors, 32 transistors, 13 connectors, 9 capacitors and 5 ICs. It belongs with the interfaces and adapters boards of this library.

Main components

3

README

README.md

SimHub-BMW-E46-Cluster-Module

This repo contains all of the circuitry, code, and resources used to create a shield board for an Arduino Mega that could be used to communicate with a BWM E46 instrument cluster from a PC. The main application of this project was in using the cluster in conjunction with SimHub in order to show the values from the supported video games on the cluster's gauges.

All of the testing I performed was on an E46 cluster with the following ID number and firmware:

  • Cluster Serial Number: 1031098105
  • Cluster Hardware Number: 30 (Can retrieve this by running the on-board 'Test 1' on the cluster, in test 1.5)
  • Cluster Software Number: 360 (Can retrieve this by running the on-board 'Test 1' on the cluster, in test 1.5)

See the following link for how to retreive this data: https://www.e46fanatics.com/threads/just-found-us-version-of-hidden-menu.239619/

Credits

There is no way I could have accomplished this project without many of the resources available to me:

Hardware Design

The circuit designed for this project was designed as a shield for an Arduino Mega microcontroller board. The purpose of this circuit was to take the signals from the Arduino Mega and use them to control the lights, gauges, and serial busses in the cluster. With this design, a user can supply 12V to the DC barrel jack input of the Arduino Mega in order to power the cluster, and then connect a USB-B cable from the computer running the video games to the Arduino to pass data between the computer and the Arduino.

Signals required to operate the cluster

In order to determine what signals I needed to drive the cluster, I searched for "E46 cluster pinout" and soon arrived at the following website which provided the pinout for the two connectors on the cluster: https://www.bmwgm5.com/E46_IKE_Connections.htm

With this, and the help of the people on the following forum, I was able to come up with the following table outlining what signals were required at each pin of the cluster:

BMW CAN Bus Forum: https://www.bimmerforums.com/forum/showthread.php?1887229-E46-Can-bus-project

X11175 Connector Pin Function / Signal Levels

Pin NumberPin FunctionDetailed DescriptionNotes
1Ground
2Battery Charge IndicatorProvides a voltage up to 12 V indicating the batteries voltage level
3Engine Start Signal FeedbackNot certain, but seems like 12V into this pin indicates the engine has started
412V Power inputAlways gets 12V from the battery
512V On / StartReceives 12V when car is fully on (key turned to second position)
612V Accessory / On / StartReceives 12V when car is in accessory mode or when fully on
7Cluster backlightOn certain cluster models (not this one), setting to 12V turns backight on
8Speedometer Signal OutputUnknown what this does, the cluster I used did not have anything wired here
9CAN-H SignalThe CAN High side of the differential pair
10CAN-L SignalThe CAN Low side of the differential pair
11Fuel Tank 1 +Pin that fuel tank 1 level sensor positive signal is connected to70 Ohms to ground = empty, 395 Ohms to ground = full
12Fuel Tank 1 -Return connection for fuel tank 1 level sensor (sits at ground potential)Connecting this to ground does not cause issues for this circuit
13Oil Pressure SwitchConnects to oil pressure sensorPulling down to ground = oil pressure issue, leaving unconnected = no issue
14K-Bus SignalK-Bus Communication signalThe K-Bus can be controlled by one of the Arduino's serial peripherals after being level-shifted so that it ranges from 0-12V instead of the Arduino's 0-5V
15Fuel Tank 2 +Pin that fuel tank 2 level sensor positive signal is connected to70 Ohms to ground = empty, 310 Ohms to ground = full
16Fuel Tank 2 -Return connection for fuel tank 2 level senor (sits at ground potential)Connecting this to ground does not cause issues for this circuit
17Oil Level SensorSignal that measures how full the engine oil isConnecting this pin to ground indicates an issue with the oil level, leaving unconnected = no issue
18Service Interval Indicator ResetNot certain what purpose this serves
19Rear-Left Wheel Speed SensorSignal that connects to wheel speed sensor that drives the speedometerThis is driven by a 12V fixed 50% duty cycle variable frequency square-wave (about 31 Hz = 10 MPH, 1646 Hz = 155 MPH)
20Brake Fluid Level SensorSignal that connects to brake fluid sensorConnecting this to ground indicates there is no issue with the brake fluid, leaving this unconnected indicates there is an issue
21Airbag Warning LEDIndicates the passenger airbag is ready to engageConnecting this to ground indicates the airbag is ready to engage, and will illuminate the light on the dashboard
22ABS Warning LightInicates that ABS is disabledConnecting to ground indicates that ABS is active, and the thus the LED on the cluster will turn off, and vice versa
23Parking brake switchIndicates that the E-Brake is engagedConnecting to ground indicates that the parking brake is not engaged, and will cause the 'BRAKE' light to turn off
24Brake wear sensorIndicates when the brakes are wornConnecting to ground indicates that the brakes are not worn, and the cluster light will turn off, and vice versa
25Diag Signal TXUnsure the function of this signal
26Coolant Level SensorIndicates if the coolant level is too lowConnecting this to ground indicates that the coolant level is sufficient, and will turn the cluster light off, and vice versa

X11176 Connector Pin Function / Signal Levels

Pin NumberPin FunctionDetailed DescriptionNotes
1AT+ Outside TemperatureReads data from sensor on the outside temperature3.07kOhm to ground = 95 degrees farenheit, 4.7kOhm to ground = 77 degrees farenheit, 7.33kOhm to ground = 59 degrees farenheit
2AT- Outside TemperatureReturn connection for the outside temperature sensorConnecting this to ground does not cause issues for this circuit
3Not connectedN/A
4Washer Fluid LevelIndicates if the washer fluid level is too lowConnecting to ground indicates that the washer fluid is filled, and clear the light on the instrument cluster, and vice versa
5Cruise Control ActiveSignal indicates if cruise control is acitve or notConnecting to ground indicates that cruise control is active
6Signal Airbag Warning, rollover sensorIndicates rollover in convertible version of carNot sure the polarity of this light as it was not active on this version of the cluster
7ReverseOnly in manual transmission version of carNot sure the polarity of this light as it was not active on this version of the cluster
8Not connectedN/A
9Not connectedN/A
10Not connectedN/A
11Not connectedN/A
12Drivers seat beltLight to indicate if the driver's seat belt is engagedConnecting to ground indicates that the driver's seat belt is engaged, and vice verse
13BC Button on turn signal stalkConnecting to ground indicates that the BC button is pressed
14Signal Gong?Unsure, but felt like this might engage the beeper on certain models
15Not connectedN/A
16Not connectedN/A
17Not connectedN/A
18Not connectedN/A

Sub-Circuits used in cluster module

Basic Pull-Down Network

This circuit in essence acts like a switch: When the Arduino applies 5V to the input of the circuit, the MOSFET (the DMN67D8L-7 part) turn on, and pulls the cluster pin to ground. The current that flows in this case can be up to 30mA, so the part was selected so that it could handle at least this (the selected part can handle up to roughly 200 mA). If the Arduino applies 0V to the input of the circuit, the MOSFET turns off and the cluster pin is pulled back up to 12V.

This circuit is used to control the following pins:
X11175 Connector: 13, 17, 19, 20, 21, 22, 23, 24, 26
X11176 Connector: 4, 5, 6, 7, 12, 13

5V to 12V Level Shifter

This circuit acts very similar to the basic pull-down network: If the Arduino applies 5V on the input of the circuit, Q6 will turn on (connect the cluster pin to 12V), and Q4 will turn off. If the Arduino applies 0V on the input of the circuit, Q6 will turn off, and Q4 will turn on (connect the cluster pin to ground). The 10 Ohm resistor was added to limit the current going into the pin the circuit is connected to.

This circuit is used to control the following pins: X11175 Connector: 2, 7 X11176 Connector: 14

KBUS Level Shifter

When the Arduino applies 0V to this circuit, Q7 turns off, and pulls the gate of Q9 up to 5V. This turns on Q9, and thus applies 0V to cluster pin 14. When the Arduino applies 5V to this circuit, Q7 turns on, and pulls the gate of Q9 down to ground. This turns off Q9, and thus pulls cluster pin 14 up to 12V. This circuit is used to translate the 5V 'Serial' messages coming from the Arduino to 12V message signals that the cluster expects to see.

Ignition and Accessory Mode Circuits

When the Arduino applies 5V to this circuit, it turns on Q31, which then pulls the gate of Q32 down to ground. Q32 is a PMOS transistor, and thus this turns the FET 'ON' which then applies 12V to the cluster pin. When the Arduino applies 0V to this circuit, it turns Q31 off, which then pulls the gate of Q32 up to 12V. This turns the FET 'OFF' which then pulls the cluster pin down to ground.

This circuit was used to control the ignition and accessory mode cluster pins (X11175 pins 5 and 6 respectively)

SPI -> CAN Circuitry

This circuit is a direct copy of the circuit used on the MCP2515 SPI to CAN development boards, such as this one:

Fuel Level Circuit

This circuit is known more commonly as a 'shunt-regulator' (similar to the popular TL431 part you can find available online). This circuit makes more sense when you consider what the circuit on the input of the cluster looks like for X11175 Pins 11 and 15 (Tank1+ and Tank2+ respectively):

image

In this more simplified circuit, I represent the digital potentiometer as a normal potentiometer, and show what the input of the cluster looks like for the Tank+ pins. The idea is that as we change the value of the potentiometer, the gain of the circuit changes and causes the voltage at the Tank+ pin to change accordingly.

For example:
If the potentiometer is set to 0 ohms, the tank+ pin will be set to roughly 0.65V. To the cluster, this would look just the same as connecting a 50 Ohm resistor from the pin to ground. In the case that the potentiometer is set to 5kOhms, the voltage at the take+ pin will be set to roughly 2.7 Volts, which looks just the same as if a 397 Ohms resistor was connected from the pin to ground.

In this sense, the circuit acts as a variable resistor that we can set from the Arduino ranging between about 50 Ohms and 397 Ohms, which covers the normal operating range for this pin of a resistance value between 70 Ohms and 395 Ohms (see table above for tank+ pins). In theory, the same circuit could have also been used for the ambient temperature sensor, but I chose against this since it did not change system performance at all.

Other Circuits

There are a few circuits in the design containing connectors, DIP switches, and other such items that I do not cover here as they are more self-explanatory, but if you would like to know about any other part of of the schematic design, please let me know.

Arduino Code

For this project, I provided two main programs: E46_Cluster_Test, and main-simhub-code. The following section outlines these two programs, as well as the communication protocol that is common to both programs:

E46_Cluster_Test

This program was created in order to perform basic tests on the cluster. After uploading this code, you can send commands from the serial monitor to the Arduino, and then the Arduino will interact with the cluster in order to carry out the desired function. You must send every command with the following syntax:

In addition, make sure the Arduino Serial monitor is setup as shown below (most importantly, have the baud rate set to 9600, and the line ending set to 'Newline'):

image

See the section Valid Command / Argument Combos for both programs for a list of commands that you can send to the cluster, along with the effect each one has.

main-simhub-code

This program was created in order to interface with the cluster through the computer software SimHub, which allows you to send data from racing games to an Arduino. This program receieves data from SimHub, and using the same methods as the E46_Cluster_Test program, sets the cluster up to reflect the sent data. You have to upload this program to the Arduino before attempting to use the SimHub application, or else it will hijack the serial port and not let you program the Arduino until you close the application.

In order to make this application work with the hardware, you need to do the following:

  1. Upload the main-simhub-code sketch to your Arduino
  2. Open SimHub, and Navigate to the following menu: Arduino -> My Hardware
  3. Confirm that there is a device connected in this menu
  4. Under the Custom Protocol for this device, paste in the contents of the JavaScript_Protocol.txt file, and be sure to check the Use javascript box
  5. Press OK at the bottom of the window

At this point, you should be able to launch games from the SimHub dashboard (ensure that you configure each game according to SimHub's instructions).

Valid Command / Argument Combos for both programs

The following is a list of valid commands and arguments that you can send to the instrument cluster from both applications. You can send these commands directly through the serial monitor for the E46_Cluster_Test program, or through a Custom Protocol in SimHub:

CommandValid ArgumentsDescription
speedInteger between 1 and 163Sets the speedometer to the desired value in MPH
rpmInteger between 0 and 7000Sets the tachometer to the desired value in RPM
tempInteger between 65 and 405Sets the oil temperature gauge to the desired value in degrees celcius
ignitionEither 1 or 0Turns the ignition state to on / off
accessoryEither 1 or 0Turns the accessory state to on / off
fuelInteger between 1 and 100Sets the fuel gauge to the desired value (have to cycle 12V power to cluster to change immediately)
engineStateFeedbackEither 1 or 0No noticeable effect
signalGongEither 1 or 0No noticeable effect
bc_buttonEither 1 or 0No noticeable effect
seatBeltEither 1 or 0No noticeable effect
coolantLevelSensorEither 1 or 0'0' causes the coolant light to come on, '1' turns it off (have to cycle ignition to change state)
brakeWearSensorEither 1 or 0'0' causes the brake pad wear light to come on, '1' turns it off
parkingBrakeStateEither 1 or 0'0' turns BRAKE light on, '1' turns it off
ABS_WarningEither 1 or 0'0' turns ABS light on, '1' turns it off
airbagLightEither 1 or 0'0' turns airbag light off, '1' turns it on
brakeFluidSensorEither 1 or 0No noticeable effect
oilSensorEither 1 or 0No noticeable effect
oilPressureSwitchEither 1 or 0No noticeable effect
clusterBacklightEither 1 or 0No noticeable effect
washerFluidLightEither 1 or 0'1' turns the light off, '0' turns it on (have to cycle ignition to change
cruiseLightEither 1 or 0
rolloverSensorEither 1 or 0
reverseEither 1 or 0
eLightEither 1 or 0'1' turns the Service Engine Soon light on, '0' turns off
emlLightEither 1 or 0'1' turns the EML light on, '0' turns off
gasCapLightEither 1 or 0'1' turns the CHECK GAS CAP light on, '0' turns off
heatLightEither 1 or 0'1' turns the over temperature light on, '0' turns off
oilLightEither 1 or 0'1' turns the low oil pressure warning light on, '0' turns it off
chgLightEither 1 or 0'1' turns the battery charge light on, '0' turns it off
highBeamEither 1 or 0'1' turns the highbeam indicator on, '0' turns it off
fogRearEither 1 or 0'1' turns the rear fog-light indicator on, '0' turns it off
fogFrontEither 1 or 0'1' turns the front fog-light indicator on, '0' turns it off
leftBlinkEither 1 or 0'1' turns the left blinker on, '0' turns it off
rightBlinkEither 1 or 0'1' turns the right blinker on, '0' turns it off
backRightLightEither 1 or 0'1' turns the light on, '0' turns it off
backLeftLightEither 1 or 0'1' turns the light on, '0' turns it off
frontRightLightEither 1 or 0'1' turns the light on, '0' turns it off
frontLeftLightEither 1 or 0'1' turns the light on, '0' turns it off
carLightEither 1 or 0'1' turns the light on, '0' turns it off

Parts

120
QtyValueFootprintReferences
27DMN67D8L-7Package_TO_SOT_SMD:SOT-23Q1, Q2, Q10, Q11, Q12, Q13, Q14, Q15, Q16, Q17, Q18, Q19, Q20, Q21, Q22, Q23 +11
21100Resistor_SMD:R_0603_1608MetricR18, R25, R28, R29, R30, R31, R32, R33, R34, R35, R36, R37, R38, R39, R40, R41 +5
2110kResistor_SMD:R_0603_1608MetricR1, R2, R16, R19, R20, R26, R43, R45, R46, R47, R48, R49, R50, R51, R52, R55 +5
50.1uCapacitor_SMD:C_0805_2012MetricC3, C6, C7, C8, C9
510Resistor_SMD:R_0603_1608MetricR11, R12, R23, R24, R44
5Conn_01x08_FemaleConnector_PinSocket_2.54mm:PinSocket_1x08_P2.54mm_VerticalJ1, J2, J3, J6, J7
5TP0610K-T1-E3Package_TO_SOT_SMD:SOT-23Q6, Q8, Q27, Q30, Q32
21kResistor_SMD:R_0603_1608MetricR3, R27
21uCapacitor_SMD:C_0805_2012MetricC1, C2
222pCapacitor_SMD:C_0603_1608MetricC4, C5
2604Resistor_SMD:R_0603_1608MetricR14, R15
2966Resistor_SMD:R_0603_1608MetricR9, R10
2Conn_01x09Connector_PinHeader_2.54mm:PinHeader_1x09_P2.54mm_VerticalJ11, J12
2Conn_01x13Connector_PinHeader_2.54mm:PinHeader_1x13_P2.54mm_VerticalJ10, J13
1100kResistor_SMD:R_0603_1608MetricR22
1120Resistor_SMD:R_0603_1608MetricR17
1200kResistor_SMD:R_0603_1608MetricR21
18 MHz# Custom Crystals:Crystal_SMD_5032-4Pin_5.0x3.2mmY1
190.9kResistor_SMD:R_0603_1608MetricR5
1Conn_01x10_FemaleConnector_PinSocket_2.54mm:PinSocket_1x10_P2.54mm_VerticalJ5
1Conn_02x09_Top_Bottom# Custom Connectors (2.00 mm):PinHeader_2x09_P2.00mm_Vertical_SMD_Top_Bottom;98424-G52-18ALFJ9
1Conn_02x13_Top_Bottom# Custom Connectors (2.54 mm):3020-26-0300-00J8
1Conn_02x18_Odd_EvenConnector_PinSocket_2.54mm:PinSocket_2x18_P2.54mm_VerticalJ4
1MCP2515-xSOPackage_SO:SOIC-18W_7.5x11.6mm_P1.27mmU5
1MCP4251-xxxx-STPackage_SO:TSSOP-14_4.4x5mm_P0.65mmU1
1MCP6002T-I/SNPackage_SO:SOIC-8_3.9x4.9mm_P1.27mmU4
1SW_DIP_x04Button_Switch_SMD:SW_DIP_SPSTx04_Slide_9.78x12.34mm_W8.61mm_P2.54mmSW2
1SW_MEC_5EButton_Switch_SMD:SW_SPST_Omron_B3FS-101xPSW1
1SolderJumper_2_OpenJumper:SolderJumper-2_P1.3mm_Open_Pad1.0x1.5mmJP1
1TJA1050T-3Package_SO:SOIC-8_3.9x4.9mm_P1.27mmU6
1TL431DBZPackage_TO_SOT_SMD:SOT-23U2

Similar boards

  • 6 layers121 × 83 mmPS2 79004 Rev 0 4, the printed circuit board in 3D

    PS2 79004 Rev 0 4

    tschicki/PS2-Portable

    A custom designed PS2 Portable

    770 parts207MIT
  • 4 layers85 × 56 mmAnthC, the printed circuit board in 3D

    AnthC

    Anthilla/AnthC

    Anthilla AnthC Board

    211 parts40
  • 2 layers50.5 × 128.5 mmOpenThereminV45, the printed circuit board in 3D

    OpenThereminV45

    GaudiLabs/OpenThereminV4

    Open Source Theremin Instrument

    107 parts249GPL-3.0
  • 2 layers223.5 × 160 mmBase, the printed circuit board in 3D

    Base

    bread-modular/bread-modular

    Modular Synths for Everyone

    201 parts67MIT
  • 4 layers79 × 39.1 mmConnector pcb, the printed circuit board in 3D

    Connector pcb

    festlv/mso5000-logic-probe

    Cheap logic probe for Rigol MSO5000-series oscilloscopes

    39 parts37MIT
  • 2 layers120 × 80 mmSpikeling v3.2, the printed circuit board in 3D

    Spikeling v3.2

    OpenSourceNeuro/Spikeling

    A hardware implementation of spiking neurons for neuroscience teaching and outreach

    233 parts21GPL-3.0
  • 2 layers98.7 × 98.7 mmEEE3088F Team-9, the printed circuit board in 3D

    EEE3088F Team-9

    davidbits/EEE3088F-Team-9

    63 partsCC-BY-4.0
  • 6 layers165 × 99.5 mmOscilloscope, the printed circuit board in 3D

    Oscilloscope

    eriklind90/oscilloscope_PCB

    196 parts

Questions

How big is the BMW E46 Cluster Interface Board PCB?

It measures 101.6 × 53.3 mm and has 2 copper layers, 1.6 mm thick.

What parts does the BMW E46 Cluster Interface Board use?

120 parts, built around the MCP6002T-I/SN(MS), DMN67D8L-7 and TP0610K-T1-E3. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the BMW E46 Cluster Interface Board KiCad files?

From the KSullivan20221/SimHub-BMW-E46-Cluster-Module repository on GitHub, at the commit this page was made from: the board is KiCAD Project/BMW E46 Cluster Interface Board.kicad_pcb. PCBKit opens the board in the browser, with nothing to install.

Can I use the BMW E46 Cluster Interface Board design in my own project?

Its repository states no licence, so its author keeps all rights: ask KSullivan20221 before reusing the design.