Skip to Content

How to test CAN bus on a Raspberry PLC

CAN bus test with can-utils between two Raspberry PLCs
September 7, 2021 by
How to test CAN bus on a Raspberry PLC
Boot & Work Corp. S.L, Fernandez Queralt Martinez

Complete guide: Choosing an industrial controller

To test CAN bus on a Raspberry PLC, connect CAN H to CAN H and CAN L to CAN L between two PLCs, bring up the can0 interface at the same bitrate on both, run candump can0 on one PLC and cansend can0 111#FF on the other. If the first PLC prints can0 111 [1] FF, the CAN controller, the wiring and the bitrate are correct.

This test was made with two Raspberry PLC v3, where the CAN controller is an MCP2515 on the SPI bus of the Raspberry Pi. In the current Raspberry PLC family, CAN is an expansion board with the same controller: MCP2515, CAN 2.0B, up to 1 Mbit/s. The test with can-utils is the same. Only the overlay settings change with the hardware version.

What is CAN bus?

CAN (Controller Area Network) is a serial bus where every node sends short frames with an identifier, and every node receives all frames. It was designed for wiring inside vehicles, and it is now used in machines, mobile equipment and industrial devices. When two nodes transmit at the same time, the frame with the lowest identifier wins the bus and the other node retries, so no data is lost in a collision.

FeatureClassic CAN (CAN 2.0)
Identifier11 bits (standard, CAN 2.0A) or 29 bits (extended, CAN 2.0B)
Data per frame0 to 8 bytes
Physical layerDifferential pair, CAN H and CAN L, usually twisted
Termination120 Ω at each end of the bus
BitrateUp to 1 Mbit/s. The bus gets shorter as the bitrate goes up
Error handlingCRC and acknowledge bit in every frame; a node with too many errors goes to bus off

On Linux, the CAN controller appears as a network interface (can0) through SocketCAN, so you configure it with ip and test it with the can-utils tools.

What you need

  • Two Raspberry PLC with CAN: a v3, or a current model with the CAN expansion board.
  • A 12 to 24 Vdc power supply for each PLC.
  • A twisted pair cable for CAN H and CAN L.
  • Two 120 Ω resistors, one at each end of the bus, if your boards do not have them.

Check the CAN interface on each PLC

  1. Use the Raspberry PLC image, or build it with the configuration files as explained in how to build a Raspberry PLC image from Raspberry Pi OS.
  2. Check that SPI is enabled. The MCP2515 talks to the Raspberry Pi through SPI.
  3. Check that the configuration file has the overlay of the CAN controller. On the Raspberry PLC v3 it is this line, with the 20 MHz crystal and the interrupt on GPIO 5 of that board:
    dtoverlay=mcp2515-can0,interrupt=5,oscillator=20000000
    The file is /boot/firmware/config.txt on Raspberry Pi OS Bookworm and /boot/config.txt on older images. On a CAN expansion board, use the oscillator and interrupt values of its user guide, not the v3 values.
  4. After a reboot, check that the driver found the controller. The mcp251x driver writes a line when it initializes the MCP2515:
    dmesg | grep -i mcp251
  5. Bring up the interface and check its state:
    sudo ip link set can0 up type can bitrate 500000 restart-ms 100
    ip -details -statistics link show can0
    The interface must be UP and the CAN state ERROR-ACTIVE. Use the same bitrate on both PLCs.
  6. The v3 image also brings up can0 at boot with the file /etc/network/interfaces.d/can0. Its content is:
    auto can0
    iface can0 inet manual
        pre-up /sbin/ip link set can0 type can bitrate 500000 triple-sampling on restart-ms 100
        up /sbin/ifconfig can0 up
        down /sbin/ifconfig can0 down
    This file needs ifupdown and ifconfig (net-tools). If your image does not use them, bring up the interface with the ip command of the previous step.
  7. Install can-utils, which gives the candump, cansend and cangen commands:
    sudo apt update
    sudo apt install can-utils

Wire the CAN bus between two PLCs

Connect CAN H of the first PLC to CAN H of the second one, and CAN L to CAN L. Use a twisted pair. If the PLCs do not share the power supply, also connect a common ground reference.

