Is Arduino Mega capable of handling real time CAN data using MCP2515?

I'm Doing project for my company, we have our own product (used in 2 wheeler bike) which take input from 3phase motor and output 14v DC to charge 12v battery. if anything wrong product will send ERROR message in 0x0D1 id.

I configured MCP2515 with Arduino Mega. below are my conditions.

  1. when Arduino receive CAN message start 1 relay which is connected to (supplied by 12v SMPS) green Indicator.

  2. When Arduino detect ERROR in 0x0D1 in 5th byte (lower bit), It will STOP Motor by enabling 2nd relay, and 3rd relay for Red Indicator, also it will stop 1st relay.

All the above condition checked and working fine for some time like 30 min. after that Arduino starts malfunctioning or freezing.
A) it getting CAN messages but it stops 1st relay.
B) it sending Random CAN error Message which is not sent by product (crossed verified by PCAN Explorer 5 and Pico scope)

After pressing reset it will start working for another 20-30min.

NOTE-

  1. I have given proper power supply.
  2. All relay powered by 12V SMPS.
  3. All grounds are common.
  4. its a standard CAN id 500kbps 8Mhz.
  5. In this case Arduino receives more then 200 messages per seconds

so lastly remains is Arduino capable to handle real time continues data. because other are generating CAN message from another Arduino in my case its getting from real product which sends more then 200 messages per seconds.

Code for your reference.

#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(53);                               // Set CS to pin 10

const int Motor = 22;
const int Load = 23;
const int IndicatorMIL = 24; 

static unsigned long startTime = 0;
static unsigned MilFlag = 0; 

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

  pinMode(Motor, OUTPUT);                          // sets the digital pin 22 as CAN0 Motor STOP .
  pinMode(Load, OUTPUT);                          // sets the digital pin 23 as CAN0 Load Relay.
  pinMode(IndicatorMIL, OUTPUT);                          // sets the digital pin 24 as CAN0 MIL Indicator.
  
  // Initialize MCP2515 running at 8MHz with a baudrate of 500kb/s and the masks and filters disabled.
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == 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)
    //Serial.println("CAN Receive buffer:");
    if (MilFlag == 0){
      digitalWrite(Load, HIGH);
      startTime = millis();
    }
  }
  else {
      if(millis() - startTime > 1000){
        digitalWrite(23, LOW);
      }
    }
  }

     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);
  
      for(byte i = 0; i<len; i++)
      {
        sprintf(msgString, " 0x%.2X", rxBuf[i]);
        Serial.print(msgString);
      }

    // check if the received ID is 0xxx and the xxth Bit value has changed from the previous value.
       
      
    if (rxId == 0xD1 && rxBuf[4] !=0x00){
      //Serial.println("\n");
      byte x = rxBuf[4];
      byte MIL=0;
      for (char i=0; i<4; i++)
      {
        byte temp=bitRead(x,i);
        MIL = MIL + temp;
      }
      //Serial.println("\n");
      //Serial.println(MIL);
      //Serial.println(x);                      // Total No of 1 in Lower Bit.
      if (MIL !=0)                             // check if the received Bit is 0
      {
      Serial.println("\n");
      Serial.println("ACTIVE MIL CAN_0");
      Serial.println(x); 
      digitalWrite(Motor, HIGH);                 // Make the Motor STOP Relay High.
      MilFlag = 1;
      digitalWrite(Load, LOW);                  // Make the Load Relay Low.
      digitalWrite(IndicatorMIL, HIGH);                 // Make the MIL indicator Relay High.
      }
    }
    Serial.println();
  }

Output which im getting.

Thanks in advance.!!

Please post schematics and a link to the relay datasheet or technical manual.

That is a subjective question, the answer is maybe If you are processing a continuous stream of 100 gigabytes a second, no, but if it is 1 byte a second maybe. It is highly dependent on the hardware and code. if you put a 1 second delay in your code it will stall for that one second and fail. If you are writing to a LCD it will again stall because many of the libraries use delay.

As requested by @Railroader post an annotated schematic and links to the data sheets.

If I were in your situation I would get a much faster board, perhaps one of the ESP's and setup a test. If the faster board makes no difference the you have an indication the Mega is capable enough.

I'm using 8 channel relay board which has separate 12V (12V-5A SMPS) supply. and it will trigger using any Arduino digital pin (5V). so basically I'm triggering PIN.

Link:

@gilshultz there is no any delay in program.

That relay is safe to use. Be aware of kick backs from the load and use kick back diodes on the 12 volt side.

Yup, But there is no load still I'm testing it.

BUT main point is why its freezing...??

Schematics might tell the reason....

1 Like

The CAN setup you are using has filters inherent in the MPC2515, you can set them up to ignore messages you do not want. That once set requires no processor overhead. Without a schematic which has been requested several times the odds are getting very slim you will getting a solution.

1 Like

Apologies for that. Hear is the Schematics Diagram.