Home

Awesome

Arduino-STM32-CAN

Basic Extended CAN(BxCan) communication example for Arduino Core STM32.

Hardware requirements

NOTE
3V CAN Transceivers are fully interoperable with 5V CAN Transceivers.
Check here.

Software requirements

Wirering

My test circuit

The Nano on the left is a receiver with a terminating resistor.
The Nano on the right is a transmitter without a terminating resistor.
The STM32 transceiver has a terminating resistor.

Transmitter

Receiver

STM32-Receive

Communication with Arduino-UNO

You can use this library.

Communication with Arduino-DUE

You can use this library. STM32F103-CAN-DUO

Communication with ESP8266

You can use this library. STM32F103-CAN-ESP8266

Communication with ESP32

ESP-IDE has a CAN Network example.
https://github.com/espressif/esp-idf/tree/master/examples/peripherals/twai/twai_network
You can use it.
STM32F103-CAN-ESP32

Notes on ESP32 bitrate
In ESP-IDF V4, CONFIG_ESP32_REV_MIN >= 2 means "halve communication speed".
This is to support slower bitrates below 25Kbps.
This fuature can be controlled by CONFIG_ESP32_REV_MIN.
This fuature is enabled when CONFIG_ESP32_REV_MIN >= 2.
See here for detail.
This specification is not available in ESP-IDF V5.

Communication with Raspberry Pi

Edit /boot/config.txt and reboot.

dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=spi-bcm2835-overlay

Make sure the device is ready after reboot.

$ dmesg | grep mcp251x
[   19.992025] mcp251x spi0.0 can0: MCP2515 successfully initialized.

$ ls /sys/bus/spi/devices/spi0.0
driver  modalias  net  of_node  power  statistics  subsystem  uevent

$ ls /sys/bus/spi/devices/spi0.0/net
can0

$ sudo /sbin/ip link set can0 up type can bitrate 1000000

$ dmesg | grep can0
[   19.992025] mcp251x spi0.0 can0: MCP2515 successfully initialized.
[ 1309.525795] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready

$ sudo ifconfig can0
can0: flags=193<UP,RUNNING,NOARP>  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

$ sudo ifconfig can0 txqueuelen 1000

Install can-utils.

$ sudo apt-get install can-utils

# Receiver
$ candump can0

# Transmitter
$ cansend can0 123#11223344AABBCCDD

STM32F103-CAN-RPI

Troubleshooting

There is a module of SN65HVD230 like this.
SN65HVD230-1

There is a 120 ohms terminating resistor on the left side.
SN65HVD230-22

A transmission fail will occur.
SendFail

I have removed the terminating resistor.
And I used a external resistance of 150 ohms.
A transmission fail is fixed.
SN65HVD230-33

If the transmission fails, these are the possible causes.

I changed the single wire to twisted wire. It's fixed.
CAN-SendFail

Using PlatformIO

Arduino-IDE only supports ST-LINK V2.1 adapters, but OpenOCD used by PlatformIO supports both V2.0 and V2.1.
With ST-LINK, there is no need to change boot mode when writing firmware.
PlatformIO allows you to use cheap Chinese ST-LINK adapters like this one.
You can get it at a low price (about $2).
ST-LINK-1 ST-LINK-2

Connect the ST-LINK adapter and the STM32 development board as follows.

ST-LINKSTM32
3.3V3.3V
GNDGND
SWDIOSWIO(=PA13)
SWCLKSWCLK(=PA14)

platformio-2

Advanced use of BxCan

Skip if you don't need advanced usage.
Advanced usage has different purposes depending on the requirements of the application.
So I can't give you a concrete code example.

About transmission

STM32 has three transmit(TX) mailboxes.
Three TX mailboxes are provided to the software for setting up messages.
This sample code uses only the first TX mailbox and blocks the application until the send is successfully completed.
There are two ways to know if the send was successful without blocking.
Read the reference manual carefully and modify the source code as needed.

About reception

STM32 has two receive(RX) mailboxes.
Each RX Mailbox allows access to a 3-level depth FIFO, the access being offered only to the oldest received message in the FIFO.
This sample code uses only the first RX mailbox.
The RX mailbox is closely related to the receive filter settings.
By properly setting the receive filter, you can sort the received messages into two RX Mailboxes.
For example, high priority messages can be stored in the first RX MailBox and low priority messages can be stored in the second RX MailBox.
Read the reference manual carefully and modify the source code as needed.

Reference

https://github.com/nopnop2002/Robotell-USB-CAN-Python

https://github.com/nopnop2002/esp-idf-CANBus-Monitor