Getting to know CAN
For a few weeks already I’m looking into the topic of CAN-bus. It’s BMW’s (and many other car manufacturer’s) electronic-bus. Basically all info runs over that bus, however it is devided in multiple sections which are separated by gateways.
If I could tap into that bus I eventually could be able to not only read all the info that’s being passed on there, I could also send my own data on its way, controlling various stuff.
Luckily, some people already had the same idea and started getting into this, also already decoding various messages. Two weeks ago I bought the PiCAN2 board by SK Pang on Amazon for around 35€ with some discount I had on Amazon. Otherwise -at least for Germany – a different shop would’ve made more sense. SK Pang itself offers manuals how to set up the device. Everything you need will be provided my them. The only issue I ran into was the baud-rate which must be 100kbit/s instead of 500kbit/s for K-CAN, which we are working with here.
The hardware setup also was no issue at all. I’d tapped into CAN_L and CAN_H anyways already during my reverse cam installation. The process is not covered there, however, this source seems accurate from what I remember. Since this device is a HAT, meaing it covers all pins on the Pi, I installed a second one which is used just for the CAN-business. I connected both with a short LAN cable so they can communicate. I’ll try to reduce everything to one device again at some point of time since, obviously, power consumption doesn’t exactly go down by this.
After setting everything up and starting the program by SK Pang, one can expect around 180 messages per second – with the ignition being off (but units ‘alive’).
The most valuable source surely is Trevor Cook who obviously spent quite some time experimenting around on his E84. Many of these codes also work on my E60 which made it rather easy for me. I created a Google Doc to keep track of what I know.
As of now I spotted 130 unique IDs where only a fraction of it could be decoded.
The tool ‘cansniffer’ makes it a lot easier but it’s still some work – also because no one fully knows what’s on that bus.
Processing is done completely in Bash – just because I’m familiar with it.
Since the Raspberry Pi doesn’t really care about your preference regarding this one may use pretty much any programming language.
At the moment I’m mainly able to read various values from my car. Here’s an example of data I’m able to pull:
|Wheel position||7.48° Right|
|Door status||All doors closed, trunk closed, locked|
Obviously one can also send stuff, most of it can be seen in the table in the paragraph above – namely everything which is green.
Important for reading is the so-called wakeup call: 130#22.214.171.124F.FE
It simulates turning on the ignition and waking up some, if not all control units for a few seconds.
However, it must be sent permanently while reading data.
Currently I have an issue that the head lights turn on, but not off again after dark, since the light is switched to automatic. I’m ‘solving’ this by just not reading data at night, for now.
I’m also able to (un-)lock via my phone (however it’s still quite complicated – over SSH).
Currently I’m looking for a way of controlling the roof and windows, as well as the horn.
I spent quite some time looking for those codes, to the point that i fear they might not even be on that bus. I already read that it might not be possible to control them but I don’t even find the button-singal when manually pressing it.
Since I’m able to control the windows and roof via the key remotely it must be some signal there.
Also, I didn’t find out yet if it’s possible to control the left and right head beams individually.
In the end I’d like a nice (un-)lock-routine, flashing some lights and stuff.
But using the key is easy – I’d like to use something like NFC with my phone. Obviously, there’s quite some security risk to it so I’m thinking about that one a bit longer before testing something.
However: The less is known about a system, the safer it is.
In the distant future I’d like to also work on PT_CAN, which is kinda the engine-bus.