Create Your Own CAN Network With MCP2515 Modules and Arduino

In the old days, cars had more than 2,000 meters of cable in them, connecting switches on the dashboard directly to the headlights and taillights, for instance. As cars became more complex, this simple logic would no longer work. In 1986, Bosch introduced the CAN bus system, which solved this problem and made car manufacturing cheaper and easier. CAN is now the industry standard and is used in everything from cars and trucks to buses and tractors, and even airplanes and ships.

Knowing how to read and parse CAN messages on your Arduino will allow you to obtain data from your car such as coolant temperature, throttle position, vehicle speed, and engine rpm, and use it in your in-dash projects.

The MCP2515 CAN Bus Interface Module is the best solution to add CAN connectivity to your Arduino with SPI interface. This tutorial will show you how to connect the MCP2515 module to an Arduino, but first, a quick primer on the CAN protocol.

Basics of CAN Bus System

A Controller Area Network (CAN bus) is a communications standard designed to allow in-vehicle devices to communicate with each other without a host computer.

To better understand the CAN bus, think of your car as a human body. In this context, the CAN bus is the nervous system.

can bus nervous system analogy

Similar to how the nervous system allows communication between different parts of the body, the CAN bus allows communication between different CAN bus Nodes, also known as Electronic Control Units (or ECUs).

A modern car has over 70 ECUs, each of which is responsible for performing a specific task. Although these ECUs can perform a single task efficiently, they must share information with one another. For example, the engine control module sends the current engine speed to the instrument cluster, where it is displayed on a tachometer; similarly, the driver’s door controller sends a message to the passenger’s door controller to actuate the window.

car ecu can network

ECUs are connected to the bus in a multi-master configuration. Meaning, each ECU can take control of the bus and broadcast information (such as sensor data) over it. The broadcasted data is accepted by all other ECUs on the CAN bus. Each ECU can then read the data and decide whether to accept it or ignore it.

CAN Bus Topology

The physical communication happens via the CAN bus wiring harness, consisting of two wires, CAN low and CAN high. Both wires are twisted tightly together so that electromagnetic interference affects the signal in both wires uniformly, thereby minimizing errors.

can twisted pair

The far ends of the cable are terminated with 120-ohm resistors. Because the CAN bus is a high-speed data bus, if the bus is not terminated, the signal will reflect back and interfere with the next data signal coming down the line, potentially disrupting communications and causing the bus to fail.

can bus

CAN Signaling

To enable data transmission on these wires, their voltage levels are changed. These changes in voltage levels are then translated to logic levels enabling nodes on the network to communicate with one another.

can signaling

To transmit a “logic 1” on the CAN bus, the voltage on both lines is set to 2.5 volts (i.e. there is no voltage difference). This state is known as the Recessive State, and it indicates that the CAN bus is available for use by any node.

In contrast, to transmit “logic 0”, the CAN high line is set to 3.5 volts and the CAN low line to 1.5 volts (i.e. there is a 2V voltage difference). This state of the bus is known as the Dominant State, which tells every node on the bus that another node is transmitting and that it should wait until the transmission is finished before transmitting its message.

CAN Bus Node

Each CAN node contains a CAN transceiver, a CAN controller, and a microcontroller.

can node ecu

A CAN transceiver

  • When receiving: It converts the voltage levels on the CAN bus to levels that the CAN controller can understand.
  • When transmitting: It converts the data stream from the CAN controller to CAN bus levels.

A CAN controller

  • When transmitting: It transmits the message from the microcontroller serially onto the bus when the bus is free.
  • When receiving: It stores the received serial bits from the bus until an entire message is available, and instructs the microcontroller to retrieve it (usually by triggering an interrupt).

A microcontroller

It decides what the received messages mean and what messages it wants to transmit. Sensors, actuators and control devices are connected to it.

A Standard CAN Frame

Communication over the CAN bus is done via CAN frames. Here is a standard CAN frame with an 11 bit identifier. Let’s take a quick look at each of the eight message fields:

