ESP32 CAN Bus Tutorial | Interfacing MCP2515 CAN Module with ESP32
ESP32 CAN Bus Tutorial using the MCP2515 Module by Interfacing MCP2515 with ESP32 to transmit Sensor Data using CAN Protocol Communication
- Suitable forB.Tech/Diploma ESP32/IoT students
- Build time1-2 weeks
- LevelBeginner
- Available atAjvika Labs, Kakinada
About this project
Overview
In this tutorial, we will explore the CAN Bus communication protocol by interfacing the MCP2515 CAN Bus Module with ESP32 microcontroller. Our objective is to transmit data from a DS18B20 temperature sensor over a specified distance using the CAN protocol. In earlier tutorial, we used
MCP2515 with Arduino
for CAN Bus communication.
The Controller Area Network (CAN) Bus is widely used in industrial settings and automotive diagnostics due to its ability to cover long distances, moderate communication speed, and high reliability. The standard protocols like UART, SPI, and I2C are less reliable over long distances. But CAN is ideal for vehicular systems and environments where communication occurs over extensive wiring. CAN communication typically supports speeds ranging from 50 Kbps to 1 Mbps and can maintain signal integrity over distances from 40 meters at 1 Mbps to up to 1000 meters at 50 Kbps.
We will use a pair of ESP32 boards and MCP2515 modules to demonstrate the transmission of DS18B20 temperature sensor data. The transmitted data will be received by receiver over and is displayed on OLED Display. Let’s get started with today’s guide on CAN Bus communication using the Microchip MCP2515 CAN Bus Module.
Bill of Materials
Here are the list of components that you need for this tutorial
S.N.
Components
Quantity
1
ESP32 Board
2
Amazon
AliExpress
2
CAN Module MCP2515
2
Amazon
AliExpress
3
OLED Display
1
Amazon
AliExpress
4
DS18B20 Temperature Sensor
1
Amazon
AliExpress
5
Resistor 4.7K
1
Amazon
AliExpress
6
Jumper Wires
30
Amazon
AliExpress
7
Breadboard
2
Amazon
AliExpress
MCP2515 CAN Bus Controller Module
The MCP2515 CAN Bus Controller is a simple Module that supports CAN Protocol version 2.0B and can be used for communication at 1Mbps.
This particular module is based on MCP2515 CAN Controller IC and TJA1050 CAN Transceiver IC. The MCP2515 IC is a standalone CAN Controller and has an integrated SPI Interface for communication with microcontrollers. Coming to the TJA1050 IC, it acts as an interface between the MCP2515 CAN Controller IC and the Physical CAN Bus.
The board has a 8 MHz Crystal oscillator. Even the 16 MHz version is also available. A jumper can be attached which will give 120ohm Termination. CAN_H & CAN_L are the two screws where wires can be attached over a distance for communicating with other CAN Module.
Following is the schematic of MCP2515 CAN Module.
MCP2515 IC is the main controller that internally consists of three main subcomponents: The CAN Module, the Control Logic, and the SPI Block. CAN Module is responsible for transmitting and receiving messages on the CAN Bus. Control Logic handles the setup and operation of the MCP2515 by interfacing all the blocks. The SPI Block is responsible for the SPI communication interface. The TJA1050 IC IC is responsible for taking the data from the controller and relaying it onto the bus.
Features and Specification of MCP2515
Uses High-speed CAN transceiver TJA1050
Dimension: 40×28mm
SPI control for expanding Multi CAN bus interface
8MHZ crystal oscillator
120Ω terminal resistance
Has independent key, LED indicator, Power indicator
Supports 1 Mb/s CAN operation
Low current standby operation
Up to 112 nodes can be connected
For more information refer to
MCP2515 Datasheet
which also has a detailed guide.
Interfacing MCP2515 CAN Bus Module with ESP32
Now let us interface MCP2515 CAN Bus Module with ESP32 Board and test the CAN Communication protocol. We will transmit the DS18B20 Waterproof Temperature Sensor data over a CAN Bus with the help of pair of ESP32 Board & MCP2515 CAN Module. Here is the simple connection diagram.
The left part consisting of ESP32 Board, MCP2515 CAN Module & DS18B20 Sensor is a transmitter part.
Similarly, the right part consisting of ESP32 Board, MCP2515 CAN Module & OLED Display is the receiver part.
The transmitter & Receiver Part is connected to each other with the help of the MCP2515 CAN Bus Module. The CAN_H & CAN_L of the transmitter are connected to the CAN_H & CAN_L of the receiver respectively.
The connection between ESP32 Board & MCP2515 CAN Module is as follows.
MCP2515 Pin
ESP32 Pin
VCC
5V
GND
GND
CS
IO5
SO
IO19
SI
IO23
SCK
IO13
INT
IO4
On the transmitter part, the DS18B20 Sensor pin is connected to ESP32 IO21 Pin. The DS18B20 Sensor output is connected to VCC via 4.7K resistor.
On the receiver part, the I2C OLED Display has 4 pins & VCC, GND, SCL, and SDA. The SCL & SDA are I2C Pins that are connected to the IO22 & IO21 of the ESP32 Board. The VCC & GND of OLED connects to the 3.3V & GND of Arduino.
You can assemble the circuit on a breadboard or you can use your own custom PCB for this project.
Source Code/Program for ESP32 MCP2515 CAN Communication
Before moving to the coding part of the project, we need to install MCP2515 CAN Bus Library to the Arduino IDE. Download the library from the following link and then add it to the Arduino Library folder.
MCP2515 CAN interface Library
This CAN-BUS library gives your ESP32 CAN-BUS capability with the following features.
Implements CAN V2.0B at up to 1 Mb/s
SPI Interface up to 10 MHz
Standard (11 bit) and extended (29 bit) data and remote frames
Two receive buffers with prioritized message storage
You also need to add
OneWire Library
as well as
Dallas Temperature Library
for DS18B20 Temperature sensor.
The code is divided into two parts one as CAN transmitter code and the other as CAN Receiver code.
ESP32 CAN Transmitter Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include `OneWire.h`
#include `DallasTemperature.h`
#include `SPI.h`
#include `mcp2515.h`
#define ONE_WIRE_BUS 21 // GPIO where the DS18B20 is connected
OneWire
oneWire
(
ONE_WIRE_BUS
)
;
DallasTemperature
sensors
(
&
oneWire
)
;
struct
can_frame
canMsg
;
struct
MCP2515
mcp2515
(
5
)
;
// CS pin is GPIO 5
#define MAX_RETRIES 3
#define CAN_ACK_ID 0x037 // CAN ID for acknowledgment
void
setup
(
)
{
Serial
begin
(
115200
)
;
SPI
begin
(
)
;
mcp2515
reset
(
)
;
mcp2515
setBitrate
(
CAN_500KBPS
MCP_8MHZ
)
;
mcp2515
setNormalMode
(
)
;
sensors
begin
(
)
;
}
void
loop
(
)
{
sensors
requestTemperatures
(
)
;
float
temperatureC
=
sensors
getTempCByIndex
(
0
)
;
int
tempInt
=
(
int
)
(
temperatureC *
100
)
;
// Convert temperature to integer for transmission
// Prepare CAN message
canMsg
can_id
=
0x036
;
// CAN ID
canMsg
can_dlc
=
2
;
// Data length code (number of bytes)
canMsg
data
[
0
]
=
(
tempInt
>>
8
)
&
0xFF
;
// MSB of temperature
canMsg
data
[
1
]
=
tempInt
&
0xFF
;
// LSB of temperature
bool
messageSent
=
false
;
int
retries
=
0
;
while
(
!
messageSent
&&
retries
<
MAX_RETRIES
)
{
if
(
mcp2515
sendMessage
(
&
canMsg
)
==
MCP2515
::
ERROR_OK
)
{
Serial
(
\"Temperature sent: \"
)
;
Serial
(
temperatureC
)
;
Serial
println
(
\" °C\"
)
;
// Wait for acknowledgment
unsigned
long
startTime
=
millis
(
)
;
bool
ackReceived
=
false
;
while
(
millis
(
)
startTime
<
500
)
{
// Wait up to 500ms for an ACK
if
(
mcp2515
readMessage
(
&
canMsg
)
==
MCP2515
::
ERROR_OK
)
{
if
(
canMsg
can_id
==
CAN_ACK_ID
)
{
ackReceived
=
true
;
break
;
}
}
}
if
(
ackReceived
)
{
Serial
println
(
\"ACK received\"
)
;
messageSent
=
true
;
}
else
{
Serial
println
(
\"ACK not received, retrying...\"
)
;
retries
++
;
}
}
else
{
Serial
println
(
\"Error sending message, retrying...\"
)
;
retries
++
;
}
}
if
(
!
messageSent
)
{
Serial
println
(
\"Failed to send message after retries\"
)
;
}
delay
(
1000
)
;
// Send data every second
}
ESP32 CAN Receiver Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include `SPI.h`
#include <mcp2515
In this tutorial, we will explore the CAN Bus communication protocol by interfacing the MCP2515 CAN Bus Module with ESP32 microcontroller. Our objective is to transmit data from a DS18B20 temperature sensor over a specified distance using the CAN protocol. In earlier tutorial, we used
MCP2515 with Arduino
for CAN Bus communication.
The Controller Area Network (CAN) Bus is widely used in industrial settings and automotive diagnostics due to its ability to cover long distances, moderate communication speed, and high reliability. The standard protocols like UART, SPI, and I2C are less reliable over long distances. But CAN is ideal for vehicular systems and environments where communication occurs over extensive wiring. CAN communication typically supports speeds ranging from 50 Kbps to 1 Mbps and can maintain signal integrity over distances from 40 meters at 1 Mbps to up to 1000 meters at 50 Kbps.
We will use a pair of ESP32 boards and MCP2515 modules to demonstrate the transmission of DS18B20 temperature sensor data. The transmitted data will be received by receiver over and is displayed on OLED Display. Let’s get started with today’s guide on CAN Bus communication using the Microchip MCP2515 CAN Bus Module.
Bill of Materials
Here are the list of components that you need for this tutorial
S.N.
Components
Quantity
1
ESP32 Board
2
Amazon
AliExpress
2
CAN Module MCP2515
2
Amazon
AliExpress
3
OLED Display
1
Amazon
AliExpress
4
DS18B20 Temperature Sensor
1
Amazon
AliExpress
5
Resistor 4.7K
1
Amazon
AliExpress
6
Jumper Wires
30
Amazon
AliExpress
7
Breadboard
2
Amazon
AliExpress
MCP2515 CAN Bus Controller Module
The MCP2515 CAN Bus Controller is a simple Module that supports CAN Protocol version 2.0B and can be used for communication at 1Mbps.
This particular module is based on MCP2515 CAN Controller IC and TJA1050 CAN Transceiver IC. The MCP2515 IC is a standalone CAN Controller and has an integrated SPI Interface for communication with microcontrollers. Coming to the TJA1050 IC, it acts as an interface between the MCP2515 CAN Controller IC and the Physical CAN Bus.
The board has a 8 MHz Crystal oscillator. Even the 16 MHz version is also available. A jumper can be attached which will give 120ohm Termination. CAN_H & CAN_L are the two screws where wires can be attached over a distance for communicating with other CAN Module.
Following is the schematic of MCP2515 CAN Module.
MCP2515 IC is the main controller that internally consists of three main subcomponents: The CAN Module, the Control Logic, and the SPI Block. CAN Module is responsible for transmitting and receiving messages on the CAN Bus. Control Logic handles the setup and operation of the MCP2515 by interfacing all the blocks. The SPI Block is responsible for the SPI communication interface. The TJA1050 IC IC is responsible for taking the data from the controller and relaying it onto the bus.
Features and Specification of MCP2515
Uses High-speed CAN transceiver TJA1050
Dimension: 40×28mm
SPI control for expanding Multi CAN bus interface
8MHZ crystal oscillator
120Ω terminal resistance
Has independent key, LED indicator, Power indicator
Supports 1 Mb/s CAN operation
Low current standby operation
Up to 112 nodes can be connected
For more information refer to
MCP2515 Datasheet
which also has a detailed guide.
Interfacing MCP2515 CAN Bus Module with ESP32
Now let us interface MCP2515 CAN Bus Module with ESP32 Board and test the CAN Communication protocol. We will transmit the DS18B20 Waterproof Temperature Sensor data over a CAN Bus with the help of pair of ESP32 Board & MCP2515 CAN Module. Here is the simple connection diagram.
The left part consisting of ESP32 Board, MCP2515 CAN Module & DS18B20 Sensor is a transmitter part.
Similarly, the right part consisting of ESP32 Board, MCP2515 CAN Module & OLED Display is the receiver part.
The transmitter & Receiver Part is connected to each other with the help of the MCP2515 CAN Bus Module. The CAN_H & CAN_L of the transmitter are connected to the CAN_H & CAN_L of the receiver respectively.
The connection between ESP32 Board & MCP2515 CAN Module is as follows.
MCP2515 Pin
ESP32 Pin
VCC
5V
GND
GND
CS
IO5
SO
IO19
SI
IO23
SCK
IO13
INT
IO4
On the transmitter part, the DS18B20 Sensor pin is connected to ESP32 IO21 Pin. The DS18B20 Sensor output is connected to VCC via 4.7K resistor.
On the receiver part, the I2C OLED Display has 4 pins & VCC, GND, SCL, and SDA. The SCL & SDA are I2C Pins that are connected to the IO22 & IO21 of the ESP32 Board. The VCC & GND of OLED connects to the 3.3V & GND of Arduino.
You can assemble the circuit on a breadboard or you can use your own custom PCB for this project.
Source Code/Program for ESP32 MCP2515 CAN Communication
Before moving to the coding part of the project, we need to install MCP2515 CAN Bus Library to the Arduino IDE. Download the library from the following link and then add it to the Arduino Library folder.
MCP2515 CAN interface Library
This CAN-BUS library gives your ESP32 CAN-BUS capability with the following features.
Implements CAN V2.0B at up to 1 Mb/s
SPI Interface up to 10 MHz
Standard (11 bit) and extended (29 bit) data and remote frames
Two receive buffers with prioritized message storage
You also need to add
OneWire Library
as well as
Dallas Temperature Library
for DS18B20 Temperature sensor.
The code is divided into two parts one as CAN transmitter code and the other as CAN Receiver code.
ESP32 CAN Transmitter Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include `OneWire.h`
#include `DallasTemperature.h`
#include `SPI.h`
#include `mcp2515.h`
#define ONE_WIRE_BUS 21 // GPIO where the DS18B20 is connected
OneWire
oneWire
(
ONE_WIRE_BUS
)
;
DallasTemperature
sensors
(
&
oneWire
)
;
struct
can_frame
canMsg
;
struct
MCP2515
mcp2515
(
5
)
;
// CS pin is GPIO 5
#define MAX_RETRIES 3
#define CAN_ACK_ID 0x037 // CAN ID for acknowledgment
void
setup
(
)
{
Serial
begin
(
115200
)
;
SPI
begin
(
)
;
mcp2515
reset
(
)
;
mcp2515
setBitrate
(
CAN_500KBPS
MCP_8MHZ
)
;
mcp2515
setNormalMode
(
)
;
sensors
begin
(
)
;
}
void
loop
(
)
{
sensors
requestTemperatures
(
)
;
float
temperatureC
=
sensors
getTempCByIndex
(
0
)
;
int
tempInt
=
(
int
)
(
temperatureC *
100
)
;
// Convert temperature to integer for transmission
// Prepare CAN message
canMsg
can_id
=
0x036
;
// CAN ID
canMsg
can_dlc
=
2
;
// Data length code (number of bytes)
canMsg
data
[
0
]
=
(
tempInt
>>
8
)
&
0xFF
;
// MSB of temperature
canMsg
data
[
1
]
=
tempInt
&
0xFF
;
// LSB of temperature
bool
messageSent
=
false
;
int
retries
=
0
;
while
(
!
messageSent
&&
retries
<
MAX_RETRIES
)
{
if
(
mcp2515
sendMessage
(
&
canMsg
)
==
MCP2515
::
ERROR_OK
)
{
Serial
(
\"Temperature sent: \"
)
;
Serial
(
temperatureC
)
;
Serial
println
(
\" °C\"
)
;
// Wait for acknowledgment
unsigned
long
startTime
=
millis
(
)
;
bool
ackReceived
=
false
;
while
(
millis
(
)
startTime
<
500
)
{
// Wait up to 500ms for an ACK
if
(
mcp2515
readMessage
(
&
canMsg
)
==
MCP2515
::
ERROR_OK
)
{
if
(
canMsg
can_id
==
CAN_ACK_ID
)
{
ackReceived
=
true
;
break
;
}
}
}
if
(
ackReceived
)
{
Serial
println
(
\"ACK received\"
)
;
messageSent
=
true
;
}
else
{
Serial
println
(
\"ACK not received, retrying...\"
)
;
retries
++
;
}
}
else
{
Serial
println
(
\"Error sending message, retrying...\"
)
;
retries
++
;
}
}
if
(
!
messageSent
)
{
Serial
println
(
\"Failed to send message after retries\"
)
;
}
delay
(
1000
)
;
// Send data every second
}
ESP32 CAN Receiver Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include `SPI.h`
#include <mcp2515
Technologies used
Hardware components
- ESP32
- Arduino
- DS18B20
- OLED
- Relay
Software & tools
- Arduino IDE
What you get
- Working project / hardware kit, tested before delivery
- Complete source code with explanation
- Project demo and guidance for your viva
- Project report, PPT and IEEE paper support (on request)
Delivery & Payment
Delivery takes a minimum of two weeks from the date your inquiry is confirmed.
Payment is in two parts:
• 50% advance to start the project
• Remaining 50% before delivery
Note:
• Documentation and PPT are not included by default
• If you need documentation/PPT, it can be arranged for extra time and cost
We'll confirm the exact timeline and cost with you after reviewing your requirements.