BMW E9x K-CAN-bus hacking with Arduino & MCP2515

Hi there!

Lately i’ve been busy working on a way to get some relevant information (like RPM, throttle position, torque, coolant temp. etc) from my 320d, as i want to build my own “info-screen” which will be displayed on the iDrive-display of my car.
The best way to get extensive amount of engine operational data on any E6x/E8x/E9x would surely be to hack into the DME/DDE K-Line and send BMW-specific polls (in the same way that INPA/ISTA/Testo works using EDIABAS), and at first i tried to go that way, but couldn’t get the communication between my Raspberry Pi and the DDE6.0 on K-Line to work, so i decided to try the K-CAN-bus instead. It turned out to be really simple, using only an Arduino and an MCP2515-CAN-module.

My setup

  • Arduino Mega2560
  • MCP2515 CAN-module
  • some jumper wires



I use the Mega2560 for testing, but if i’m about to mount one permanently, i will switch to a smaller board. I usually go for the Arduino Pro Mini, which is small in size but has a decent amount of I/O and is easy to program with an USB-to-TTL-programmer. The MCP2515 uses SPI, so it can be connected to about all Arduino-models, only pin numbers will be different.

The finished wiring looks like this:

Next, off to find a suitable spot to tap into the K-CAN-bus. I used the wiring at the iDrive-display power connector because i already was familiar with removing the display (really simple, undo 2x TX10 screws and the screen pops out). There are surely other better spots to tap into the wiring, but this is one way to do it.

Wiring for the arduino (Black/Red cable) tapped into the K-CAN.
CAN H+ Green/orange, CAN L- Green:

Screen back in, ready to be tested:


Next, the Arduino needs the correct software. Fortunately, there are many suitable CAN-libraries online that seem to work with the MCP2515. I used Cory J Fowlers MCP_CAN_lib. There is an example sketch in the library called CAN_receive which will work on the BMW K-CAN-bus with some minor modifications.

MCP_CAN CAN0(10); // Set CS to pin 10
MCP_CAN CAN0(53); // Set CS to pin 53
Because i’m using pin 53 on the Arduino Mega2560 for CS.

if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
if(CAN0.begin(MCP_ANY, CAN_100KBPS, MCP_8MHZ) == CAN_OK)
Because the bus on my pre-LCI E91 is 100kb/s K-CAN (the newer ones from 2007 onwards have D-CAN @ 500kb/s). The frequency change from 16MHz to 8MHz is because my MCP2515-chip has an 8MHz oscillator, your module could be different.

After sketch was uploaded and ignition turned on, there was a nice continous stream of K-CAN-bus data on my serial terminal.

Standard ID: 0x130 DLC: 5 Data: 0x41 0x51 0x2D 0x00 0x01
Standard ID: 0x0AA DLC: 8 Data: 0xAD 0x81 0xFC 0x00 0x00 0x00 0x84 0x00
Standard ID: 0x1B8 DLC: 6 Data: 0x0F 0xC0 0x83 0x02 0xA0 0x21
Standard ID: 0x4A7 DLC: 8 Data: 0x40 0x52 0xFF 0x01 0xFF 0xFF 0xFF 0xFF
Standard ID: 0x1A6 DLC: 8 Data: 0x00 0x00 0x00 0x00 0x00 0x00 0x60 0xF8
Standard ID: 0x0C0 DLC: 2 Data: 0xFE 0xFF
Standard ID: 0x1B8 DLC: 6 Data: 0x0F 0xC1 0x83 0x02 0xA0 0x21
Standard ID: 0x349 DLC: 5 Data: 0x90 0x1A 0x9A 0x20 0x00
Standard ID: 0x1B4 DLC: 8 Data: 0x00 0xC0 0xE2 0xF9 0x00 0x30 0xFC 0x80
Standard ID: 0x0CE DLC: 8 Data: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Standard ID: 0x1A0 DLC: 8 Data: 0x00 0x80 0x00 0x00 0x80 0x00 0xC8 0x6B
Standard ID: 0x1D0 DLC: 8 Data: 0x61 0xFF 0x42 0xC5 0x00 0x00 0xCD 0xB0

I was surprised how much data is actually passing through all the time!
So how about interpreting the data? That’s something i will write about later. 😉

If you’re in a hurry, this site will get you started in understanding the data in the K-CAN-bus.


Related Posts


    • Reply

    Hi, my name is Alexandre Cruz, i’m from Brazil, and i’m interesting in do it with my CAr, a Fiat Palio.
    i’m have buy a MCP2515 from, and it’s similar yours, i try to cath information but it’s conect to MCP alwright, but don’t receive any information.

    • Reply

    Thank you very much for sharing you project! I am trying to build a dash for my standalone ecu and I have tried many examples without success but yours works. You helped me a lot! I am waiting to see more about your project and learn how to use all the data .

      Hi! Very pleased to hear that my post helped you 🙂 At the moment i’m actually playing around with a standalone ECU (MaxxECU) and the MCP2515, also building a little dash on my E36. I will make a post about that when it’s finished. 🙂

    • Reply

    Hello admin! MaxxECUs are great, especialy in Can Bus. I am using an Ecumaster EMU and still trying to use all the data – I started using arduino a few months ago and my skills in programming these boards are basic. So I am waiting for your update when your project is done! Thank you very much ?

    • Reply

    Hi K-Blogger,

    I drive an BMW 520d E60, built in 2008.
    I started a similar project using Arduino Nano, mcp2515 and SSd1306 Display.
    My luck is I discovered your page randomly.)) Your project are very nice, maybe you can help me, if I’ll get some difficulties.
    It would be very cool, if you contact me via Email.)

    Best regards from Germany

    Alex 😉

    • Reply

    Hi, have you finished project on e36? Really interested.

      Well, i’ve finished it a couple of times now, many modifications done 🙂 I will try to write some updates on the project soon.

    • Reply

    Good work.
    K-can is always 100 kbit/sec. It is not model relative.

      This was a nice fact, thank you for making me wiser! 🙂 So, K-CAN = 100kb/s, D-CAN = 500kb/s.

    • Reply

    I’m trying to set the rpm/velocity dials from a e92, but it’s not working? is it possible the cluster is expecting messages at a certain rate, otherwise it’ll ignore? perhaps the baud rate is different for this k-can?

      It most certainly can be a speed-related problem. Have you tried 500kb/s, as your car is a E92, it probably is 2008 or newer and uses D-CAN?

    • Reply

    I’m also using the MCP2515 with a bmw e92 cluster!

    Have you had any luck sending velocity information to the panel? Can’t figure out the how to translate the velocity into can data. Maybe my ID is not the same as what loopbunny shows?

      Haven’t really tried to send any data to the cluster, but as i mentioned in the other comment, try 500kb/s, maybe it’s D-CAN. 🙂

Leave a comment

Hey, so you decided to leave a comment! That's great. Just fill in the required fields and hit submit. Note that your comment will need to be reviewed before its published.