CAN (controller area network) experiment
CAN (controller area network) is a communication standard that performs serial communication using two wires. CAN is the network OBD2 (on-board) in today’s cars. Since 1996 in the U.S. and since 2006 in Japan, cars and light trucks sold have been required to be equipped with OBD2, which performs CAN communication.
Along with I2C (inter-integrated circuit) and SPI (serial parallel interface), CAN is also widely used as a serial communication. So, I tried CAN communication using Raspberry Pi Zero W and its CAN adapter.
CAN makes use of a CSMA/CR (carrier sense multiple access/collision resolution) standard that enables communication between multiple devices using a two-wire bus connection. A maximum communication speed of 1 Mbit/s is defined, and it seems that a 40 meter bus length will have a communication speed of 1 Mbit/s. CAN can connect up to 30 devices.
Here, the following three devices were connected via CAN bus.
- 2 sets of Raspberry Pi Zero W and WaveShare RS485 CAN HAT
- 1 set of Seeeduino Uno and Longan Labs Serial CAN Bus Module
Connect each CAN High terminal and CAN Low terminal in parallel.
Serial CAN Bus Module is a module that converts CAN to serial communication. Seeeduino Uno is also compatible with Arduino Uno. Seeeduino Uno comes with a Grove connector, and the connector for communication and power supply is USB micro, which is convenient.
It’s been a while since I created a micro SD card for Raspberry Pi Zero W. The Raspberry Pi Zero used this time is not the latest 2W, but W. Therefore, I needed a 32-bit Raspberry Pi OS. Currently, Wi-Fi is not available on the latest Debian OS “bookworm”, so I used the older version “bullseye”.
First, make CAN available as device
can0. The communication speed was set to 1 Mbit/s.
sudo ip link set can0 type can bitrate 100000 sudo ifconfig can0 up
Next, set one of the two Rasberry Pi Zero Ws as the transmitter and the other as the receiver. With CAN, 8 bytes are transmitted at a time, and these are distinguished by ID numbers. Here, 8 random bytes with ID
0x123 are sent continuously every second. The sender Python code
send.py is as follows:
#!/usr/bin/env python import os import can import random import time can0 = can.interface.Bus(channel='can0', bustype='socketcan') while True: data = [random.randint(0,255) for _ in range(8)] print(data) msg = can.Message( arbitration_id=0x123, data = data, is_extended_id=False) can0.send(msg) time.sleep(1) # EOF
Meanwhile, the receiving Python code
receive.py looked like this:
#! /usr/bin/env python import os import can can0 = can.interface.Bus(channel='can0', bustype='socketcan') while True: msg = can0.recv(2.0) if msg: print (msg) # EOF
On the sending side, 8 random bytes were sent with ID
[217, 203, 250, 65, 193, 222, 223, 133] [0, 58, 102, 152, 76, 70, 98, 171] [127, 250, 174, 163, 203, 114, 7, 117] [205, 167, 208, 195, 198, 60, 67, 84] [230, 115, 117, 118, 4, 70, 153, 123]
Meanwhile, on the receiving side, I was able to receive those 8 bytes.
Timestamp: 1698198813.890996 ID: 0123 S Rx DL: 8 d9 cb fa 41 c1 de df 85 Channel: can0 Timestamp: 1698198814.894715 ID: 0123 S Rx DL: 8 00 3a 66 98 4c 46 62 ab Channel: can0 Timestamp: 1698198815.897671 ID: 0123 S Rx DL: 8 7f fa ae a3 cb 72 07 75 Channel: can0 Timestamp: 1698198816.901728 ID: 0123 S Rx DL: 8 cd a7 d0 c3 c6 3c 43 54 Channel: can0 Timestamp: 1698198817.905382 ID: 0123 S Rx DL: 8 e6 73 75 76 04 46 99 7b Channel: can0
Regarding the Serial CAN Bus Module, I installed the library for Arduino IDE and tried to match the communication speed and ID, but I was unable to receive this content. Try a little more thought.
Please note that the included software Waveforms 3.21.3 is said to be able to display CAN communication, but even if I connected it to the DIO (digital input output) terminal, I could not interpret the CAN communication. According to the Digilent forum, a method to convert CAN to SPI called PModCAN is introduced. There also seems to be a method for connecting the ground line.
I did a CAN communication experiment. I would like to extend the communication distance and make it possible to communicate with the Serial CAN Bus Module and other CAN devices.