Issues with MCP2515 and Arduino Mega - TX Buffers Not Clearing

I'm trying to use the MCP2515 with an Arduino Mega, but the system is not working properly.

The SPI connection is as follows:

  • SCK: Pin 52
  • SI: Pin 51
  • SO: Pin 50
  • CS: Pin 53

The installed library is "autowp-mcp2515".

I also added 120-ohm terminating resistors (terminators) on the ends of the CAN bus line using the Jumper

I noticed that the sendMessage method returns the error MCP2515::ERROR_ALLTXBUSY. It seems that the 3 TX buffers (TXB0, TXB1, TXB2) are not being released.

Can anyone help me?

The sender code is as follows:

#include <mcp2515.h>

/* collegamento per mega:
SCK: Pin 52
SI: Pin 51
SO: Pin 50
cS: Pin 53
*/

struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(53);
MCP2515::ERROR settingResult;
MCP2515::ERROR checkMsg1 = MCP2515::ERROR_OK;
MCP2515::ERROR checkMsg2 = MCP2515::ERROR_OK;

void setup() {
  canMsg1.can_id  = 0x0F6;
  canMsg1.can_dlc = 8;
  canMsg1.data[0] = 0x8E;
  canMsg1.data[1] = 0x87;
  canMsg1.data[2] = 0x32;
  canMsg1.data[3] = 0xFA;
  canMsg1.data[4] = 0x26;
  canMsg1.data[5] = 0x8E;
  canMsg1.data[6] = 0xBE;
  canMsg1.data[7] = 0x86;

  canMsg2.can_id  = 0x036;
  canMsg2.can_dlc = 8;
  canMsg2.data[0] = 0x0E;
  canMsg2.data[1] = 0x00;
  canMsg2.data[2] = 0x00;
  canMsg2.data[3] = 0x08;
  canMsg2.data[4] = 0x01;
  canMsg2.data[5] = 0x00;
  canMsg2.data[6] = 0x00;
  canMsg2.data[7] = 0xA0;

  while (!Serial);

  Serial.begin(115200);
  
  mcp2515.reset();
  settingResult = mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();
  Serial.println("\n\n\n");
  Serial.print("Setting result = ");
  Serial.println(settingResult == MCP2515::ERROR_OK ? "OK" : "!!!FAILL!!!");
  Serial.println("Example: Write to CAN");
}

void loop() {
  if (checkMsg1 == MCP2515::ERROR_OK || checkMsg2 == MCP2515::ERROR_OK){
    checkMsg1 = mcp2515.sendMessage(&canMsg1);
    checkMsg2 = mcp2515.sendMessage(&canMsg2);
    Serial.print("check send msg1 = ");
    Serial.println(checkMsg1 == MCP2515::ERROR_OK ? "OK" : "!!!FAILL!!!");
    Serial.print("check send msg2 = ");
    Serial.println(checkMsg2 == MCP2515::ERROR_OK ? "OK" : "!!!FAILL!!!");
  }
  delay(500);
}

The reciver code is as follows:

#include <mcp2515.h>

/* collegamento per mega:

SCK: Pin 52
SI: Pin 51
SO: Pin 50
cS: Pin 53
*/

struct can_frame canMsg;
MCP2515 mcp2515(53);

MCP2515::ERROR settingResult;

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

  mcp2515.reset();
  
  Serial.println("\n\n\n");
  settingResult = mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();
  Serial.print("Setting result = ");
  Serial.println(settingResult == MCP2515::ERROR_OK ? "OK" : "!!!FAILL!!!");
}

void loop() {

  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
    Serial.print("Id messaggio ->"); // print ID
    Serial.print(canMsg.can_id, HEX); // print ID
    Serial.print("{"); 
    Serial.print(canMsg.can_dlc, HEX); // print DLC
    Serial.print("}");
    
    for (int i = 0; i<canMsg.can_dlc; i++)  {  // print the data
      Serial.print(canMsg.data[i],HEX);
      Serial.print(" ");
    }
    
    Serial.println();      
  }
 
}

Without a schematic and not being familiar with your library I can only take a SWAG: It has been a while since I worked with CAN but in the back of my mine the transmitter buffer will not clear until the message is sent and acknowledged. There is an error flag that will tell you this. I hope this helps.