CAN Shield Query

CAN shield connected to an Uno. Trying to do a simple CAN/OBD-II query for engine speed. I’m not sure what I’m doing wrong. The CAN.init() comes back ok, along with all the filter commands. But my receive interrupt never triggers… ignition is on, car ('01 Civic) is running. Also, the R3 resistor on the CAN shield is still in place, does this need to be removed?

// CAN test code
#include <mcp_can.h>
#include <SPI.h>

#define CAN_BCAST 0x7df

unsigned char Flag_Recv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];

                 //EXTBYTS MODE  PID   UNUSED    

unsigned char canBuf[8] = {0x02, 0x01, 0x0c, 0, 0, 0, 0, 0};

void setup()
{
pinMode(2, INPUT); // Setting pin 2 for /INT input
attachInterrupt(0, MCP2515_ISR, FALLING); // start interrupt

Serial.begin(9600);
Serial.println(“Init”);

if(CAN.begin(CAN_500KBPS) == CAN_OK)
Serial.print(“CAN init ok!!\r\n”);
else
Serial.print(“CAN init fail!!\r\n”);

CAN.init_Mask(0, 0, 0x7f0);
CAN.init_Mask(1, 0, 0x7f0);
CAN.init_Filt(0, 0, 0x7e0);
CAN.init_Filt(1, 0, 0x7e0);
CAN.init_Filt(2, 0, 0x7e0);
CAN.init_Filt(3, 0, 0x7e0);
CAN.init_Filt(4, 0, 0x7e0);
CAN.init_Filt(5, 0, 0x7e0);
delay(10);

}

void loop()
{
// SEND //////////////////////////////////
CAN.sendMsgBuf(0x7df, 0, 8, canBuf);
delay(100); // send data per 100ms
// END SEND //////////////////////////////

// RECEIVE ///////////////////////////////
if(Flag_Recv)                           // check if get data
{
  Flag_Recv = 0;                        // clear flag
  CAN.readMsgBuf(&len, buf);            // read data,  len: data length, buf: data buf
  Serial.println("CAN_BUS GET DATA!");
  Serial.print("data len = ");
  Serial.println(len);
  
  for(int i = 0; i<len; i++)            // print the data
  {
    Serial.print(buf[i]);
    Serial.print("\t");
  }
  Serial.println();
}
// END RECEIVE //////////////////////////

}

void MCP2515_ISR()
{
Flag_Recv = 1;
}

/*********************************************************************************************************
END FILE
*********************************************************************************************************/

I would definitely remove the termination resistor.
It is 60 ohms, which is incorrect…

Also, I would suggest to not use the AVRs interrupt handling and, instead, have your main loop check to see if Pin 2 is low and then read the MCP2515. I have found utilized CAN buses will cause the interrupt handling method to crash the Sketch since the MCP2515’s /INT output is held low until all causes of the interrupt are cleared.

eg:

[code]// CAN test code
#include <mcp_can.h>
#include <SPI.h>

#define CAN_BCAST 0x7df

unsigned char Flag_Recv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];

//EXTBYTS MODE PID UNUSED
unsigned char canBuf[8] = {0x02, 0x01, 0x0c, 0, 0, 0, 0, 0};

void setup()
{
pinMode(2, INPUT); // Setting pin 2 for /INT input

Serial.begin(9600);
Serial.println(“Init”);

if(CAN.begin(CAN_500KBPS) == CAN_OK)
Serial.print(“CAN init ok!!\r\n”);
else
Serial.print(“CAN init fail!!\r\n”);

CAN.init_Mask(0, 0, 0x7f0);
CAN.init_Mask(1, 0, 0x7f0);
CAN.init_Filt(0, 0, 0x7e0);
CAN.init_Filt(1, 0, 0x7e0);
CAN.init_Filt(2, 0, 0x7e0);
CAN.init_Filt(3, 0, 0x7e0);
CAN.init_Filt(4, 0, 0x7e0);
CAN.init_Filt(5, 0, 0x7e0);
delay(10);

}