can frame
  • SOF: The Start of Frame is a ‘dominant 0’ to tell the other nodes that a CAN node intends to talk.
  • ID: The ID is the frame identifier. It is used to specify what the message means, and who’s sending it. The ID also defines the priority: the lower the ID, the higher the message’s priority.
  • RTR: The Remote Transmission Request indicates whether a node sends data or requests data from another node.
  • Control: The Control contains the Identifier Extension Bit (IDE) which is a ‘dominant 0’ for 11-bit. It also contains the 4 bit Data Length Code (DLC) that specifies how many bytes of data will be in the message.
  • Data: The 8 bytes of data contain the actual information.
  • CRC: The Cyclic Redundancy Check is for error detection.
  • ACK: The ACK slot indicates if the node has acknowledged and received the data correctly.
  • EOF: The EOF marks the end of the CAN frame.

The CAN bus is unique in that it is a message-based protocol. Typically, on a distributed network, each device has a unique ID to distinguish it from other devices on the same bus, and messages are sent from device A to device B based on their IDs.

On the contrary, nodes on the CAN Bus do not have IDs. Rather, each message is assigned a unique CAN ID that indicates what the message is about. All nodes receive all messages, and each node filters the messages that are relevant to it.

MCP2515 Module Hardware Overview

The MCP2515 CAN Bus Interface Module is a complete CAN solution that includes the MCP2515 CAN controller from Microchip and TJA1050 High speed CAN transceiver from Philips. It is the best solution to add CAN connectivity to your Arduino with SPI interface.

Due to its reliability and robustness, the MCP2515 Module can be used in various projects that require reliable data transfer in noisy environments, or over a substantial distance.

The MCP2515 CAN Controller

The MCP2515 is a stand-alone CAN controller that implements the CAN specification, Version 2.0B. It is capable of transmitting and receiving both standard and extended data and remote frames. The MCP2515 includes masks and filters for filtering out unwanted messages, which reduces the host MCU’s overhead.

mcp2515 can controller

The MCP2515 has an interrupt (INT) output pin that can trigger an MCU interrupt when a valid message is received and loaded into one of the receive buffers.

The TJA1050 CAN Transceiver

The TJA1050 serves as an interface between a MCP2515 CAN controller and the physical two-wire CAN bus, and meets the automotive requirements for the high-speed (up to 1Mb/s), low quiescent current, electromagnetic compatibility and electrostatic discharge.

tja1050 can transceiver

The TJA1050 CAN transceiver allows for a maximum of 110 nodes to be connected to the bus.

CAN Bus Connector

There is a 2-pole screw terminal (labeled as H and L) on board for connecting CAN bus twisted pair cable.

mcp2515 can module bus connectors

The MCP2515 Module supports data rates of up to 1Mb/s. However, the maximum transfer speed is determined by the length of the bus line: longer bus lines result in slower transfer speeds. The maximum bus length at 1 Mb/s is 40 meters, while at 125 kb/s it can reach 500 meters.

Node Termination

The CAN bus needs to be terminated on both ends by resistors, in order to prevent line reflections. Therefore, the MCP2515 Module features a 120 ohm termination resistor as well as a node termination jumper. To enable the resistor, you must keep the jumper in place.

mcp2515 can module termination jumper

If the module is the first or the last node of the CAN network, then the jumper should be placed. If the module is a middle node, the jumper should be removed.

Technical Specifications

Here are the specifications:

Operating Voltage4.75 to 5.25V (based on TJA1050 requirements)
CAN specificationVersion 2.0B at 1 Mb/s
Crystal Frequency8Mhz
Transmit BuffersThree transmit buffers with prioritization and abort features
Receive BuffersTwo receive buffers with prioritized message storage
Message FiltersSix 29-bit filters
MasksTwo 29-bit masks
Interrupt OutputsOne interrupt with selectable enables
InterfaceHigh-Speed SPI (10 MHz)

For more information about the MCP2515 CAN controller, please refer to the datasheet below.

For more information about the TJA1050 CAN transceiver, please refer to the datasheet below.

MCP2515 Module Pinout

Now let’s have a look at the pinout.

mcp2515 can module pinout

Input Connector

The breakout pins on one side of the module are used to communicate with the microcontroller.

INT pin generates an interrupt when a valid message has been received and loaded into one of the receive buffers.

SCK is the SPI clock pin.

SI is the Serial data In / MOSI pin, for data sent from your Arduino to the module.

SO is the Serial data Out / MISO pin, for data sent from the module to your Arduino.

CS is the chip select pin. It must be held low to start an SPI transaction.

GND is common ground for power and logic.

VCC is the power pin. Connect it to 5V power supply only.

CAN Bus Connector

