In this example we are using a MCP2518 SPI CAN controller and a ISO1042 Isolated CAN transciever (powered by a Isolated DC-DC buck) for CAN 2.0B Classic communication on a ESP32.
Connection schematic:

MCP2517 MCP2518FD Arduino Library #
Source: https://github.com/pierremolinaro/acan2517FD
Example code #
This example code is wirting 64-byte long messages over the canbus in FD mode
Notice this settings line:
ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_20MHz, 250UL * 1000UL, DataBitRateFactor::x1) ;
Here you can set:
- Oscillator Frequency (20MHz)
- 250UL (250Kbit/s) (arbitrary bitrate)
- Databitrate factor x arbitrary bitrate (x1 = same as arbitrary bitrate)
For more info you can always view the github repository.
Note:
The 0x01 error is raised when the MCP2517FD does not reach the configuration mode in 2ms. It means that the MCP2517FD cannot be accessed via SPI, check the hardware connections.
// ACAN2517FD or ACAN2518FD send-even
#include <ACAN2517FD.h>
// USING ESP32 VSPI pins
// CLK: GPIO 18
// MISO: GPIO 19
// MOSI: GPIO 23
// CS: GPIO 5
static const byte MCP2517_CS = 5 ; // CS pin of MCP2517
static const byte MCP2517_INT = 26 ; // INT pin of MCP2517
ACAN2517FD can (MCP2517_CS, SPI, MCP2517_INT) ;
void setup () {
Serial.begin (115200) ;
SPI.begin () ;
ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_20MHz, 250UL * 1000UL, DataBitRateFactor::x1) ;
settings.mDriverReceiveFIFOSize = 200 ;
const uint32_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
Serial.print ("Bit Rate prescaler: ") ;
Serial.println (settings.mBitRatePrescaler) ;
Serial.print ("Arbitration Phase segment 1: ") ;
Serial.println (settings.mArbitrationPhaseSegment1) ;
Serial.print ("Arbitration Phase segment 2: ") ;
Serial.println (settings.mArbitrationPhaseSegment2) ;
Serial.print ("Arbitration SJW:") ;
Serial.println (settings.mArbitrationSJW) ;
Serial.print ("Actual Arbitration Bit Rate: ") ;
Serial.print (settings.actualArbitrationBitRate ()) ;
Serial.println (" bit/s") ;
Serial.print ("Exact Arbitration Bit Rate ? ") ;
Serial.println (settings.exactArbitrationBitRate () ? "yes" : "no") ;
Serial.print ("Arbitration Sample point: ") ;
Serial.print (settings.arbitrationSamplePointFromBitStart ()) ;
Serial.println ("%") ;
Serial.print ("Data Phase segment 1: ") ;
Serial.println (settings.mDataPhaseSegment1) ;
Serial.print ("Data Phase segment 2: ") ;
Serial.println (settings.mDataPhaseSegment2) ;
Serial.print ("Data SJW:") ;
Serial.println (settings.mDataSJW) ;
Serial.print ("TDCO:") ;
Serial.println (settings.mTDCO) ;
Serial.print ("Even, error code 0x") ;
Serial.println (errorCode, HEX) ;
while (errorCode != 0) { } //Endless loop on error
}
static uint32_t gBlinkLedDate = 0 ;
static uint32_t gSentFrameCount = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
static bool gCompleted = false ;
static const uint32_t SEND_COUNT = 50 * 1000 ;
static void handleReceivedMessages (void) {
CANFDMessage frame ;
while (can.receive (frame)) {
gReceivedFrameCount ++ ;
}
}
void loop () {
handleReceivedMessages () ;
if (gBlinkLedDate < millis ()) {
gBlinkLedDate += 1000 ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
if (!gCompleted) {
Serial.print ("Sent: ") ;
Serial.print (gSentFrameCount) ;
Serial.print (", received: ") ;
Serial.print (gReceivedFrameCount) ;
Serial.print (", errors ") ;
Serial.print (can.errorCounters (), HEX) ;
Serial.print (", op mode ") ;
Serial.print (can.currentOperationMode ()) ;
Serial.print (", rcved buffer ") ;
Serial.print (can.driverReceiveBufferPeakCount ()) ;
Serial.print (", overflows ") ;
Serial.println (can.hardwareReceiveBufferOverflowCount ()) ;
gCompleted = (gReceivedFrameCount >= SEND_COUNT) && (gSentFrameCount >= SEND_COUNT) ;
}
}
if (gSentFrameCount < SEND_COUNT) {
CANFDMessage frame ;
frame.id = micros () & 0x7FE ;
frame.len = 64 ;
for (uint8_t i=0 ; i<frame.len ; i++) {
frame.data [i] = i ;
}
const bool ok = can.tryToSend (frame) ;
if (ok) {
gSentFrameCount += 1 ;
}
}
}
Example output: #
Example output on a Pi system
can0 63E [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
can0 3A2 [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
can0 10E [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F