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 MCP2515 SPI CAN controller and a SN65HVD230 CAN transciever for CAN 2.0B Classic communication on a Orange Pi Zero
Connection schematic:

MCP2515 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 mcp2515 @ 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 = <16000000>;
};
};
};
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>;
mcp2515@1 {
compatible = "microchip,mcp2515";
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 16Mhz
If you have used another crystal/resonator (e.g. 4 MHz), please adjust the value above to ‘clock-frequency = <4000000>;‘
If you have used another crystal/resonator (e.g. 8 MHz), please adjust the value above to ‘clock-frequency = <8000000>;‘
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:
auto can0
iface can0 inet manual
pre-up /sbin/ip link set can0 type can bitrate 250000 triple-sampling 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:
[ 6.200783] mcp251x spi1.1 can0: MCP2515 successfully initialized.
If you got this error, then check your wiring!:
[ 5.874150] mcp251x spi1.1: MCP251x didn't enter in conf mode after reset
[ 5.874247] mcp251x spi1.1: Probe failed, err=110
[ 5.874259] mcp251x: probe of spi1.1 failed with error -110
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 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
Recieve CAN data #
To check recieved dat you can use candump:
sudo candump can0
Example output:
can0 013 [7] DD A5 04 00 FF FC 77
can0 014 [7] DD A5 04 00 FF FC 77
can0 011 [8] DD A5 03 00 FF FD 77 00
can0 012 [8] DD A5 03 00 FF FD 77 00
can0 013 [8] DD A5 03 00 FF FD 77 00
can0 014 [8] DD A5 03 00 FF FD 77 00
can0 011 [7] DD A5 04 00 FF FC 77
can0 012 [7] DD A5 04 00 FF FC 77
can0 013 [7] DD A5 04 00 FF FC 77
can0 014 [7] DD A5 04 00 FF FC 77
can0 011 [8] DD A5 03 00 FF FD 77 00
can0 012 [8] DD A5 03 00 FF FD 77 00
can0 013 [8] DD A5 03 00 FF FD 77 00
can0 014 [8] DD A5 03 00 FF FD 77 00
can0 011 [7] DD A5 04 00 FF FC 77
To see RX/TX you can use:
candump -x can0
can0 RX - - 014 [8] DD A5 03 00 FF FD 77 00
can0 RX - - 011 [7] DD A5 04 00 FF FC 77
can0 RX - - 012 [7] DD A5 04 00 FF FC 77
can0 RX - - 013 [7] DD A5 04 00 FF FC 77
can0 TX - E 720 [8] 00 00 00 00 00 00 00 00
can0 RX - - 014 [7] DD A5 04 00 FF FC 77
can0 RX - - 011 [8] DD A5 03 00 FF FD 77 00
can0 RX - - 012 [8] DD A5 03 00 FF FD 77 00
can0 RX - - 013 [8] DD A5 03 00 FF FD 77 00
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