On the other side of the module, there is a 2-pin screw terminal and a 2-pin male header for connecting CAN bus twisted pair cable.

L is the CAN low signal for the CAN Bus standard.

H is the CAN high signal for the CAN Bus standard.

Hardware Hookup

Now that we know everything about the module, let’s construct our own CAN network.

Example 1: Simple two node CAN Network

In this example, a simple two node CAN bus network is constructed – one node transmits a message, the other receives it.

To begin, connect the VCC pin on the module to 5V on the Arduino and the GND pin to ground.

Let’s wire up the SPI pins. Note that each Arduino board has a unique set of SPI pins that must be connected accordingly. For Arduino boards such as the UNO/Nano V3.0, these pins are digital 13 (SCK), 12 (MISO), 11 (MOSI), and 10 (CS). If you’re using a different Arduino board, check the official documentation for SPI pin locations before proceeding.

Now, connect the module’s INT pin to the Arduino’s digital pin 2.

You need to make two such circuits. One will act as a transmitter and the other as a receiver. Both have the same wiring.

Connecting the modules is straightforward: CAN L connects to CAN L and CAN H connects to CAN H. The wires should ideally be twisted pair, but for simple breadboard testing or other short runs, this is not required.

It’s important to keep in mind that as the bus length increases or environmental electrical noise increases, using twisted pair and adding shielding becomes more important.

Finally, place the jumper on both modules, as this is a simple two-node CAN bus network.

Construct the network as shown.

two node can network mcp2515 arduino wiring

Example 2: Multi-Node CAN Network

In this example, a larger CAN network is constructed – multiple nodes send messages and one node relays them to a PC over a serial port.

Other nodes can be added between the two end nodes. These can be spliced in-line or attached to the main bus using a short stub cable as long as the length is kept under 12″.

Finally, place the jumper on the CAN network’s first and last nodes and remove it from the nodes in between.

Construct the network as shown.

multi node can network mcp2515 arduino wiring

Library Installation

There’s a really great library available for working with the MCP2515 module. You will need to download and install it in your Arduino IDE.

To install the library, navigate to Sketch > Include Library > Manage Libraries… Wait for the Library Manager to download the library index and update the list of installed libraries.

manage libraries 2

Filter your search by entering ‘mcp2515’. Look for CAN by Sandeep Mistry. Click on that entry and then choose Install.

can arduino library installation

Arduino Example Code

In this simple test, we’ll attempt to transmit a “Hello World” message on the CAN bus to see if it can be decoded. It will help you learn how to use the modules and can serve as the foundation for more practical experiments and projects.

Code for the Transmitter Node

Upload this sketch to the transmitter node.

If you have multiple nodes on a CAN bus, upload this sketch to each of the transmitter nodes. Make sure to change the message IDs to unique values for each node.

#include <CAN.h>

void setup() {
  while (!Serial);

  Serial.println("CAN Sender");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);

void loop() {
  // send packet: id is 11 bits, packet can contain up to 8 bytes of data
  Serial.print("Sending packet ... ");




  // send extended packet: id is 29 bits, packet can contain up to 8 bytes of data
  Serial.print("Sending extended packet ... ");




Code for the Receiver Node

Upload this sketch to the receiver node.

#include <CAN.h>

void setup() {
  while (!Serial);

  Serial.println("CAN Receiver Callback");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);

  // register the receive callback

void loop() {
  // do nothing

void onReceive(int packetSize) {
  // received a packet
  Serial.print("Received ");

  if (CAN.packetExtended()) {
    Serial.print("extended ");

  if (CAN.packetRtr()) {
    // Remote transmission request, packet contains no data
    Serial.print("RTR ");

  Serial.print("packet with id 0x");
  Serial.print(CAN.packetId(), HEX);

  if (CAN.packetRtr()) {
    Serial.print(" and requested length ");
  } else {
    Serial.print(" and length ");

    // only print packet data for non-RTR packets
    while (CAN.available()) {


Notice that the loop function is left empty, as the sketch uses an interrupt to notify the Arduino whenever a valid message is received and loaded into one of the receive buffers.


After uploading the sketch, open the serial monitor at a baud rate of 9600. The transmitter node sends a standard CAN packet and an extended CAN packet every second.

mcp2515 can transmitter node output

The receiver node receives it and passes it on to the PC over the serial port.

mcp2515 can receiver node output