void loop()
{
// SEND //////////////////////////////////
CAN.sendMsgBuf(0x7df, 0, 8, canBuf);
delay(100); // send data per 100ms
// END SEND //////////////////////////////

// RECEIVE ///////////////////////////////
if(!digitalRead(2)) // check if get data
{
Flag_Recv = 0; // clear flag
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
Serial.println(“CAN_BUS GET DATA!”);
Serial.print("data len = ");
Serial.println(len);

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

}
// END RECEIVE //////////////////////////
}

[/code]

Ok I pulled that resistor and I’m checking PIN2 as you suggested. But now all I get is “CAN send fail”

[code]
// Mike Spenard CAN test code
#include <mcp_can.h>
#include <SPI.h>

#define CAN_BCAST 0x7df

unsigned char Flag_Recv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];

                 //EXTBYTS MODE  PID   UNUSED    

unsigned char canBuf[8] = {0x02, 0x01, 0x0c, 0, 0, 0, 0, 0};

void setup()
{
pinMode(2, INPUT); // Setting pin 2 for /INT input
attachInterrupt(0, MCP2515_ISR, FALLING); // start interrupt

Serial.begin(9600);
Serial.println(“Init”);

if(CAN.begin(CAN_500KBPS) == CAN_OK)
Serial.print(“CAN init ok!!\r\n”);
else
Serial.print(“CAN init fail!!\r\n”);

CAN.init_Mask(0, 0, 0x7f0);
CAN.init_Mask(1, 0, 0x7f0);
CAN.init_Filt(0, 0, 0x7e0);
CAN.init_Filt(1, 0, 0x7e0);
CAN.init_Filt(2, 0, 0x7e0);
CAN.init_Filt(3, 0, 0x7e0);
CAN.init_Filt(4, 0, 0x7e0);
CAN.init_Filt(5, 0, 0x7e0);
delay(10);

}

void loop()
{
// SEND //////////////////////////////////
if(CAN.sendMsgBuf(0x7df, 0, 8, canBuf) == CAN_OK)
Serial.print(“CAN send ok!!\r\n”);
else
Serial.print(“CAN send fail!!\r\n”);
delay(100); // send data per 100ms
// END SEND //////////////////////////////

// RECEIVE ///////////////////////////////
while(digitalRead(2));                           // check if get data

Flag_Recv = 1;
   
if(Flag_Recv)
{
  Flag_Recv = 0;                        // clear flag
  CAN.readMsgBuf(&len, buf);            // read data,  len: data length, buf: data buf
  Serial.println("CAN_BUS GET DATA!");
  Serial.print("data len = ");
  Serial.println(len);
  
  for(int i = 0; i<len; i++)            // print the data
  {
    Serial.print(buf[i]);
    Serial.print("\t");
  }
  Serial.println();
}
// END RECEIVE //////////////////////////

}

void MCP2515_ISR()
{
Flag_Recv = 1;
}

/*********************************************************************************************************
END FILE
*********************************************************************************************************/[/code]

sendMsgBuf keeps returning 7, ie, CAN_SENDMSGTIMEOUT. Any ideas why?

That is not how I suggested to use pin 2 in the snippet of code in my previous reply, though it looks like it should work if you just want the Arduino to hang until pin 2 goes low which will end the while() loop. Seeing as you are also using delay(), I would be correct to assume that what you are doing is not time sensitive.

As for getting send fail/timeout, I would be left to assume the baud rate is wrong. Are you sure it is not 250k?

I’m just trying to get this thing to return a PID query for now, hence the while() kludge.

I’m not sure what it is, I’m using the default 500K because that’s what this silly shield’s lib came with. What is it suppose to be in a '01 Honda?!

500k is the randomly chosen baud rate for the example sketches to test/demo the CAN shield. OBD-II was only 250k until some time ago when 500k was added, its safe to assume your car isn’t 500k since nothing is obviously working. Are you sure an '01 Honda has CAN on the OBD-II interface? I know its a requirement for 2008 and later model years in the US but anything earlier was entirely up to the manufacturer. Are pins 6 and 14 present on your OBD-II connector? If those are not populated, nothing we do here will get your car to talk CAN.

http://en.wikipedia.org/wiki/On-board_diagnostics#OBD-II