In this tutorial, youāll discover how to connect your Raspberry Pi to a CAN Bus system, commonly found in vehicles, while exploring the functionality of each component and addressing common pitfalls that may arise.
This post was originally published on my blog:Ā http://youness.net/raspberry-pi/raspberry-pi-can-bus.
In this post, I shall show you how on hook up Raspberry Pi to a CAN Bus (or in other words, your car!).
Initially, itās worthwhile noting that Raspberry Pi boards do not come equipped with CAN functionality by default. Following this realization, we can condense the numerous Google search results into two key points.
- The CAN Bus protocol is not supported by hardware of GPIO on Raspberry Pi.
TL;DR:
- In this setup, weāll utilize the SPI Bus as a bridge between the Raspberry Pi and the CAN Bus.
- For this setup, weāll employ a CAN controller compatible with Linux/Raspbian, specifically the MCP2515.
Notably, the instructions below are primarily tested for the MCP251x family, which is a commonly employed component. Although I may expand the scope to include other CAN controllers in the future, the fundamental principles remain applicable to any component you might be using.
1. Hardware
1.1 CAN Bus Basics
1.1.1 CAN Wiring
The CAN Bus communication protocol utilizes a differential signaling approach, where two wires are employed: CAN-H (High) and CAN-L (Low), enabling reliable data transfer.
1.1.2 CAN Node
To establish a functioning CAN Bus network, a minimum of two nodes is required. As a result, testing with a single node is not feasible. Therefore, a crucial mistake to avoid is attempting to use only one CAN Bus node, as this will not allow for the network to operate successfully.
1.1.3 CAN Termination
For a CAN Bus network to function correctly, it is essential to include termination resistors between CAN-H and CAN-L at each extremity. The primary purpose of these resistors is to prevent signal reflections, which can compromise data transmission. According to ISO 11898, a suitable value for these resistors is 120 Ī©. Failure to include these termination resistors is a critical mistake, as it can render your CAN Bus network unfunctional.
1.1.4 CAN Controller
The CAN Bus communication protocol is a multi-master architecture, which means each node in the network requires a dedicated controller to manage its data transmission and reception. This CAN controller is typically connected to the CAN bus using the CAN-H and CAN-L wires. Popular examples of CAN controllers include the MCP2515 and SJA1000 devices.
1.1.5 CAN Transceiver
CAN controller requires a send/receive chip so as to convert signals to CAN Bus levels. Controller and Transceiver internal connection is done through two wires TxD, and RxD. Examples: MCP2551, TJA1040. ..
Regrouping all the above parts: Iāll hide the node B for the rest of the post.
1.2 SPI Bus Basics
1.2.1 Why SPI?
The Raspberry Pi device lacks a built-in CAN Bus interface, which is why we need to work around its limitations. However, the Raspberry Piās GPIO pins do feature SPI Bus compatibility, which is supported by a wide range of CAN controllers.
SPI Wiring
SPI Bus uses 4 connections as follow:
- MOSI (Master Out Slave In)
- MISO (Master In Slave Out)
- SCLK (Serial Clock)
Adding to that two other pinouts:
- CS or SS (Chip Select, Slave Select) to enable and disable the chip.
- INT (Interruption) to interrupt the chip when needed.
For that project you donāt really need to know more than that about SPI connections. Including Raspberry Pi to the previous schematic gives:
Letās move now to some practical details.
1.3 Components
1.3.1 MCP2515 (CAN Controller)
Supply:
The MCP2515 can work at 5V or 3V3, so it can be connected to Raspberry Pi GPIO.
Clock:
The MCP2515 needs an external quartz.For a value of 16Mhz, the datasheet recommends two capacitors of 22pF each.
Pull-up:
Three pins need a pull-up resistor to stay at a recognized level, I took 4K7 (4,7KĪ©) resistors. The pins are:
- Pin 17 for Reset.
- Pin 16 for CS.
- Pin 12 for INT.
The SPI bus itself (MOSI, MISO, SCLK) doesnāt need pull-up resistors.
1.3.2 MCP2551 (CAN Transceiver)
Supply:
In contrast to the MCP2515, the MCP2551 IC is restricted to operating at 5V voltage levels, which is a mistake. Error number 3: If the IC and Raspberry Pi operate at different voltage levels, the signals will not be compatible. Directly connecting an MCP2515 to an MCP2551, for instance, will result in incompatible signal levels. To resolve this issue, a 5V-to-3V3 level conversion is required. Microchip offers guidance on this topic in their ā3V Tips ān Tricksā document. (see below)
Reset: We will not need to reset the MCP2551 so the pin 8 can be connected to GND.
1.3.3 5V to 3V3
The easiest way for me is by a resistor divider (voltage divider) between MCP2515 and MCP2551. This divider is needed only for the RxD since it is here where the 5V will be introduced.
I used two resistors:
- R1: 10K (10KĪ©)
- R2 = 22K (22KĪ©)
You can use different values as far as the result is the same with an acceptable current/voltage.
1.4 Overall schematic
I put the pinout numbers, not the GPIO numbers, I think that it is easier to follow.
1.5 Bill of Material
2. Software
Iām running Raspbian, always opting for a fresh and updated start. To streamline my setup, I stick with Raspbian Stretch Lite, which I find ideal since itās designed for minimal resource utilization and doesnāt require a full-fledged desktop environment.
Update/Upgrade and reboot:
sudo apt-get updatesudo apt-get upgradesudo reboot
Usual customizations: Wi-Fi, keyboard, SSHā¦etc.
If you need specific help for all that, please leave a comment.
2.1 Why MCP251x?
Most CAN modules by SPI controllers hadnāt been natively supported in Linux kernels until recently. This meant that users had to manually compile and integrate the modules, and this process had to be repeated every time the kernel was updated. If you are interested by this part of history, you can read my 2015 post here.
Today things are much easier, Linux kernels added support for MCP251x (and other controllers), so you can directly load them like any other hardware peripheral.
2.2 SPI/CAN Configuration
Enable SPI and overlay it as follows:
sudo nano /boot/config.txt
Uncomment the line:
dtparam=spi=on
After the above line add this:
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25dtoverlay=spi0-hw-cs
The above lines overlay SPI, set can0 interface to 16MHz, and interrupt the GPIO25 pin.
This is the correct way for +4.4.x kernels, the mistake nĀ°4 is to use a deprecated overlay method. (For earlier versions, the overlay may be different.)
Save the file: CTRL+X, then Y, then Enter.
Reboot, and you can check that the SPI module was started:
dmesg | grep -i spi
By using the same command, you can check if the CAN module is started by default:
dmesg | grep -i can
If, for any reason, this is not the case, you can add CAN module at system start:
sudo nano /etc/modules
Add ācanā in a new line, save the file and reboot.