Raspberry Pi – CAN Bus communicatie (GPIO)

Het is mogelijk een raspberry pi te gebruiken met een CAN Bus interface, met CAN Bus kan je datalijnen gebruiken tot ca. 5000m, en apparaten werken peer-to-peer (ipv master – slave) dat is erg interessant!

Wat je nodig hebt is een CAN Bus module met een controller en transciever om het differentiële signaal van de CAN Bus bus om te zetten naar SPI signalen voor de Arduino (en andersom).

Hardware 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. In order to setup a complete communication system, you will need two CAN Bus Module.

  • Supports CAN V2.0B specification, with communication speed up to 1Mb/s.
  • 0 to 8-byte data field with standard frame, extended frame and remote frame.
  • 5V DC power supply module, SPI interface protocol control.
  • Onboard 120 Ohm termination resistor.
  • Working current: 5mA (1 microamp standby current).
  • Operating temperature: -40 C – +85 C

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 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 following image shows the components and pins on a typical MCP2515 Module:

MCP2515 datasheet (Microchip)

TJA1050 datasheet (NXP)

Module schema

Before seeing the schematic of the module, you need to understand a couple of things about both the ICs i.e. MCP2515 and TJA1050.

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.

Coming to the TJA1050 IC, since it acts as an interface between MCP2515 CAN Controller and the physical CAN Bus, this IC is responsible for taking the data from the controller and relaying it on to the bus.

The following image shows the schematic of the MCP2515 CAN Module and it shows how MCP2515 IC and TJA1050 IC are connected on the Module.

Schema met component waarden:

Before connecting to the Raspberry Pi

While this module is dirt cheap and extremely prevalent, it is not 3.3V compatible and hence Raspberry PI compatible. This board is designed to work from 5V only.

The on-board Microchip MCP2515 CAN Controller supports a wide voltage range from 2.7 to 5.5V. However, the CAN Transceiver, the TJA1050 from NXP only supports 4.75 to 5.25V.

Solution(s) to make this module suitable for the Raspberry Pi 3.3V

  • Levelshifter?

Note: You can not use a levelshifter 3.3V <> 5.0V, the MPC2515 will not be recognized for intialisation by the Raspberry Pi !

  • MCP2515 CAN Bus Module Board with TJA1050 SN65HVD230

If you are proficient at SMD rework, you can remove the 5V CAN Transceiver and install a 3.3V version. I did this and opted to replace the 5V TJA1050 with the 3.3V SN65HVD230.

  • MPC2515 3.3V adjustment

With a pincet, bent this VCC pin (see under) upwards, solder a wire on it and connect to 3.3V on the pi:

Raspberry Pi connection

Sluit de CAN Bus Module aan zoals hieronder aangegeven (let op pas de 3.3V hack toe).

Voorbeeld op de Raspberry pi ZERO:


The PiCAN2 board provide CAN-Bus capability for the Raspberry Pi. It uses the Microchip MCP2515 CAN controller with MCP2551 CAN transceiver. Connection are made via DB9 or 3 way screw terminal.

Easy to install SocketCAN driver. Programming can be done in C or Python.


  • CAN v2.0B at 1 Mb/s
  • High speed SPI Interface (10 MHz)
  • Standard and extended data and remote frames
  • CAN connection via standard 9-way sub-D connector or screw terminal
  • Compatible with OBDII cable
  • Solder bridge to set different configuration for DB9 connector
  • 120? terminator ready
  • Serial LCD ready
  • LED indicator
  • Foot print for two mini push buttons
  • Four fixing holes, comply with Pi Hat standard
  • SocketCAN driver, appears as can0 to application
  • Interrupt RX on GPIO25



  • Raspberry Pi connectivity, compatible with Raspberry Pi Zero/Zero W/Zero WH/2B/3B/3B+
  • CAN function, onboard CAN controller MCP2515 via SPI interface, onboard transceiver SN65HVD230
  • RS485 function, controlled via UART, half-duplex communication, supports automatic TX/RX control without programming, onboard transceiver SP3485
  • Onboard TVS (Transient Voltage Suppressor), effectively suppress surge voltage and transient spike voltage in the circuit for RS485 transceiving, lightning-proof & anti-electrostatic
  • Reserved control pins, allows to work with other control boards
  • Comes with development resources and manual (examples in wiringPi/python)


  • Operating voltage: 3.3V
  • CAN controller: MCP2515
  • CAN transceiver: SN65HVD230
  • 485 transceiver: SP3485
  • Dimension: 65mm x 30mm
  • Mounting hole size: 3.0mm
3V3 3V3 3.3V Power
GND GND Ground
SCK P11 / SCLK SPI clock input
MOSI P10 / MOSI SPI data input
MISO P9 / MISO SPI data output
CS P8 / CE0 SPI chip selection
INT P25 Interrupt
RXD P15 / RXD RS485 UART receive
TXD P14 / TXD RS485 UART transmit
RSE P4 RS485 TX/RX control (auto control by default, some soldering is required to enable manual control), high for TX, low for RX

Configure CAN Bus on the Raspberry Pi



Without an ID EEPROM on the ‘hat’ specifying the hardware, the Linux kernel will not automatically discover the CAN Controller on the SPI interface. To load the appropriate driver, you must specify device tree overlay settings at boot.

