Introduction: Hack Your Vehicle CAN-BUS With Arduino and Seeed CAN-BUS Shield

Modern Vehicles all come equipped with a CAN-BUS Controller Area Network, Instead of having a million wires running back and forth from various devices in your car to the battery, its making use of a more clever system.

All electronic functions are connected to the TIPM, (Totally integrated Power Module), such as solenoids/relays to lock the doors or mini motors to wind the windows ect ect.

From each node (IE Switch pod that controls your windows or electric door locks) it broadcasts a message across the CAN. When the TIPM detects a valid message it will react accordingly like, lock the doors , switch on lights and so on.

WHY?
Because you can :-)

What you need.
Arduino UNO + Seeed CAN-BUS Shields
You can get the CAN-BUS Shield from SeeedStudio.com

Step 1: Setting Up an Interface for Connecting Your Laptop.

The Seeed CAN-BUS Shield has a header dedicated for the CAN-High (+) and CAN-Low (-)

Obviously all vehicles aren’t the same so the location to tap into the CAN-BUS will differ from vehicle to vehicle.
In this instructable I’m using a Jeep Wrangler (AKA Jeep JK) 2010, Rubicon 2DR , with a manual shifter.

The easiest way into the bus is to connect into the radio, at the back of the radio it has a White/Orange (- CAN-L) and White Grey ( + CAN-H ) wire. From there I routed the cable through to the glove box of the Jeep.

Step 2: Programming the Arduino to Accept Messages From the CAN-BUS

First of all you need the Seeed CAN-BUS Shield’s Library downloadable at GIT-HUB

After downloading the CAN-BUS Library you need to import it into your Arduino Libraries folder.
In the Arduino Editor Select Sketch --> Import Library --> Add Library and then point it to the Zip file you downloaded, (No need to unzip the contents it can be imported as is.

Tip: You might have to rename the zip as the Arduino IDE does not like unusual characters , so maybe try canbus.zip instead of can-bus.zip

Something important to note:

The CAN-BUS Shield library comes with a working example, it does not include getting the CAN-ID which is quite important to know when analysing the data, So i modified it slightly to include the ID also to seperate all values with a comma so that you can use it as a csv file.

Copy and paste the below code into your Arduino Sketch Editor.

#include "mcp_can.h"<br>
INT32U canId = 0x000;
unsigned char len = 0;
unsigned char buf[8];
char str[20];

void setup()
{    
Serial.negin(115200);
START_INIT:
if(CAN_OK == CAN.begin(CAN_125KBPS))
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        delay(100);
        goto START_INIT;
    }
}
void loop()<br>{
    if(CAN_MSGAVAIL == CAN.checkReceive())
    {
        CAN.readMsgBuf(&len, buf);
        canId = CAN.getCanId();
        
        Serial.print(canId);Serial.print(",");
        for(int i = 0; i<len; i++)
	{
		Serial.print(buff[i]);Serial.print(",");
	}
	Serial.println();
   }
}

Hit the upload button to upload the sketch.

Step 3: Connecting to the Arduino + CAN-BUS Shield to Get CAN Data

Now you need to make sure the CAN-BUS Shield has been connected to the vehicle's CAN-BUS, via the CAN-H & CAN-L Connector.

If you are sure everything has been connected then use putty to connect to the shield via Serial.

Putty is actually a SSH Client but can also handle serial data and it works great for this purpose.

Look at the Image attached to this step for the Serial port configuration.

Once you connect, Your vehicle's CAN-BUS will bombard putty with CAN-BUS Data.

Step 4: Analyze the Data

From here you need to figure out how to detect the messages, such as turning on lightts, open windows ect ect.

When connecting with putty you can log all incomming data to file as explained in the screenshot from the previous step.

Connect and log to a file called file1.csv and let it run with all windows closed, vehicle's key in on position but not started, and let it run for about 5 minutes, Kill the putty session, then restart the Arduino (The Sketch does not clear the buffer), And this time log all data to file2.csv , once putty starts duming data, quickly press a buton (Only one at a time cus you will not know which message goes to which button), once you pressed a button a few times quickly disconnectputty from the can bus.

So theoretically all messages in File2.csv thats also in File1.csv should be ignored/filtered the messages thats left over in File2.scv should be the message button presses.

If you have some programming skills you might find a better way to manage this.
I cretated a basic application in VB6 , you can look for more information about the tool on my Blog
Unfortunatly the application is a bit incomplete, eventhough it has the capability to connect directly to the Arduino Via Serial it doesnt work propperly, so please ignore the Serial Connection part.

It will basically take the fisrt file run which you were dumping data for ~5 Minutes (ignoredatabase.can) and incomming.can as the log file which includes button presses.

I encourage you to find a better way to analyse the data as this can be very stime consuming.

Step 5: Sending a Message Into the CAN-BUS

To send a message into the CAN-BUS is pretty straight forward.

The below will send the "Sway-Bar" disconnect on a Jeep Wrangler.

Note the CAN-ID needs to be converted into HEX format, an easy way to convert it is to use the Windows Calculator, Using "Programmer Mode" for Windows 7 Calculator

From the below code you can see its sending it to CAN-ID 2B0 = 688

#include <mcp_can.h><br>#include <spi.h></spi.h></mcp_can.h>
void setup()
{
    Serial.begin(115200);
  
START_INIT:
    if(CAN_OK == CAN.begin(CAN_125KBPS))                   // init can bus : baudrate = 500k
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        delay(100);
        goto START_INIT;
    }
}
void loop()
{
    unsigned char stmp3[4] = {3, 0, 3, 0};
    CAN.sendMsgBuf(0x2B0, 0, 4, stmp3);  
    delay(10000); 
     
}

Step 6: A Prototype Built Using the Information From This Instructable

Not going into much detail, this is just to show you whats possible.

This Arduino + Seeed CAN-BUS Shield has an added feature, I built a Button & 4 LED Display.
When pressing the red button it will cycle through all posible LED states and each state represents a feature.

Pressing the yellow button will send the message to the bus.