Playing with CAN bus

I got inspired by comma.ai – it’s a HW device which will drive your car, pretty much like Tesla does but for a fraction of it’s price. For this, it needs to connect to CAN bus of your car. My current car cannot be driven by wire but it has some simple CAN buses so I decided to have a little play with one of them, just to explore the technology.

First of all, I did some research and found a simple guide to CAN buses in my car (only czech version). According to this, the bus should be a standard CAN with 62.5kbps, so it should be possible to do some experiments.

Hardware

I wanted to see the data from the CAN bus in my computer. My first choice was STM32F103 which has an integrated CAN controller but later on I found out that it cannot be used simultaneously with USB controller so my search continued.

I’ve found that ESP32 has a CAN interface too so I ordered a 3V3 compatible CAN transceiver module SN65HVD230  and assembled a simple prototype board:

Finding the right wires

Next challenge was to find and hookup the correct wires in my car. I didn’t want to disassemble doors or some other complicated parts so I Iooked for a pinout of a comfort unit under my steering wheel which is more or less accessible. I was able to find this post which also has a nice picture of the comfort unit so I knew what to search for and which pins (6 and 9) to hookup.

Cable colours were different but after probing with scope the signal was there.

I’ve built an example project for esp32 CAN and went for a first test.

First test

After connecting the module to prepared wires, no packets were received. So I measured the wires again to see the signal.

This didn’t look like a differential pair, moreover not even like 62.5kbps but rather 100kbps. After some more tests I went back to my research.

Proper documentation

After some search I’ve found an another documentation, this time for Volkswagen group’s CAN bus. And this was some interesting reading!

First of all, I found out that 62.5kbps is not used anymore in comfort buses after year 2000 (page 4), it was replaced with 100kbps which was in match with my measurements.  Next point was diagnosing errors on the bus. I’ve found an example fault (page 50) which was describing my situation: identical signal on both wires caused by a short between bus wires. This led me to a possible cause: 120 Ohm terminator in my CAN transceiver module. After removing it, the signal returned back to differential:

After this, my module also started to receive packets:

New standard frame from 0x00000151, DLC 4, Data 0x00 0x00 0xF8 0xF8 
New standard frame from 0x00000591, DLC 3, Data 0x47 0x00 0x8B 
New standard frame from 0x00000371, DLC 1, Data 0xC0 
New standard frame from 0x00000601, DLC 1, Data 0x00 
New standard frame from 0x00000401, DLC 6, Data 0x02 0x01 0x00 0x00 0x00 0x00 
New standard frame from 0x00000353, DLC 8, Data 0x80 0x00 0x00 0x4F 0x00 0x02 0x00 0x00 
New standard frame from 0x00000635, DLC 3, Data 0x00 0xFF 0x00 
New standard frame from 0x00000351, DLC 8, Data 0x80 0x00 0x00 0x01 0x00 0x7D 0x7D 0x00 
New standard frame from 0x00000402, DLC 6, Data 0x03 0x01 0x00 0x00 0x00 0x00 
New standard frame from 0x00000551, DLC 1, Data 0x02 
New standard frame from 0x00000621, DLC 3, Data 0x00 0x72 0x6D 
New standard frame from 0x000005C3, DLC 2, Data 0x00 0x00 
New standard frame from 0x000003B5, DLC 5, Data 0x80 0x00 0x00 0x8C 0x04 
New standard frame from 0x000002B1, DLC 2, Data 0x05 0x00 
New standard frame from 0x00000381, DLC 5, Data 0x00 0x0C 0x00 0x8C 0x04 
New standard frame from 0x00000281, DLC 2, Data 0x05 0x00 
New standard frame from 0x00000293, DLC 2, Data 0x15 0x01 
New standard frame from 0x00000271, DLC 1, Data 0x03 
New standard frame from 0x00000151, DLC 4, Data 0x00 0x00 0x48 0x48 
New standard frame from 0x00000403, DLC 6, Data 0x08 0x01 0x00 0x00 0x00 0x00 
New standard frame from 0x00000353, DLC 8, Data 0x80 0x00 0x00 0x4F 0x00 0x02 0x00 0x00 
New standard frame from 0x00000408, DLC 6, Data 0x01 0x01 0x00 0x00 0x00 0x00 
New standard frame from 0x00000351, DLC 8, Data 0x80 0x00 0x00 0x01 0x00 0x7D 0x7D 0x00 
New standard frame from 0x000005C3, DLC 2, Data 0x00 0x00 
New standard frame from 0x00000621, DLC 3, Data 0x00 0x72 0x6D 
New standard frame from 0x000003B5, DLC 5, Data 0x80 0x00 0x00 0x8C 0x04 
New standard frame from 0x000002B1, DLC 2, Data 0x05 0x00 
New standard frame from 0x00000381, DLC 5, Data 0x00 0x0C 0x00 0x8C 0x04 
New standard frame from 0x00000281, DLC 2, Data 0x05 0x00 
New standard frame from 0x00000293, DLC 2, Data 0x15 0x01 
New standard frame from 0x00000271, DLC 1, Data 0x03 
New standard frame from 0x00000151, DLC 4, Data 0x00 0x00 0x98 0x98 
New standard frame from 0x00000591, DLC 3, Data 0x47 0x00 0x8B 
New standard frame from 0x00000371, DLC 1, Data 0xC0

Then I have modified the code to be able to easily extract packets and work with them in python. I captured a few events with notes on what has been done (closing doors, locking, etc.) so I could try to decode the messages.

Sending messages

I wanted to create a PoC smartphone controled central locking. I changed the code to allow sending messages out of my PC with my python script.

$ ./client.py 02811500
UDP target IP: 192.168.4.1
UDP target port: 3333
03b5 8200000c04
0293 0101
0591 47048b
0293 0201
0591 47018b
03b5 8600000c04
02b1 0100

I tried to resend a few of the received messages and some of them really locked doors. The problem was with controlling of all doors. The lock signal worked only for three doors and the trunk. I think, this is because if you lock left front door with a key, the signal is sent to the other doors but in the same doors it is processed internally. So I also captured signals after locking with key in the right front doors and it had a different message ID.

  • locking from LF door: 0x0281 8100
  • locking from RF door: 0x02b1 8100

So my solution was to send both of these signals so I changed the code, included a webserver and tested  it.

You can see  it in action here:

It works so-so but as a PoC it’s enough. My next car will be definitely one with an electromechanical power steering which can be controlled via CAN so I can make some experiments with autonomous driving. As a teaser for this technology you can watch this video:

If you have any questions on comments, feel free to ask.

Bye!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.