Read CAN Message with interrupt

Hi I'm using this library, https://www.arduino.cc/reference/en/libraries/mcp_can/
but I want to read the messages with an interrupt like this:


But it doesn't work, anyone knows if I had to modify something in the library?

Thanks for the support,
Àlex.

@coryjfowler

What do you want to do in the ISR?

I want to enter the interrupt when a CAN message is received by the MCP, process that CAN message and continue with my program. The function that is called by the interrupt is the following one:

void can_read()
{
  CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)
    
  switch(rxId)
  {    
    case 0x181: 
    {
      VALUE_VEL = (rxBuf[4] & 0xFF) | (rxBuf[5] << 8) | (rxBuf[6] << 16) | (rxBuf[7] << 24);
    } 
    break;

    case 0x281:
    {
      TEMPM = (rxBuf[0] & 0xFF);
      TEMPI = (rxBuf[1] & 0xFF);
    }
    break;
    
    case 0x202:
    {
      DM = (rxBuf[0] & 0xFF);
      GEAR = (rxBuf[1] & 0xFF);
    }
    break;

    case 0x301:
    {
      VOLTAGE = (rxBuf[0] & 0xFF) | (rxBuf[1] << 8);
      TEMPB = (rxBuf[5] & 0xFF);
    }
    break;

    case 0x501:
    {
      VOLTAGE_LED = (rxBuf[0] & 0xFF) | (rxBuf[1] << 8);
    }
    break;
  }
}

The device has a receive buffer so you would normally use a 'level' rather than an 'edge' triggered interrupt.
This ensures you process all messages, not just the first in the buffer.
Alternatively include a check inside the interrupt to see if there are more messages to process after you have processed the first. The INT pin will only be reset once the buffer is fully empty.

What does that mean? Does the same code work outside the ISR?

You should check the return value of that method!

Ok, I will try to change the interrupt to a level. This can be the problem because when I try my code, I only receive one message and the program don't enter the interrupt again. The INT pin I have to reset it manually or the library reset it automatically?

Yes, the code works outside the ISR. I don't know if I had to modify anything in the library because I don't know if the library reset by himself the INT pin.

The return of the value of my method works properly.

I posted the method that provides a useful return value and that is not your method.

Post the complete code. The problem is most probably in that part of the code you're hiding from us.

Dashboard_Arduino_ePR02_CAN_v2.ino (9,0 KB)
That's the full code, the final line that calls a function "CAN0.clearInterrupts()" is the function I modified in the .cpp of the library based in other libraries.

  attachInterrupt(digitalPinToInterrupt(CAN0_INT), can_read, FALLING);

That code still uses an edge interrupt and your code doesn't check for multiple messages. If the 2515 still has messages in the queue you cannot reset the interrupt (according to the datasheet).

Ok, so I put the interrupt with LOW but then I had to reset the INT pin or the library does it by himself?

My interpretation of the datasheet is that you can still have the same code (try to reset it each after each message), it won't succeed before the last message was handled. Try it and tell us the result.

I finally get a result but with the library "arduino-mcp2515-master". Some month ago I was using this, but it doesn't work with the display I am configuring because of the CNF values but I change them and it works. I think that library works better than the other.

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