CAN Bus first attempt

As mentioned previously, I setup the Can-Bus v1.2 Shield and plugged it into my 2016 Mercedes c200 using the OBD-II cable.

I downloaded the Canbus library from HERE.  Actually there was more code, but I was only interested in the Canbus.h/cpp library files for the Arduino.  The sample they have includes SDCards, GPS, LCD screen and all I wanted was the simple stuff to start off with.  Probably end up going the whole hog, but, small steps...

I wrote the following simple code:

#include <Canbus.h>

char buffer[512];  //Data will be temporarily stored to this buffer before being written to the output

void setup() {
  Serial.begin(9600);
  Serial.println("ECU Reader");  /* For debug use */
  if(Canbus.init(CANSPEED_500))  /* Initialise MCP2515 CAN controller at the specified speed */
  {
    Serial.println("CAN Init ok");
  } else
  {
    Serial.println("CAN'T init ok");
  }    
  delay(1000); 
}


void loop() {
  if(Canbus.ecu_req(ENGINE_RPM,buffer) == 1)          /* Request for engine RPM */
  {
    Serial.println("ENGINE RPM");
    Serial.println(buffer);    
  } 
   
  if(Canbus.ecu_req(VEHICLE_SPEED,buffer) == 1)       /* Request for vehicle KM */
  {
    Serial.println("VEHICLE SPEED");
    Serial.println(buffer);
  }
  
  if(Canbus.ecu_req(ENGINE_COOLANT_TEMP,buffer) == 1) /* Cooland temperature */
  {
    Serial.println("ENGINE COOLANT TEMP");
    Serial.println(buffer);   
  }
  
  if(Canbus.ecu_req(THROTTLE,buffer) == 1)            /* How much you pressed the pedal down */
  {
    Serial.println("THROTTLE");
    Serial.println(buffer);
  }  
   delay(100); 
}


Plugged in the Arduino and then watched the Serial output:

