CAN bus reading error, mixed packets

Hello to everybody,

i need to read some informations from an external circuit via CAN bus (125Kbps, 8bit, extended mode).
To begin i have used an MCP2515 board and Arduino UNO, but was my intention to use a NANO board.

i started to receive easily the can packets, but i could see that the last packet is printed in a wrong sequence.
the same program in an ESP8266 works good, could be a problem of slowness?

Thanks for your help

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

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];

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

void setup() {
  Serial.begin(115200);
  if (CAN0.begin(MCP_STDEXT, CAN_125KBPS, MCP_8MHZ) == CAN_OK) Serial.print("MCP2515 Init Okay!!\r\n");
  else Serial.print("MCP2515 Init Failed!!\r\n");
  pinMode(CAN_INT, INPUT);  // Setting pin 2 for /INT input

  CAN0.init_Mask(0, 1, 0xFFFFF000);  // Init first mask...
  CAN0.init_Filt(0, 1, 0x1FDFC000);  // Init first filter...
  CAN0.init_Mask(1, 1, 0xFFFFF000);

  Serial.println("MCP2515 Library Mask & Filter Example...");
  CAN0.setMode(MCP_NORMAL);  // Change to normal mode to allow messages to be transmitted

}

void loop() {
 
  if (!digitalRead(CAN_INT) && CAN0.checkReceive()==CAN_MSGAVAIL)  // If pin 2 is low, read receive buffer
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);  // Read data: len = data length, buf = data byte(s)
    Serial.print("ID: ");
    Serial.print(rxId, HEX);
    Serial.print(" Data: ");
    for (int i = 0; i < len; i++)  // Print each byte of the data
    {
      if (rxBuf[i] < 0x10)  // If data byte is less than 0x10, add a leading zero
      {
        Serial.print("0");
      }
      Serial.print(rxBuf[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
  // delay(10);
}

that is the wrong result:

13:17:20.566 -> ID: 9FDFC101 Data: 04 00 00 FE 00 00 00 FE 
13:17:20.566 -> ID: 9FDFC102 Data: 00 00 00 00 0A 00 11 01 
13:17:20.566 -> ID: 9FDFC103 Data: 81 05 05 04 FF 04 1F 02 
13:17:20.566 -> ID: 9FDFC104 Data: 00 00 19 00 00 00 00 08 
13:17:20.566 -> ID: 9FDFC106 Data: 06 50 6E 8B E7 3C 18 00 
13:17:20.566 -> ID: 9FDFC17F Data: D5 FB 8A 3B                 <--- should be the last row
13:17:20.566 -> ID: 9FDFC105 Data: 40 01 00 68 00 FF 00 08  <-- should be before  6th row

This is the right sequence read with ESP8266

ID: 9FDFC001 Data: 04 00 00 FE 00 00 00 FE
ID: 9FDFC002 Data: 00 00 00 00 0A 00 11 01
ID: 9FDFC003 Data: 81 05 05 04 FF 04 1F 02
ID: 9FDFC004 Data: 00 00 19 00 00 00 00 08
ID: 9FDFC005 Data: 40 01 00 68 00 FF 00 08
ID: 9FDFC006 Data: 06 AA 6E 8B E7 3C 18 00
ID: 9FDFC07F Data: 42 9E 84 FB

Collect the data and rather than delay(10) print to screen.

2 Likes

Great. It was the right solution. Thanks a lot!

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

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
unsigned char lkdsBuf[64];
unsigned int id = 0;


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

void setup() {
  Serial.begin(115200);
  if (CAN0.begin(MCP_STDEXT, CAN_125KBPS, MCP_8MHZ) == CAN_OK) Serial.print("MCP2515 Init Okay!!\r\n");
  else Serial.print("MCP2515 Init Failed!!\r\n");
  pinMode(CAN_INT, INPUT);  // Setting pin 2 for /INT input

  CAN0.init_Mask(0, 1, 0xFFFFF000);  // Init first mask...
  CAN0.init_Filt(0, 1, 0x1FDFC000);  // Init first filter...
  CAN0.init_Mask(1, 1, 0xFFFFF000);

  Serial.println("MCP2515 Library Mask & Filter Example...");
  CAN0.setMode(MCP_NORMAL);  // Change to normal mode to allow messages to be transmitted

  id = 0;                               // azzera l'indice del buffer
  memset(lkdsBuf, 0, sizeof(lkdsBuf));  // svuota buffer
}

void loop() {

  int i8 = 0;

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

    for (int i = 0; i < len; i++)  // Print each byte of the data
    {
      lkdsBuf[id] = rxBuf[i];
      id++;
    }
  }

  if ((rxId & 0x0000000F) == 0x0F) {
    // last string print the buffer
    Serial.println(rxId, HEX);    // print the last id (just to check)

    for (int i = 0; i < id; i++)  // Print each byte of the data
    {
      if (lkdsBuf[i] < 0x10)  // If data byte is less than 0x10, add a leading zero
      {
        Serial.print("0");
      }
      Serial.print(lkdsBuf[i], HEX);
      Serial.print(" ");
      if (i8++ == 7) {          // spare buffer in 8 bytes
        Serial.println();
        i8 = 0;
      }
    }
    Serial.println();

    memset(lkdsBuf, 0, sizeof(lkdsBuf));  // empty buffer
    id = 0;                               // reset index
    rxId = 0;                           // reset Id
  }
  // delay(10);
}

And that's the correct result

9FDFC07F
04 00 00 FE 00 00 00 FE 
00 00 00 00 0A 00 11 01 
81 05 05 04 FF 04 1F 02 
00 00 19 00 00 00 00 08 
40 01 00 68 00 FF 00 08 
06 EC A3 8C E7 0A 18 00 
59 96 EF E3 

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