Arduino Nano ESP32 and MCP2515

I've attempted to use Cory Fowler's MCP2515 library with the Arduino Nano ESP32, and it works successfully on Arduino UNO (5V) and generic ESP32 Wroom32 (3.3V). However, I'm unable to make it work on the Arduino Nano ESP32, despite trying both legacy mode and Arduino Pin configurations. Here's the code and output:

// CAN Receive Example
//

#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 D5                              
MCP_CAN CAN0(D10);                               


void setup()
{
  Serial.begin(9600);
  delay(5000);
  Serial.print("MOSI: ");
  Serial.println(MOSI);
  Serial.print("MISO: ");
  Serial.println(MISO);
  Serial.print("SCK: ");
  Serial.println(SCK);
  Serial.print("SS: ");
  Serial.println(SS);  
  
  // Initialize MCP2515 running at 16MHz 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)
    
    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);
  
    if((rxId & 0x40000000) == 0x40000000){    // Determine if message is a remote request frame.
      sprintf(msgString, " REMOTE REQUEST FRAME");
      Serial.print(msgString);
    } else {
      for(byte i = 0; i<len; i++){
        sprintf(msgString, " 0x%.2X", rxBuf[i]);
        Serial.print(msgString);
      }
    }
        
    Serial.println();
  }
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

Output:

MOSI: 38
MISO: 47
SCK: 48
SS: 21
Entering Configuration Mode Successful!
Setting Baudrate Successful!
MCP2515 Initialized Successfully!
MCP2515 Library Receive Example...

Are you using a module that has both the MCP2515 and a transceiver chip?

Are you powering it with 5v?

Are you voltage downshifting the SPI lines going into the ESP32?

(Most Niren style modules are designed to work at 5v, however some ship with fake transceivers that may work at 3.3v even though they aren't supposed to.)

Thanks for your reply!

Are you using a module that has both the MCP2515 and a transceiver chip?

-Yes I am using a MCP2515 module. It has the MCP2515 controller and TJA1050 transceiver chip

Are you powering it with 5v?

-This is what I thought the problem was too so I tried it with a ESP32 dev board(one's you get off ali) and it worked! This devboard and the mcp2515 were powered with 3.3V. However, the same module doesn't work with the Arduino Nano ESP32 module.

Are you voltage downshifting the SPI lines going into the ESP32?

No I am not but this is because the MCP2515 is powered by 3.3V.

I have just looked and the TJA1050 and the MCP2515 are both 3.3V compatible..

I do not see anywhere how the bus is terminated and that there are two or more nodes on the bus. Can you post a simple schematic showing how this is put together.

The datasheet for the TJA1050 is says it's compatible with the 3.3 or 5v signals on the CAN bus. That's different from the Vcc supply voltage which is listed at 4.75v minimum.

Running it at 3.3v is going to give 'undefined' behavior.

Thank you very much, I suspected that was the case. I will try and see if I can test this with a level shifter.
Just reiterating though it works with the ESP32 dev board which also operates at 3.3V level.

Sure can, hope this helps

The actual signal status, recessive or dominant, is based on the differential voltage Vdiff between CAN_H and CAN_L, not on actual voltage levels. Here is a better explanation: CAN Bus And SAE J1939 Bus Voltage - Copperhill

Were you able to get this working?

Check this link out, your ESP probably has a can controller built in and just needs a transceiver chip.

I wasn't able to get it working with Arduino nano esp32, I think there is a library error which I am not skilled enough to fix. However since then I have switched to ESP32 devkit board with a MCP2515 and that works really well with Cory Fowler's library.