---------------------------
ECU Reader
CAN Init ok
ENGINE RPM
0 rpm 
ENGINE RPM
0 rpm 
ENGINE RPM
0 rpm 
ENGINE RPM
0 rpm 
ENGINE RPM
0 rpm 
ENGINE RPM
179 rpm 
ENGINE RPM
1536 rpm 
ENGINE RPM
1500 rpm 
ENGINE RPM
1493 rpm 
ENGINE RPM
1385 rpm 
ENGINE RPM
1260 rpm 
ENGINE RPM
1185 rpm 
ENGINE RPM
1163 rpm 
ENGINE RPM
1153 rpm 
ENGINE RPM
1145 rpm 
ENGINE RPM
1143 rpm 
ENGINE RPM
1170 rpm 
THROTTLE
15 % 
ENGINE COOLANT TEMP
17 degC
ENGINE RPM
1119 rpm 
ENGINE COOLANT TEMP
18 degC
ENGINE RPM
1084 rpm 
ENGINE RPM
1107 rpm 
ENGINE RPM
1023 rpm 
ENGINE RPM
1001 rpm 
ENGINE RPM
1001 rpm 
ENGINE RPM
981 rpm 
ENGINE RPM
994 rpm 
ENGINE RPM
980 rpm 
ENGINE RPM
982 rpm 
ENGINE RPM
979 rpm 
THROTTLE
14 % 
ENGINE COOLANT TEMP
20 degC
ENGINE RPM
986 rpm 
ENGINE RPM
986 rpm 
ENGINE RPM
983 rpm 
ENGINE RPM
976 rpm 
ENGINE RPM
969 rpm 
ENGINE RPM
982 rpm 
THROTTLE
13 % 
ENGINE RPM
971 rpm 
ENGINE RPM
951 rpm 
ENGINE COOLANT TEMP
22 degC
ENGINE RPM
948 rpm 
THROTTLE
13 % 
ENGINE RPM
961 rpm 
ENGINE COOLANT TEMP
22 degC
ENGINE RPM
1039 rpm 
ENGINE RPM
1038 rpm 
ENGINE RPM
1008 rpm 
ENGINE RPM
973 rpm 
ENGINE RPM
956 rpm 
ENGINE COOLANT TEMP
23 degC
ENGINE RPM
916 rpm 
ENGINE RPM
914 rpm 
ENGINE RPM
897 rpm 
ENGINE RPM
894 rpm 
ENGINE RPM
883 rpm 
ENGINE RPM
881 rpm 
ENGINE RPM
1844 rpm 
ENGINE RPM
1423 rpm 
ENGINE COOLANT TEMP
25 degC
ENGINE RPM
1024 rpm 
ENGINE RPM
941 rpm 
ENGINE RPM
883 rpm 
ENGINE RPM
1096 rpm 
ENGINE RPM
1311 rpm 
VEHICLE SPEED
0 km 
ENGINE RPM
1043 rpm 
ENGINE RPM
928 rpm 
ENGINE RPM
897 rpm 
ENGINE RPM
863 rpm 
ENGINE RPM
857 rpm 
ENGINE COOLANT TEMP
27 degC
ENGINE COOLANT TEMP
27 degC
THROTTLE
12 % 
ENGINE RPM
860 rpm 
ENGINE RPM
856 rpm 
ENGINE RPM
858 rpm 
ENGINE RPM
860 rpm 
THROTTLE
12 % 
ENGINE RPM
851 rpm 
ENGINE RPM
842 rpm 
THROTTLE
12 % 
ENGINE COOLANT TEMP
28 degC
ENGINE RPM
829 rpm 
ENGINE RPM
826 rpm 
ENGINE RPM
829 rpm 
THROTTLE
12 % 
ENGINE RPM
827 rpm 
ENGINE RPM
827 rpm 
ENGINE RPM
825 rpm 
ENGINE RPM
831 rpm 
ENGINE RPM
828 rpm 
ENGINE RPM
812 rpm 
ENGINE RPM
816 rpm 
VEHICLE SPEED
0 km 
ENGINE RPM
818 rpm 
ENGINE RPM
814 rpm 
ENGINE RPM
817 rpm 
ENGINE RPM
821 rpm 
ENGINE RPM
819 rpm 
ENGINE RPM
818 rpm 
THROTTLE
11 % 
ENGINE RPM
808 rpm 
ENGINE RPM
807 rpm 
ENGINE COOLANT TEMP
30 degC
ENGINE RPM
810 rpm 
---------------------------

Yaaay!  It's alive.  We can get proper, realistic data from the car.

The following C Header file shows the HEX values of the PID that we are currently listening for:

As per the list HERE, you can see how they tally up, ie. 0x0C = ENGINE_RPM.

The nice thing about this library is that the author has done some work for you already in relation to turning the data values received into a value that is meaningful:


For instance, the ENGINE_RPM is shown as:

That translates in the C code:

case ENGINE_RPM:   //   ((A*256)+B)/4    [RPM]
engine_data =  ((message.data[3]*256) + message.data[4])/4;
sprintf(buffer,"%d rpm ",(int) engine_data);
Now, you can start to get creative and add more sensors to read and using the OBD-II PID guide, we can add the required formulas in code.  As has been said, 1,000,000 times before, the car manufacturers do use these basic PID codes, but they also use custom ones and obviously their own formulas too.

We can change the Arduino code to just dump out everything is hears on the Can-Bus:

void loop()
{ 
tCAN message;

if (mcp2515_check_message()) 
 {
    if (mcp2515_get_message(&message)) 
 {
               Serial.print("ID: ");
               Serial.print(message.id,HEX);
               Serial.print(", ");
               Serial.print("Data: ");
               for(int i=0;i<message.header.length;i++)
                {
                  Serial.print(message.data[i],HEX);
                  Serial.print(" ");
                }
               Serial.println("");
             }}
}

One idea would be to have a trigger (button press?) and then perform a specific action in the car, such as open drivers window, then press the trigger again.  Then analyse the data captured to work out what the codes were that were opening the window.
Then...get adventurous and call the sendMessage() command to the car CanBus to tell it to open the window.

Right, enough playing around with the Mercedes, I now need to test this on the 2001 MG F and see if I can get anything useful from that car!

Comments