Unable to send / recieve CAN at the same time using MCP2515

I have a custom PCB, that uses a ATMEGA2560 with an MCP2515 and a MCP2551 in order to recieve CAN. Board is able to read CAN using the following code:

#include <SPI.h>
#include <mcp2515.h>

// LEDs debug
#define LED_DEBUG0 49
#define LED_DEBUG1 48
#define LED_DEBUG2 47
#define LED_DEBUG3 46
#define LED_DEBUG4 45
#define LED_DEBUG5 44
#define LED_DEBUG6 43
#define LED_DEBUG7 42

struct can_frame canMsg_recieved;
struct can_frame canMsg_send1;
struct can_frame canMsg_send2;
MCP2515 mcp2515(53);

unsigned long last_time_send_1_2 = 0;

void send_canMsg_1_2(void) {
  digitalWrite(LED_DEBUG4, true);
  mcp2515.sendMessage(&canMsg_send1);
  mcp2515.sendMessage(&canMsg_send2);
  Serial.println("B");  
  digitalWrite(LED_DEBUG4, false);
}

void setup() {
  // ########################################################################################
  // I/0
  // ########################################################################################
  // LEDs debug
  pinMode(LED_DEBUG0, OUTPUT);
  pinMode(LED_DEBUG1, OUTPUT);
  pinMode(LED_DEBUG2, OUTPUT);
  pinMode(LED_DEBUG3, OUTPUT);
  pinMode(LED_DEBUG4, OUTPUT);
  pinMode(LED_DEBUG5, OUTPUT);
  pinMode(LED_DEBUG6, OUTPUT);
  pinMode(LED_DEBUG7, OUTPUT);
  // ########################################################################################
  // CANBUS
  // ########################################################################################
  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS);
  mcp2515.setNormalMode();
  canMsg_send1.can_id = 750;
  canMsg_send1.can_dlc = 8;
  canMsg_send2.can_id = 751;
  canMsg_send2.can_dlc = 8;
  canMsg_send1.data[0] = 0xFF;
  canMsg_send1.data[1] = 0xFF;
  canMsg_send1.data[2] = 0xFF;
  canMsg_send1.data[3] = 0xFF;
  canMsg_send1.data[4] = 0xFF;
  canMsg_send1.data[5] = 0xFF;
  canMsg_send1.data[6] = 0xFF;
  canMsg_send1.data[7] = 0xFF;

  canMsg_send2.data[0] = 0xFF;
  canMsg_send2.data[1] = 0xFF;
  canMsg_send2.data[2] = 0xFF;
  canMsg_send2.data[3] = 0xFF;
  canMsg_send2.data[4] = 0xFF;
  canMsg_send2.data[5] = 0xFF;
  canMsg_send2.data[6] = 0xFF;
  canMsg_send2.data[7] = 0xFF;

  Serial.begin(115200);
}

void loop() {
  if (mcp2515.readMessage(&canMsg_recieved) == MCP2515::ERROR_OK) {
    digitalWrite(LED_DEBUG2, true);
    Serial.print("A ID: ");
    Serial.println(canMsg_recieved.can_id);
    digitalWrite(LED_DEBUG2, false);
  }
 else if (millis() - last_time_send_1_2 > 1000) {
    last_time_send_1_2 = millis();
    //send_canMsg_1_2();
    Serial.println("C");
  }
}

Notice that I am not sending nothing, since send_canMsg_1_2() is commented in the last lines. With this script, I get the following output:

12:36:51.357 -> C
12:36:51.779 -> A ID: 1000
12:36:51.779 -> A ID: 1001
12:36:51.779 -> A ID: 1003
12:36:51.779 -> A ID: 1002
12:36:52.377 -> C
12:36:52.747 -> A ID: 1000
12:36:52.747 -> A ID: 1001
12:36:52.747 -> A ID: 1003
12:36:52.747 -> A ID: 1002
12:36:53.344 -> C
12:36:53.765 -> A ID: 1000
12:36:53.765 -> A ID: 1001
12:36:53.765 -> A ID: 1003
12:36:53.765 -> A ID: 1002

Seems to work propperly (Is printing "C" at 1Hz (every 1 second) and is recieving all the messages from my ECU (4 different frames at 1Hz, 1s)). But if I try to send any package (uncommenting the last send_canMsg_1_2() line), I get the following:

12:38:56.997 -> B
12:38:56.997 -> C
12:38:57.781 -> A ID: 1001
12:38:57.781 -> A ID: 1003
12:38:58.012 -> B
12:38:58.012 -> C
12:38:59.010 -> B
12:38:59.010 -> C
12:39:00.028 -> B
12:39:00.028 -> C
12:39:00.770 -> A ID: 1001
12:39:00.770 -> A ID: 1003