Wiring diagram: CAN H and CAN L connected between the CAN terminals of two Raspberry PLC
CAN H and CAN L between the communication connectors of two Raspberry PLC.

The bus needs a 120 Ω resistor at each end, also with only two nodes. With the power off, you should measure about 60 Ω between CAN H and CAN L. Check in the user guide of your PLC if the board already has a termination resistor.

Send and receive a CAN frame

1. Listen on the first PLC. Open a terminal and start candump. It prints every frame that reaches can0.

candump can0
Terminal of the first Raspberry PLC running candump can0 and waiting for frames
candump waiting for frames on the first PLC.

2. Send a frame from the second PLC. 111#FF means identifier 0x111 (hexadecimal, 11 bits) and one data byte, 0xFF.

cansend can0 111#FF
Terminal of the second Raspberry PLC: ifconfig can0 shows UP and RUNNING, then cansend can0 111#FF
The second PLC: can0 is UP and RUNNING, and cansend sends the frame.

3. Read the result on the first PLC. candump shows the interface, the identifier, the number of data bytes in brackets and the data:

  can0  111   [1]  FF
Terminal of the first Raspberry PLC: candump can0 receives the frame can0 111 [1] FF
The first PLC receives the frame 111 with one byte, FF.

More frames to test the bus:

cansend can0 123#DEADBEEF        # standard ID 0x123, 4 data bytes
cansend can0 18FF1234#0102030405  # extended 29-bit ID, 5 data bytes
candump -ta can0                  # received frames with absolute time
cangen can0 -g 100                # one random frame every 100 ms

If the frame does not arrive

SymptomUsual causeWhat to check
can0 does not existNo overlay, SPI off, or wrong oscillator or interrupt valuesThe overlay line, SPI, and dmesg | grep -i mcp251
can0 is DOWNThe interface was not brought upsudo ip link set can0 up type can bitrate 500000
cansend says "No buffer space available"No other node acknowledges the frames, so the transmit queue fills upThe other PLC is on, same bitrate, CAN H and CAN L not swapped, termination
State ERROR-PASSIVE or BUS-OFFToo many errors on the busBitrate, termination, wiring. With restart-ms the controller recovers from bus off by itself
Frames arrive with errors in the statisticsNoise or a long stubTwisted pair, short branches, one termination at each end only

From a test frame to a CAN application

A frame from the terminal proves the hardware. A real device usually speaks a higher layer protocol on top of CAN, such as CANopen in industrial drives and sensors, or SAE J1939 in vehicles and mobile machines. In a program, you use the same can0 interface from Python with the python-can library, or from C with SocketCAN sockets.

See CANopen on a Raspberry PLC. Two worked examples from the PLC Solution Library read a CANopen encoder and inclinometer on a solar tracker, and control a LOVATO VLB3 drive over CANopen.

CANopen encoder readingCANopen drive control

FAQ about CAN bus on a Raspberry PLC

Does the Raspberry PLC have CAN bus?

The Raspberry PLC v3 has an MCP2515 CAN controller. In the current family, CAN is an expansion board with the MCP2515 controller, CAN 2.0B, up to 1 Mbit/s. Ask for it when you order the PLC.

Which bitrate should I use?

The one of the other devices on the bus: all nodes must use the same. 500 kbit/s and 250 kbit/s are common. Lower bitrates allow longer cables.

Do I need termination resistors with only two PLCs?

Yes. The bus needs 120 Ω at each end, whatever the number of nodes. Without termination, frames can fail even on a short cable.

Does the MCP2515 support CAN FD?

No. The MCP2515 is a CAN 2.0B controller: classic frames with up to 8 data bytes.

Why does cansend fail with "No buffer space available"?

Because no other node acknowledges the frames. Check that the second PLC is on and listening at the same bitrate, and check the wiring and the termination.

​Search in our Blog

How to test CAN bus on a Raspberry PLC
Boot & Work Corp. S.L, Fernandez Queralt Martinez September 7, 2021
Share this post

Looking for your ideal Programmable Logic Controller?

Take a look at this product comparison with other industrial controllers Arduino-based. 

We are comparing inputs, outputs, communications and other features with the ones of the relevant brands.

PLC Comparison