Python CAN / SLCAN send and receive example

SLCAN is a CAN interface protocol operating via serial communication. It’s often used to connect to CAN interfaces via USB.

The following example uses the python-can library to send and receive CAN messages via SLCAN.

The basic intention is to have two separate CAN adapters (such as the really cheap FYSETC UCAN with the slcan firmware)

First, install the python-can library:

pip install python-can

Sender example

This code connects to /dev/ttyACM0 and repeatedly sends a single CAN message:

#!/usr/bin/env python3
import can
import time

# Configuration for the SLCAN device
slcan_device = '/dev/ttyACM0'
baud_rate = 500000  # Set the appropriate baud rate for your setup

# Create a CAN bus instance using the SLCAN interface
bus = can.interface.Bus(interface='slcan', channel=slcan_device, bitrate=baud_rate)

# Define a simple CAN message
can_id = 0x123  # CAN ID
data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]  # 8 bytes of data

# Create a CAN message
message = can.Message(arbitration_id=can_id, data=data, is_extended_id=False)

try:
    while True:
        # Send the CAN message
        bus.send(message)
        print(f"Sent: {message}")

        # Wait for a second before sending the next message
        time.sleep(1)

except KeyboardInterrupt:
    print("Stopped by user")

except can.CanError as e:
    print(f"CAN error: {e}")

Example output

Sent: Timestamp:        0.000000    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Sent: Timestamp:        0.000000    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Sent: Timestamp:        0.000000    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Sent: Timestamp:        0.000000    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Sent: Timestamp:        0.000000    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Sent: Timestamp:        0.000000    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Sent: Timestamp:        0.000000    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Sent: Timestamp:        0.000000    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08

Receiver example

This code connects to /dev/ttyACM1 and listens for incoming CAN messages (and prints them on the command line):

#!/usr/bin/env python3
import can

# Configuration for the SLCAN device
slcan_device = '/dev/ttyACM1'
baud_rate = 500000  # Set the appropriate baud rate for your setup

# Create a CAN bus instance using the SLCAN interface
bus = can.interface.Bus(interface='slcan', channel=slcan_device, bitrate=baud_rate)

try:
    print("Listening for CAN messages on", slcan_device)
    while True:
        # Read a message from the CAN bus
        message = bus.recv()

        if message is not None:
            print(f"Received: {message}")

except KeyboardInterrupt:
    print("Stopped by user")

except can.CanError as e:
    print(f"CAN error: {e}")

Example output

Listening for CAN messages on /dev/ttyACM1
Received: Timestamp: 1722300573.156834    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Received: Timestamp: 1722300573.157226    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Received: Timestamp: 1722300573.157592    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Received: Timestamp: 1722300573.157937    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Received: Timestamp: 1722300573.979205    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Received: Timestamp: 1722300574.979508    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Received: Timestamp: 1722300575.979660    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Received: Timestamp: 1722300576.979969    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08
Received: Timestamp: 1722300577.980201    ID:      123    S Rx                DL:  8    01 02 03 04 05 06 07 08