Hacking and processing CAN data

Hi everyone,

Is it possible to program the Arduino board with a small application which performs some calculations with the CAN data read from the OBD layer in real-time.

Does Arduino support this kind of applications ?

Thanks in advance

Hi,
yes that´s possible. The OBD-Plug can be used with a serial port.
But you will have a small delay, because you have to ask for a specific value. From my tests you are able to receive about 4 values per second.

It´s very important with which vehicle you´d like to communicate, because the initialization process differs. And probably the commands, either.

To get the values directly from the CAN, which permanently transfers the data, you can use the CAN-BUS-Shield. This will be the easiest way.

Hi Trib,

Thanks for your reply.

Yes, I am using the CAN Bus Shield V1.2 for my project. So, I guess I am in the correct path for now.

However, I would like to extract few data from engine controller such as engine speed, engine load throttle position. As CAN transfers the 8-bit data, I want to process only 4th and 5th bit of the 8-bit data since it carries the actual data.

Did you face the similar problem in your project? If yes, how did you manage to do that?

Thanks in Advance

Yes, that should make the deal :slight_smile:

I thought the Library comes with the correct calculations and stuff. But maybe there are different Libraries?

Some return values include one or two bytes. Then there is the correct calculation, which you can found here.

For example you want to get the RPM (0C), the request looks similar to that one:
80 11 F1 02 21 0C AE
The Response will be like that:
80 F1 11 04 61 0C 0F 84 83
Now you can take the values and calculate the result easily:
(256 * responseArray[6] + responseArray[7]) / 4

But i would reccomend not to invent the wheel by yourself. There are plenty of codes, which already done that already.
Just take a look on GitHub. Seeduino got a lot of examples there.
GitHub/Seeed-Studio

Thank you Trib. I will look into the links that you have sent.

In case if I need any help I will post here, hoping that you would reply :slight_smile:

If you don't mind could you leave your mail ID here so that i can contact you directly.

Thank you once again.

Hi Trib,

Is it possible to read several CAN messages in one go?

For example, see the attached code

unsigned char rpl[8] = {0x04, 0x01, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00}; // Message request for engine rpm and engine load

unsigned char sptrq[8] = {0x04, 0x01, 0x0D, 0x61, 0x62, 0x00, 0x00, 0x00}; // request for Vehicle speed, desired and actual torque

unsigned char thr[8] = {0x03, 0x01, 0x11, 0x49, 0x00, 0x00, 0x00, 0x00}; // request for throttle position and accelerator pedal position.

void loop()
{
if(flagRecv)
{ // check if get data

flagRecv = 0; // clear flag

while (CAN_MSGAVAIL == CAN.checkReceive())
{
CAN.sendMsgBuf(0x7DF, 0, 8, rpl);
CAN.readMsgBuf(&len, rpm);

Engine_Speed = ((256*rpm[3])+rpm[4])/4;
Engine_load = (rpm[6]/2.55);

CAN.sendMsgBuf(0x7DE, 0, 8, sptrq);
CAN.readMsgBuf(&lon, sped);

Vehicle_Speed = (sped[3]);
Demand_torque = (sped[5]-125);
Actual_torque = (sped[7]-125);

CAN.sendMsgBuf(0x7DB, 0, 8, thr);
CAN.readMsgBuf(&siz, thro);

Throttle = (thro[3]/2.55);
Acc_pedal = (thro[5]/2.55);

For printing and displaying data

for(int i = 0; i<len; i++)
{

Tft.drawNumber(Engine_Speed, 90, 30, 5, WHITE);
Tft.drawNumber(Engine_load, 90, 60, 5, WHITE);

Serial.print(rpn*);Serial.print("\t");*

  • } *

  • for(int i = 0; i<lon; i++)*

  • {*

  • Tft.drawNumber(Vehicle_Speed, 90, 90, 5, WHITE);*

  • Tft.drawNumber(Demand_torque, 90, 120, 5, WHITE);*

  • Tft.drawNumber(Actual_torque, 90, 150, 5, WHITE);*
    _ Serial.print(sped*);Serial.print("\t");_
    _
    }_
    _
    for(int i = 0; i<siz; i++)_
    _
    {*_

* Tft.drawNumber(Throttle, 90, 180, 5, WHITE);*
* Tft.drawNumber(Acc_pedal, 90, 210, 5, WHITE);
_ Serial.print(thro);Serial.print("\t");
//delay(100);
}*_

I tried doing this but the program does not work as expected. Problem I am getting is the calculation of rpm and other values are not happening as expected.
Is it possible to do like this?. Or is there any other way to read the required messages simultaneously.
Thanks in advance

All cars use different in how they output can bus messages, and you will get very limited can bus messages on the OBD2 Port

Here is a reference to defcon 21, hacking cars using fussing and through the can bus.

Hi neoredstone,

Thank you. I will look into it.

I already got the above program working. With some alteration, the program works perfectly fine.

And thank you once again for your suggestion.

Having looked at the video by NeoRedStone,
I can appreciate the capacity for automobile makers to let their "OEM" hair down and do whatever they want, as long according to the golden rule, "It works". However unlike Linux which is mainly open source and under continual scrutiny, these guys can plug into cars what ever software they like, and make it as mysterious as they like at the same time. Rather than bolster my confidence as a car appreciator and hoping to sniff a few can codes to turn on my Wireless, I have found my confidence that these people really know what they are designing, at a very low point. The recent scandal of VW in Australia with a Golf being involved in a fatal (for the golf driver) rear end collision with a truck due to mysterious (claimed) transmission shutdown Golf shut down on freeway some what disconcerting.

I know all the industries want to be individual and protect their IP, but then they also have to accept the blame when their product is to blame. Some sort of common protocol, community vetted, would give customers some peace of mind their purchase has met the required safety standards, rather than having to put all their faith in some proprietary "black box".

It would also my plan for an after-market radio installation a bloody lot easier to work out.

Cheers rob

@Vasanthss519 Would you be so kind as to make available your full program you used to get RPM and Engine Load information from the CAN bus?
Thank you,
David Cyr