Arduino Uno R3 + Can-bus shield V 1.2 from http://www.seeedstudio.com/

Hi i am new to arduino an my programing skills are minimum.

Im want to make a can bus sniffer for use on an old BMW E39 that use BaudRate 100. To communicate between Engine ecu, Transmission ecu, and Abs ecu.

The problem is that i don't receive any data. The Recv indicator led is on, and i get the message "CAN BUS Shield init ok!" But no data.

I have search the internet now for days but can't find anything

Im have tried the example code from the can bus library https://github.com/Seeed-Studio/CAN_BUS_Shield

And i have tried the code from this example http://www.instructables.com/id/Hack-your-vehicle-CAN-BUS-with-Arduino-and-Seeed-C/

I have also tried to remove the terminal resistor.

Sorry if my english is bad, i hope it's understandable.

Best regards.

Here is the code am using:

#include <SPI.h>
#include "mcp_can.h"

INT32U canId = 0x000;
unsigned char len = 0;
unsigned char buf[8];
char str[20];

const int SPI_CS_PIN = 9;

MCP_CAN CAN(SPI_CS_PIN);

void setup()
{
Serial.begin(115200);
START_INIT:
if(CAN_OK == CAN.begin(CAN_100KBPS))
{
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()
{
if(CAN_MSGAVAIL == CAN.checkReceive())
{
CAN.readMsgBuf(&len, buf);
canId = CAN.getCanId();
Serial.println("-----------------------------");
Serial.print(canId);Serial.print(",");
for(int i = 0; i<len; i++)
{
Serial.print(buf*);Serial.print(",");*

  • }*
  • Serial.println();*
  • }*
    }

Hello Dschantz,

as you used the standard code to get the shield running, didn't checked exactly if you changed something. I would say that you face a different problem, how did you remove the resistor for the termination, because you want to sniff in an working bus which should be terminated in the right way.
Did you cut the tiny connection on the board next to the terminals with the screws?
How did you connect the CAN.

And at least don't try this in a moving car, don't know what happens if you corrupt messages for the engine or the ABS...

Succubus

Thanks for the reply.

I cut the tiny connection on the board next to the terminals with the screws.

I used the can wires going in to the engine ecu, and connected the can thru there. I used the can bus terminal on the shield with the screws

I did not do a test drive with the canbus sniffer connectet, but i did start the engine.

I fond some info on the canbus system for these old cars, i think the termination resistor for the canbus is 60 ohm on these, not 120 ohm. Correct me if am wrong. Can this be the problem ?

Hello Dschantz,

yes 60 Ohm is right, 120 Ohm on both sides (parallel) equals 60 Ohm. The 9 pin plug has no standard connection (pin 2 and 7) I also used the terminal with the screws. Did you connect CAN high to canh and same for the CAN low side?

If you cut off this connection the switch is working so check if it is set to off in your case.

I am nearly sure that the CAN for the engine ECU in a car is a high speed CAN otherwise you have to change the transceiver but as there is a HS one on this board it should work fine.

Thanks for the reply Soccubus :slight_smile:

So should i try connect a 60 ohm resistor between Can-H and Can-L on my can bus shield ? And se if that works ? the resistor that i cut on the can board is 120 ohm ?

I checked the cable connection many times :slight_smile: Can-H is on Can-H and the same for can low.

The switch on the board is off.

I am nearly sure that the CAN for the engine ECU in a car is a high speed CAN otherwise you have to change the transceiver but as there is a HS one on this board it should work fine. <- what do you mean the mcp 2551 Transceiver on the can bus shield ?

Hello Dschantz,

let's start with the CAN bus termination, a CAN Bus has to be terminated on both ends of the bus which aren't connected to another CAN node. This termination is done with a 120 Ohm resistor on each side, this results in an overall resistance of the bus between CAN High and CAN Low of 60 Ohm. In your case I guess are both ends already terminated you should not add another resistor.

Now to the CAN shield, if you cut the tiny bridge next to the terminal with the screws you enabled the switch, before it was shortened (I didn't know who designed this, shaking my head, before I checked the PCB I thought it is an bug in the schematics). Keep the switch in position OFF. otherwise you add a third resistor to your can and the overall resistance is 40 Ohm

I think the CAH which is used between the ECUs is an high speed (HS) CAN -> the CAN shield already has the right transceiver on the PCB... I can tell you it is no fun to change them to Low speed as the Low speed transceiver has a different number of pins, I had to do this several times.
-> You can leave everything as it is... (but 100kbps can be high or low speed) do you know/read somebody who got it working with this shield?

If everything is fine it is a software problem...

Can you just try to rename your CAN object (MCP_CAN CAN(SPI_CS_PIN):wink: into something what is not exactly named "CAN" e.g. "myCAN" inclusive all other occurrences.
Made some changes to your code:

#include <SPI.h>
#include "mcp_can.h"

INT32U canId = 0x000;
unsigned char len = 0;
unsigned char buf[8];
char str[20];

const int SPI_CS_PIN = 9;

MCP_CAN myCAN(SPI_CS_PIN); // changed CAN to myCAN

void setup()
{   
Serial.begin(115200);
START_INIT:
if(CAN_OK == myCAN.begin(CAN_100KBPS))
    {
        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()
{
    if(CAN_MSGAVAIL == myCAN.checkReceive())
    {
        myCAN.readMsgBuf(&len, buf);
        canId = myCAN.getCanId();
        Serial.println("-----------------------------");
        Serial.print(canId);Serial.print(",");
        for(int i = 0; i<len; i++)
  {
    Serial.print(buf[i]); // buf without an index didn't work here
    Serial.print(",");
  }
  Serial.println();
   }
}

Thanks again.

That did the trick. ;D I also had to change the baudrate to 500. And i edit the code a bit.

#include <SPI.h>
#include "mcp_can.h"

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;

MCP_CAN myCAN(SPI_CS_PIN); // Set CS pin

void setup()
{
Serial.begin(115200);

while (CAN_OK != myCAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
{
Serial.println("CAN BUS Shield init fail");
Serial.println(" Init CAN BUS Shield again");
delay(100);
}
Serial.println("CAN BUS Shield init ok!");
}

void loop()
{
unsigned char len = 0;
unsigned char buf[8];

if(CAN_MSGAVAIL == myCAN.checkReceive()) // check if data coming
{
myCAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf

unsigned char canId = myCAN.getCanId();

Serial.println("-----------------------------------------------------------");
Serial.print("Get data from ID: ");
Serial.println(canId, HEX);

for(int i = 0; i<len; i++) // print the data
{
Serial.print(buf*, HEX);*

  • Serial.print("\t");*
  • }*
  • Serial.println();*
  • }*
    }

Hello Dschantz,

nice that you got it running, ok sure if the Baudrate is incorrect nothing will work. But I still wonder how you got this compiled/running:

   for(int i = 0; i<len; i++)    // print the data
        {
            Serial.print(buf, HEX);
            Serial.print("\t");
        }

in my opinion this change should show all bytes of the message:

   for(int i = 0; i<len; i++)    // print the data
        {
            Serial.print(buf[i], HEX); // <-- added index here
            Serial.print("\t");
        }

But now have fun with tracing :wink:

Hey guys,

Having perhaps a similar problem here.

I am trying to use the v1.2 board. When I connect with the OBD-II connecter on the highspeed baud (500) I can correctly read the data on the bus. However, when I try to connect using the terminal connectors I can neither send or receive anything.

I am patching into the med-speed can bus in my car behind the radio (I know my cars OBD is not directly connected to the CAN, it requires probing the ECU). Using an oscilloscope, I confirmed my baud rate is 95.6kbaud, and I have been able to decode the data using the oscilloscope (it has a canbus analyzer).

However, for the life of me I am unable to receive or send anything on the terminal outputs. I have tried with and without a terminal resister, directly onto the oscilloscope. The lines remain high.

I am using:

Arduino Uno + seedstudio_v_1.2 shield
Saleae logic analzer

Any idea why the standard "Send" arduino example does not output anything onto the canbus lines. The canbus responds that it initialized successfully.. but thats all I get.

Many thanks in advance guys.

ps. I am using the correct SPI pin, I also checked and there is SPI data flowing to the shield... so I am guessing the shield is fried?? Its my second one :cry:

Hello Sparkplug23,

if your shield is still working with OBD2 it shouldn't be fried (and both used ic's are easy to change and cheap). Don't know what kind of radio you have but there is more than kind of CAN transceiver:

  • Highspeed this is on the CAN shield which needs an resistor of 120 Ohm at both ends of the bus,
  • Lowspeed which needs different transceivers and no resistors
  • and SingelWire CAN which uses only one wire

It could also be that you have to cut the small bridge on the left side of R3 (P1) otherwise the 120 Ohm resistor of the shield is used in any way!

It could be possible that your radio uses no high speed CAN, in this case you have to change the transceiver this is not impossible but not completely easy (I did this for a project some times, exchanged with a tja1055)

Succubus

Hi, is there a way for sorting the incoming messages by can id ? I am struggling to figure this out, i found some code on the forum regarding sorting array. can i use some of the code. Maybe change the byte with unsigned char ? As i said earlier my programing skills are not so good. :confused:

byte numbers[] = {2, 5, 10, 1, 31};

void setup()
{
Serial.begin(9600);

printArray(numbers, sizeof(numbers));
isort(numbers, sizeof(numbers));
printArray(numbers, sizeof(numbers));
}

//Bubble sort my are
void isort(byte a, int n)
{
for (int i = 1; i < n; ++i)
{
int j = a
;

  • int k;*
  • for (k = i - 1; (k >= 0) && (j < a[k]); k--)*
  • {*
  • a[k + 1] = a[k];*
  • }*
  • a[k + 1] = j;*
    }
    }
    //what it says on the tin
    void printArray(byte *a, int n)
    {
    for (int i = 0; i < n; i++)
    {
    _ Serial.print(a*, DEC);_
    _
    Serial.print(' ');_
    _
    }_
    Serial.println();
    _
    }_
    _
    //we'll not use loop for this*_
    void loop()
    {
    }

Hello,

I'm also working the same car and for similar project.

I would also read the CANBUS and display certain data to my Sainsmart 3.2" display.

At the moment I have
Arduino UNO R3
Sainsmart 3.2" display
CANBUS shield by Elecfreaks v 1.2

Do you have any progress about your project?

Greetings

Hi.

I have received can bus data, but there are a lot of date coming. I am struggling to sort the data for better understanding.

I have moved on to using raspberry pi for analyzing the data. sins my coding skills are not that grate.

https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=141052

I am building my own canbus shield for raspberry pi using the MCP2551 transceiver instead of the TJA1050 used in the example above. For my understanding the TJA1050 don`t support high speed canbus
as the MCP2551 do.