Arduino mega + mcp2515 does not read all can messages

Hi all, for a while now been trying to read can-bus messages on my Volvo s60 01' and i am just not able to :frowning: .. I am trying to connect to hi speed can-bus, but as I connect via obd port i need to send constant k-line messages to keep can-bus relay actrive (k-line part is working perfectly, just informing to better understand code).
And with arduino MEGA and MCP2515 I have tried various codes, and the latest one should be working, but it is not - I get some of hex values, but they do not look like real can-bus traffic you would see in a car.
here is the code:

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

// MCP2515 CAN interface
#define CAN0_INT 2 // Assuming MCP2515 INT pin is connected to digital pin 2
MCP_CAN CAN0(53);  // Assuming you're using digital pin 53 for CS

// MC33290 K-line interface (using Serial1: TX1 and RX1)
#define KLINE_TX 18
#define KLINE_RX 19

unsigned long lastSendTime = 0; // Keep track of the last time the K-line message was sent
unsigned long sendDelay = 3000; // Delay between K-line messages in milliseconds
unsigned long lastRequestTime = 0; // Track the last time CAN request was sent
// unsigned long requestDelay = 1000; // Delay between CAN requests in milliseconds
bool waitForReply = false;

void sendKLineMessage() {
  // Timer to manage delay
  if ((millis() - lastSendTime) < sendDelay) {
    return;  // Exit if the delay time hasn't passed yet
  }

  // Message for keeping the CAN-bus relay active
  unsigned char klineMessage[7] = {0x84, 0x40, 0x13, 0xB2, 0xF0, 0x03, 0x7C}; // K-line message
  Serial.print("Sending K-line message: ");
  for (int i = 0; i < 7; i++) {
    Serial.print(klineMessage[i], HEX);
    Serial.print(" ");
    Serial1.write(klineMessage[i]);  // Send each byte of the K-line message
  }
  Serial.println();  // Print a newline after sending the message

  lastSendTime = millis(); // Update the time when K-line message was last sent
}

void setup() {
  Serial.begin(115200);  // Start serial communication for debugging
  Serial1.begin(10800);  // Start K-line communication

  Serial.println("Setup started.");

  // Send initial message on K-line to activate CAN-bus relay
  sendKLineMessage();
  delay(1000); // Small delay to make sure K-line message is sent initially
  Serial.println("Initial K-line message sent.");

  // Initialize MCP2515
  if (CAN0.begin(MCP_ANY, CAN_250KBPS, MCP_8MHZ) == CAN_OK) {
    Serial.println("MCP2515 Initialized Successfully!");
  } else {
    Serial.println("Error Initializing MCP2515...");
    while (1);  // Hang if MCP2515 initialization fails
  }

  //pinMode(CAN0_INT, INPUT);
  CAN0.setMode(MCP_NORMAL);  // Set MCP2515 to normal mode
  Serial.println("MCP2515 in Normal mode.");
}

void loop() {
  // Handle K-line messaging independently from CAN messaging
  sendKLineMessage();  // Send K-line message if the delay period has passed
  
  long unsigned int rxId;
  unsigned char len = 0;
  unsigned char buf[8];

  if (CAN_MSGAVAIL == CAN0.checkReceive()) {
    CAN0.readMsgBuf(&rxId, &len, buf);

    Serial.print("Message ID: ");    
    Serial.println(rxId, HEX);

    Serial.print("Data: ");
    for (int i = 0; i < len; i++) {
      Serial.print(buf[i], HEX);
      Serial.print(" ");
    }
    Serial.println();

    CAN0.setMode(MCP_NORMAL);
  }

  delay(10);

  }

and here is what i get from the start (it goes on and on..):

19:53:42.504 -> Setup started.
19:53:43.541 -> Initial K-line message sent.
19:53:43.541 -> Entering Configuration Mode Successful!
19:53:43.541 -> Setting Baudrate Successful!
19:53:43.541 -> MCP2515 Initialized Successfully!
19:53:43.541 -> MCP2515 in Normal mode.
19:53:43.541 -> Message ID: 8010001C
19:53:43.541 -> Data: C0 8E 30 5C 44 0 A3 60
19:53:43.657 -> Message ID: 80600006
19:53:43.657 -> Data: 0 0 5 9B AB FF FC 18
19:53:43.732 -> Message ID: 8050003C
19:53:43.732 -> Data: 83 10 A E C0 20 1A 1C
19:53:43.853 -> Message ID: 8010001C
19:53:43.853 -> Data: 0 8E B0 5C 44 0 23 60
19:53:43.935 -> Message ID: 8010001C
19:53:43.935 -> Data: 80 8E B0 5C 44 0 23 60
19:53:44.037 -> Message ID: 8040001E
19:53:44.037 -> Data: C7 0 91 16 4 0 60 0
19:53:45.583 -> Sending K-line message: 84 40 13 B2 F0 3 7C
19:53:45.653 -> Message ID: 8010001C
19:53:45.653 -> Data: C0 8E 30 5C 44 0 A3 60
19:53:45.768 -> Message ID: 8010001C
19:53:45.768 -> Data: C0 8E 30 5C 44 0 A3 60
19:53:45.898 -> Message ID: 8010001C
19:53:45.898 -> Data: 40 8E 30 5C 44 0 A3 60
19:53:45.988 -> Message ID: 80600006
19:53:45.988 -> Data: 0 0 25 9B AB FF FC 18
19:53:46.107 -> Message ID: 8010001C
19:53:46.107 -> Data: 80 8E 30 5C 44 0 23 60
19:53:46.195 -> Message ID: 8010001C
19:53:46.195 -> Data: 0 8E 30 5C 44 0 23 60
19:53:46.284 -> Message ID: 8010001C

Maybe someone could help me figure it out? :slight_smile:

1 Like

hi, LinoKitty,

maybe the vehicle has many CAN bus lines connected thru Gateway that's why you cannot see all CAN message. pls help me out, if i am wrong.
first thing is that the Arduino can't read over 8 bytes like SOFT ID or DM1 etc. so, you need to put some tp message handling.

Second, it seems you need to put the ID filter. if you link to the Extended CAN and ID needs to be filtered.
Serial.print(rxId & 0x1FFFFFFF, HEX);

I don't know about all cars or your specific vehicle, but this is quite common. OEMs implement such protections to safeguard the vehicle from damage and misuse. For example, imagine the consequences of opening a valve at the wrong time – it could cause significant issues.

All figured out, it seems i had to send another request message for diagnostics "mode".
Now when sending messages every 3s i get all the data i needed. Thank you for insight

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