CAN (controller area network) experiment

category: make

CAN

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.

Connection

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.

Connect each CAN High terminal and CAN Low terminal in parallel. CAN experiment

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.

Experiment

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 ID0x123 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 0x123.

[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.

Conclusion

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.