Add the following line(s) to your /boot/config.txt file:

The oscillator parameter should be set to the actual crystal frequency found on your MCP2515. This frequency can change between modules, and is commonly either 16 or 8 MHz. My MCP2515 CAN Bus module board has a 8MHz on-board crystal and hence, I set the above line to 8000000.

The interrupt parameter specifies the Raspberry PI GPIO pin number. We have connected the INT pin to GPIO25.

By default, the mcp2515 driver uses a maximum SPI frequency of 10MHz (as per the MCP2515 datasheet). You can also specify the overlay an optional parameter spimaxfrequency, e.g. spimaxfrequency=2000000 to slow down the SPI clock to help with signal integrity issues – e.g. if you have flying leads, rather than a PCB!

Note: Historic documentation may suggest adding dtparam=spi=on and dtoverlay=spi-bcm2835-overlay. While the SPI master is not enabled by default, and specifying dtparam=spi=on will enable it, so will the mcp2515-can0 overlay. The spi-bcm2835-overlay was used to specify a newer bcm2835 SPI driver (vs the older bcm2708), but since version 4.4 of the kernel, bcm2835 is now the default driver.


Add the following line(s) to your /boot/config.txt file:

RS485 CAN HAT @ 8MHz

Add the following line(s) to your /boot/config.txt file:

RS485 CAN HAT @ 12MHz

Add the following line(s) to your /boot/config.txt file:

Install CAN Bus utils

CAN-utils is a collection of extremely useful debugging tools using the SocketCAN interface. It includes applications such as:

  • candump – Dump can packets – display, filter and log to disk.
  • canplayer – Replay CAN log files.
  • cansend – Send a single frame.
  • cangen – Generate random traffic.
  • canbusload – display the current CAN bus utilisation.

Install CAN Bus utils with: sudo apt-get install can-utils


Now reboot your PI. You should see the following kernel messages on boot:

Naturally, if you see “Cannot initialize MCP2515. Wrong wiring?“, check the power and wiring of your CAN controller.

Check if SPI is loaded

Start CAN Interface

Once you have rebooted and the driver has been successfully loaded, you can manually bring up the CAN interface using:

sudo /sbin/ip link set can0 up type can bitrate 500000

Check with ifconfig:

To automatically bring up the interface on boot, edit your /etc/network/interfaces file and add the following:

Console Utils

Listen to CAN Bus messages

candump any = listen to any canbus device connected

candump can0 = only listen on canbus device can0

candump can0,0x21:7ff = only listen on canbus device can0 and canbus device id 0x20 (32)

cansend can0 020#01 = Send 1 byte (1st) to device ID 0x20 (32)


On buses which high frame rates, the mcp251x driver may struggle. It is not unusual to see the irq/160-mcp251x kernel process using 25 percent of the CPU and the spi0 kernel using another 10 percent.

Enabling DMA doesn’t seem to make a material difference.

For most applications, it is unlikely you will want to capture and process every CAN frame. More likely than not, you are only only after frames sent to a specific address or range of addresses. This is how CAN buses were envisioned.

Given any other CAN device, one would just set a CAN filter and mask. This would filter out any frames not of interest and leave the firmware/software to deal with the important frames.

While this can be done, one of the deficiencies of the SocketCAN interface is that this filtering happens at a kernel module level. The filter and mask is never passed to the mcp251x for hardware level filtering. As a result, high CPU utilisation is still present when using filtering.

Add ability to use CAN ID hw filter

Now able to setup use of receive buffer hardware filters at module load time. Access through module parameters as this should be configured at module load time as changing receive buffer configurations should only be done when chip is in Configuration mode.


mcp251x CAN driver with hardware filtering for the Raspberry Pi

Based on patch from: https://support.criticallink.com/redmine/attachments/download/14913/0001-can-mcp251x-Add-ability-to-use-CAN-ID-hw-filter.patch

First download the kernel headers:

Now download this repo

Make the kernel module:

If successful it should display something similar to below and create you a mcp251x.ko file.


To test the driver, remove the old one (if loaded) and insert your new module into the kernel using:

and check your kernel messages:

Parameters to specify CAN filters and masks can be sent to the kernel using insmod:

Modinfo can be used to determine parameters:

When the driver is loaded, you may check the current parameters via the sysfs. e.g.

Example: Filter on CAN ID 0x10 (16) and 0x20 (32)

$ sudo insmod mcp251x.ko rxbn_op_mode=1,1 rxbn_filters=0x10,0x20 rxbn_mask=0xFFF,0xFFF

Download @ https://github.com/craigpeacock/mcp251x

mcp251x-master (DL @ 2020-12-17)




CAN Bus load

With the next command you can see the load on the canbus channel:

canbusload -b can0@250000

can0@250000 0 0 0 0% |………………..|

can0@250000 0 0 0 0% |………………..|

can0@250000 0 0 0 0% |………………..|

can0@250000 0 0 0 0% |………………..|

can0@250000 0 0 0 0% |………………..|

can0@250000 0 0 0 0% |………………..|

can0@250000 0 0 0 0% |………………..|

can0@250000 4 540 256 0% |………………..|

can0@250000 2 270 128 0% |………………..|

can0@250000 2 270 128 0% |………………..|

can0@250000 2 270 128 0% |………………..|