Used image: Orangepizero3_1.0.4_debian_bookworm_server_linux6.1.31
Software needed:
sudo apt install -y can-utils
In this example we are using a MCP2518 SPI CAN controller and a ISO1042 Isolated CAN transciever for CAN 2.0B Classic communication on a Orange Pi Zero
Connection schematic:

MCP2518 Overlay #
To use the MCP2515 we first need to create an overlay for the IO pins:
sudo nano /boot/dtb/spi-mcp251x.dts
Contents:
/*
* Device tree overlay for mcp2517/18 @ can0 on SPI1.1 (Orange Pi Zero 3)
*/
/dts-v1/;
/plugin/;
/ {
compatible = "allwinner,sun50i-h616";
fragment@0 {
target-path = "/";
__overlay__ {
can0_osc_fixed: can0_osc_fixed {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <20000000>;
};
};
};
fragment@1 {
target = <&pio>;
__overlay__ {
can0_pin_irq: can0_pin_irq {
pins = "PC7";
function = "irq";
bias-pull-up;
};
};
};
fragment@2 {
target = <&spi1>; /* Use SPI1 */
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
mcp2518fd@1 {
compatible = "microchip,mcp2518fd";
reg = <1>; /* Use SPIx.1 */
pinctrl-names = "default";
pinctrl-0 = <&can0_pin_irq>;
spi-max-frequency = <10000000>;
interrupt-parent = <&pio>;
interrupts = <2 7 0x08>; /* PC7 IRQ_TYPE_LEVEL_LOW */
clocks = <&can0_osc_fixed>;
status = "okay";
};
};
};
};
Please note:
- SPI 1.1 is used
- Interrupt (INT) is PC7
- Clock is 20Mhz
If you have used another crystal/resonator (e.g. 40 MHz), please adjust the value above ‘clock-frequency = <40000000>;‘
Add the overlay to the system:
sudo dtc -I dts -O dtb -o /boot/dtb/allwinner/overlay/sun50i-h616-spi-mcp251x.dtbo /boot/dtb/spi-mcp251x.dts
The overlay should compile and added withouth any errors
Set hardware interfaces #
To enable the overrlay and set the SPI hardware settings:
sudo nano /boot/orangepiEnv.txt
add after overlay_prefix:
overlays=ph-i2c3 ph-uart5 spi0-spidev spi1-cs1-spidev spi-mcp251x
param_spidev_spi_bus=0
dtparam=spi=on
Enable in network interface #
To enable CAN in the network interface edit the network interfaces file:
sudo nano /etc/network/interfaces
add at the end (example shows 250kbit abitration rate and 500kbit datarate:
auto can0
iface can0 inet manual
pre-up /sbin/ip link set can0 type can bitrate 250000 dbitrate 500000 fd on restart-ms 100
up /sbin/ifconfig can0 up
down /sbin/ifconfig can0 down
Now reboot:
sudo reboot
Check hardware #
After reboot check the hardware, is the chip succefuilly initialised?
dmesg |grep mcp
Should output:
[ 1733.045547] mcp251xfd spi1.1 can0: MCP2518FD rev0.0 (-RX_INT -PLL -MAB_NO_WARN +CRC_REG +CRC_RX +CRC_TX +ECC -HD o:20.00MHz c:20.00MHz m:10.00MHz rs:8.50MHz es:6.00MHz rf:8.50MHz ef:6.00MHz) successfully initialized.
If you got this error, then check your wiring!, you can use modprobe to check SPI again:
sudo modprobe -r mcp251xfd
sudo modprobe mcp251xfd
Check if CAN adapter is in the network tree:
sudo ifconfig can0
Output:
can0: flags=193<UP,RUNNING,NOARP> mtu 72
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC)
RX packets 591393 bytes 35896384 (34.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2347 bytes 18692 (18.2 KiB)
TX errors 0 dropped 47 overruns 0 carrier 47 collisions 0
device interrupt 68
CAN 2.0B Classic change baudrate #
You can change baudrate this way, first turn off the can0 interface:
sudo ip link set can0 down
Then enable the can0 interface again with the desired baudrate example 500kbit:
sudo ip link set can0 up type can bitrate 500000
DMESG errors
To prevent format errors (wich you cannot suppress)
[ 2552.869113] mcp251xfd spi1.1 can0: CRC write command format error.
you can start with “fd off”
sudo ip link set can0 up type can bitrate 500000 fd off
CAN FD Classic change baudrate #
You can change baudrate this way, first turn off the can0 interface:
sudo ip link set can0 down
Then enable the can0 interface again with the desired ARBITRATION bitrate of 250kbit and a DATA bitrate 500kbit as example:
sudo ip link set can0 up type can bitrate 250000 dbitrate 500000 fd on
Recieve CAN data #
To check recieved dat you can use candump:
sudo candump can0
Example output:
can0 63E [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
can0 3A2 [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
can0 10E [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14
15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
To see RX/TX you can use:
candump -x can0
Example output:
can0 RX B - 712 [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12
13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E
2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
can0 RX B - 49C [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12
13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E
2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
can0 RX B - 1FE [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12
13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E
2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
can0 RX B - 786 [64] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12
13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E
2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
if you have 2 canbus interfaces you may want to add color:
candump -x -c can0
Filter data
To filter data e.g. a specific ID, you can use for example ID 11:
candump -x can0,011:7FF
Send CAN data #
You can send CAN data by using cansend [ID]#[MESSAGE], example
sudo cansend 003#010203FDFF
System load #
We have tested the Orange Pi Zero 3 system load with an ESP32 on “full blast” 64 byte CAN messages.
Result :6.9% system load on SPI1.1 with 250kbit speed:

Result :12.5% system load on SPI1.1 with 500kbit speed:
