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:
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
Post a Comment