Unable to Establish CAN Bus Communication Between Two MCP2515 and MCP2551

Hello everyone,

I'm currently working on an OBD project where I aim to establish communication using the MCP2515 CAN bus controller and the MCP2551 CAN transceiver. In the initial stages of this project, I successfully used the MCP2515 CAN bus module (with a TJA1050) and got it working. Later, I replaced the transceiver side with standalone MCP2515 and MCP2551 components and got it working as well.

Here's the challenge I'm facing: I've created my own circuits and made that work while being connected to the CAN bus module. However, when I try to connect the two "standalone" parts to each other, they don't seem to communicate. The error message I'm encountering is "Error sending message." I've tried numerous troubleshooting steps, but I'm still unable to figure out why they won't establish communication. I've notice that the Arduino uno provides 5V while the arduino nano provides 4.8V. I don't know if that really makes any difference.

I'll be attaching pictures of my circuit and the code I've been using for reference. Any insights or ideas would be highly appreciated!

Some information about the circuit:
The capacitors at OSC1, OSC2, RXD are 27pF
The voltage capacitors are 10uF (electrolytic) and 100nF (ceramic)
The Reset resistor is 10k Ohm
The RS resistor is 4.7k Ohm
The CANH/L resistor is 120 Ohm and the capacitor is 100pF


// CAN Send Example
//

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

MCP_CAN CAN0(10);     // Set CS to pin 10

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

  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
  else Serial.println("Error Initializing MCP2515...");
  CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
}

byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
byte data2[8] = {0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
void loop()
{
  // send data:  ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
  byte sndStat = CAN0.sendMsgBuf(0x400, 0, 8, data);
  byte sndStat2 = CAN0.sendMsgBuf(0x100, 0, 8, data2);

  if(sndStat == CAN_OK){
    Serial.println("Message Sent Successfully!");
  } else {
    Serial.println("Error Sending Message...");
  }
  delay(100);   // send data per 100ms
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/
// CAN Receive Example
//

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

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
char msgString[128];                        // Array to store serial string

#define CAN0_INT 2                              // Set INT to pin 2
MCP_CAN CAN0(10);                               // Set CS to pin 10


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

  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
  if (CAN0.begin(MCP_ANY, CAN_250KBPS, MCP_16MHZ) == CAN_OK)
    Serial.println("MCP2515 Initialized Successfully!");
  else
    Serial.println("Error Initializing MCP2515...");

  CAN0.setMode(MCP_NORMAL);                     // Set operation mode to normal so the MCP2515 sends acks to received data.

  pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input

  Serial.println("MCP2515 Library Receive Example...");
}

void loop()
{
  if (!digitalRead(CAN0_INT))                        // If CAN0_INT pin is low, read receive buffer
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)

    if ((rxId & 0x80000000) == 0x80000000)    // Determine if ID is standard (11 bits) or extended (29 bits)
      sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
    else
      sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);

    Serial.print(msgString);

    if ((rxId & 0x40000000) == 0x40000000) {  // Determine if message is a remote request frame.
      sprintf(msgString, " REMOTE REQUEST FRAME");
      Serial.print(msgString);
    } else {
      for (byte i = 0; i < len; i++) {
        sprintf(msgString, " 0x%.2X", rxBuf[i]);
        Serial.print(msgString);
      }
    }

    Serial.println();
  }
}

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

During my troubleshooting process, I stumbled upon an interesting observation. It appears that my "standalone" circuit can only receive messages successfully. When I set it up my circuit as the transmitter and have the CAN module as the receiver, I consistently encounter the error message "Error sending message." Interestingly, when I swap their roles and use the CAN module as the transceiver and my circuit as receiver, communication works flawlessly.

Why might my circuit be encountering difficulties when acting as a transmitter? Any suggestions or explanations would be greatly appreciated.

Is there a receiver when it is transmitting, if not it will not work. Use the receiver module in the library and get your transmitter to talk to that first. If you are trying to send messages on OBDII you may be in the forbidden zone.

1 Like

For some reason I needed the module to be at 500kbs while my circuit is at 250kbs for the system to communicate

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.