How to handle receive interrupts with ESP32 microcontroller and MCP2515

Hello. I am currently trying to do CAN communication using an ESP32-WROOM-32E and an MCP2515.

I would appreciate it if someone could tell me more about the inability to process interrupts when receiving CAN.

ESP32 MCP2515 CAN Library

We are currently using the library listed in the link above. The development environment is Arduino IDE.

The pin layout of MCP2515 and ESP32 is as follows.

MISO 19
MOSI 23
SCK 18
CS 5
INT 16

The code used is based on the READ.ME description on GitHub.

The code for CAN reception is as follows.

#include "mcp2515.h"
#include "esp_system.h"
#include "driver/spi_master.h"

struct can_frame frame;
spi_device_handle_t spi;

MCP2515 canbus(&spi);

void setup() {
  Serial.begin(9600);
  while (!Serial) {};
  canbus.setBitrate(CAN_500KBPS, MCP_8MHZ);
  canbus.setNormalMode();
}

void loop() {
  if (canbus.readMessage(&frame) == MCP2515::ERROR_OK) {
     //if (frame.can_id == 0xE8) {
        Serial.println(" ");
        Serial.print("DATA: ");
        for (int i = 0; i < frame.can_dlc; i++) {
          Serial.print(frame.data[i], HEX);
          Serial.print(" ");
        }
    // }    
  }

 delay(10);
}

Where I was able to reflect the settings,
canbus.setBitrate(CAN_500KBPS, MCP_8MHZ);
canbus.setNormalMode();
These are two.

When I ran this program, I received the data without any problems.

However, there is a problem with this program. It uses a polling method, which often means that data cannot be retrieved completely. So I tried to do an interrupt process.

#include "mcp2515.h"
#include "esp_system.h"
#include "driver/spi_master.h"

bool interrupt = true;


void irqHandler(){
  interrupt = true;//ISR
  

}

struct can_frame frame;
spi_device_handle_t spi;


MCP2515 canbus(&spi);

void setup() {
  Serial.begin(9600);
  while(!Serial){};
  //pinMode(16,INPUT_PULLDOWN);
  canbus.setBitrate(CAN_500KBPS, MCP_8MHZ);

  canbus.setNormalMode();


  //canbus.setFilter(MCP2515::RXF0, false, 0xE8);
  //canbus.setFilter(MCP2515::RXF1, false, 0xE8);
  
  attachInterrupt(digitalPinToInterrupt(16), irqHandler ,FALLING);
  



}

void loop() {
  

  if (interrupt){
    Serial.print("IRQ Flags: 0x");
    interrupt = false;
    
    uint8_t irq = canbus.getInterrupts();

    if (irq & MCP2515::CANINTF_RX0IF){
      if (canbus.readMessage(MCP2515::RXB0, &frame) == MCP2515::ERROR_OK){
        //受信したメッセージをシリアルモニタに表示
        Serial.println(" ");
        Serial.print("DATA RXB0IF");
        for (int i = 0 ; i < frame.can_dlc; i++){
          Serial.print(frame.data[i], HEX);
          Serial.print(" ");
        }

       }
    }

    if (irq & MCP2515::CANINTF_RX1IF){
      if (canbus.readMessage(MCP2515::RXB1, &frame) == MCP2515::ERROR_OK){
        Serial.println(" ");
        Serial.print("DATA RBXIF");
        for (int i = 0 ; i < frame.can_dlc; i++){
          Serial.print(frame.data[i],HEX);
          Serial.print(" ");
        }

      }
    }
  } 


  

}

The program above is how the interrupt process is received.

The main problem with this program is that the interrupts do not respond, so if and below are not processed and are not displayed on the serial monitor at all.

We confirmed that the interrupt pin was set to pin 16 and that there were no wiring errors. We also confirmed from the datasheet that ESP32 can handle interrupts on all GPIO pins.

Also, if I commented out the if (interrupt){ part, CAN reception started without any problem and it was displayed on the serial monitor.

Next, I checked the MCP2515 datasheet and found that the INT pin changes from 5V to 0V when data accumulates in buffer 0 or 1.

I found the following configuration item at line 82 in the MCP2515.cpp source.

setRegister(MCP_CANINTE, CANINTF_RX0IF | CANINTF_RX1IF | CANINTF_ERRIF | CANINTF_MERRF);

This configuration item is supposed to be enabled at one point. (Maybe it is not).

Assuming that the settings are valid, I attached an oscilloscope to the INT pin and checked it, and it remained at 5V all the time and I could not see where it dropped to 0V.
The fact that the INT pin does not change is definitely the cause of the lack of interrupt processing.

However, although I have spent quite a bit of time on it, I can't figure out where to set it up to make it work. I would appreciate any and all advice from any great people who are familiar with this.

Thank you for your cooperation.

I have moved your topic from an Spanish language category in this forum to the English Forum > Project > General Guidance

From now on, please use the appropriate category for the language you wish to post in. This is important for the responsible use of the forum, and it is explained in the guide "How to get the best out of this forum."
This guide contains a lot of useful information. Please take the time to read it.

Thank you in advance for your cooperation.

How to get the best out of this forum read. Thanks for the pertinent advice.

The following question form was used to resolve the issue.

CAN_RECEIVE

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