Am I missing something? I guess HW must be ok, since I am recieving correct data from the ECU... The only thing that comes to my mind is that they overlay messages, but I guess MCP2515 has an integrated CSMA protocol.

BTW: I am using the following library: https://github.com/autowp/arduino-mcp2515?tab=readme-ov-file#software-usage

Thanks!

Did your MCP2551 chips come from Amazon, Aliexpress or Ebay?
If so, they are probably fake.

Assuming you have genuine chips, transmitting consumes more power than receiving, therefore look at the power supply rail with an oscilloscope to see if the chip supply voltage is dipping below the 4v brown out threshold.

They all come from Aliexpress. I also tried with a shield from Amazon and had this same probelm. Kind of sceptical with these, I can't figure why transmitting works perfect (without recieving) and recieving works perfect (without sending). Did you have this same problem with fake chips?

MCP2515 works up to 2,7V, so this may not be the problem. Altough, I will check the power supply with the oscilloscope and tell you something.

I am assuming script seems OK? I can't find any reciever / sender code uploaded in any forum. All I can find is either a reciever or a sender.

Thanks!

Unable to send/receive at the same time using MCP2510.
What you are seeing is correct, CAN was designed as a robust protocol and uses in frame acknowledgement. The bus has a dominate and a recessive mode.

Arbitration is determines when a dominate bit from a sender overrides a recessive bit from another sender. The loser shuts off and lets the message go through and tries later. It reads what it sends to determine priority but it is assumed you know what you sent.

Also note CAN is a differential bus and voltages are relative to each other not ground.

You can combine the Send and Receive codes, the receiver has a buffer which you check for messages. The receiver has an interrupt for that.
Hopefully this helps.

Hi @pepitogrillo7281 ,

as the time between sending data and receiving data is more than 700 ms according to your serial output at a rate of 500 kps on the CAN it seems to be quite unlikely that transmission and receiving interferes directly ...

Does anything happen at the "other side", the one you are sending the two messages with the IDs 750 and 751 to?

P.S.: I uploaded your sketch with enabled transmission to a MEGA2560 with a MCP2515 CAN Module and this sketch derived from your code

#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg_recieved;
struct can_frame canMsg_send1;
MCP2515 mcp2515(10);

unsigned long last_time_send_1_2 = 0;

void send_canMsg_1_2(int myID) {
  canMsg_send1.can_id = myID;
  mcp2515.sendMessage(&canMsg_send1);
}

void setup() {
  // ########################################################################################
  // CANBUS
  // ########################################################################################
  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS);
  mcp2515.setNormalMode();
  canMsg_send1.can_id = 750;
  canMsg_send1.can_dlc = 8;
  canMsg_send1.data[0] = 0xFF;
  canMsg_send1.data[1] = 0xFF;
  canMsg_send1.data[2] = 0xFF;
  canMsg_send1.data[3] = 0xFF;
  canMsg_send1.data[4] = 0xFF;
  canMsg_send1.data[5] = 0xFF;
  canMsg_send1.data[6] = 0xFF;
  canMsg_send1.data[7] = 0xFF;
  Serial.begin(115200);
}

void loop() {
  if (mcp2515.readMessage(&canMsg_recieved) == MCP2515::ERROR_OK) {
    Serial.print("In ID: ");
    Serial.println(canMsg_recieved.can_id);
  }
 else if (millis() - last_time_send_1_2 > 1000) {
    last_time_send_1_2 = millis();
    send_canMsg_1_2(1000);
    send_canMsg_1_2(1001);
    send_canMsg_1_2(1002);
    send_canMsg_1_2(1003);
    Serial.println("Done");
  }
}

to an UNO with also a MCP2515 CAN Module and got the following output with UNO (transmitting IDs 1000 ... 1003) and MEGA (transmitting IDs 750 and 751):

Left Column: UNO transmission times for messages 1000...1003
Center Column: MEGA reception and transmission
Right Column: UNO reception

So in my configuration your sketch is working.

(The timestamp comes from the Serial Monitor and therefore is not reliable "to the millisecond" regarding the timing of the boards/CAN Bus).

May I suppose then this is a hardware problem. I have bought a pair of original MCP2515, just to check. May I know what transciever were you using? And were did you get them from?

Thank you very much!

I use these modules

Not sure about the distributor...

So you are sure that the sender of the 1000...1003 IDs is not the cause? There might be a problem on that side when it receives messages...

Can you post an annotated schematic showing all connections and power sources?

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